Commit 060c4ab0 authored by Kunshan Wang's avatar Kunshan Wang

Antlr-based parsing (partial)

parent 96c3d9db
......@@ -11,23 +11,24 @@ import org.antlr.v4.runtime.tree.TerminalNode
import uIRParser._
object AntlrUvmIRReader {
import Later.Laterable
def read(ir: String): Bundle = {
def read(ir: String, globalBundle: Bundle): Bundle = {
val input = new ANTLRInputStream(ir)
val lexer = new uIRLexer(input)
val tokens = new CommonTokenStream(lexer)
val parser = new uIRParser(tokens)
val ast = parser.ir();
read(ast)
read(ast, globalBundle)
}
def read(ir: java.io.Reader): Bundle = {
def read(ir: java.io.Reader, globalBundle: Bundle): Bundle = {
val input = new ANTLRInputStream(ir)
val lexer = new uIRLexer(input)
val tokens = new CommonTokenStream(lexer)
val parser = new uIRParser(tokens)
val ast = parser.ir();
read(ast)
read(ast, globalBundle)
}
object IDFactory {
......@@ -39,30 +40,6 @@ object AntlrUvmIRReader {
}
}
class Later {
var jobs: List[() => Unit] = Nil
def apply(job: () => Unit) {
jobs = job :: jobs
}
def doAll() {
while (!jobs.isEmpty) {
val job = jobs.head
jobs = jobs.tail
job()
}
}
def isEmpty: Boolean = jobs.isEmpty
}
implicit class Laterable[T](val anything: T) {
def later(lat: Later)(job: T => Unit): T = {
lat(() => job(anything))
anything
}
}
implicit def terminalToString(tn: TerminalNode): String = tn.getText()
implicit def IntLiteralToBigInt(il: IntLiteralContext): BigInt = {
......@@ -72,40 +49,44 @@ object AntlrUvmIRReader {
case '-' => (true, 1)
case _ => (false, 0)
}
il match {
val abs = il match {
case dec: DecIntLiteralContext => BigInt(txt.substring(beg), 10)
case oct: OctIntLiteralContext => BigInt(txt.substring(beg + 1), 8)
case oct: OctIntLiteralContext => BigInt(txt.substring(beg), 8)
case hex: HexIntLiteralContext => BigInt(txt.substring(beg + 2), 16)
}
return if (neg) -abs else abs
}
implicit def floatLiteralToFloat(fl: FloatLiteralContext): Float = fl match {
case num: FloatNumberContext => num.FP_NUM().getText().toFloat
case bits: FloatBitsContext => java.lang.Float.intBitsToFloat(bits.intLiteral().intValue())
case _ => fl.getText() match {
case "nan" => java.lang.Float.NaN
case "-inf" => java.lang.Float.NEGATIVE_INFINITY
case "+inf" => java.lang.Float.POSITIVE_INFINITY
case num: FloatNumberContext => num.FP_NUM.getText.toFloat
case fi: FloatInfContext => {
if (fi.getText.startsWith("-"))
java.lang.Float.NEGATIVE_INFINITY
else java.lang.Float.POSITIVE_INFINITY
}
case _: FloatNanContext => java.lang.Float.NaN
case bits: FloatBitsContext => java.lang.Float.intBitsToFloat(bits.intLiteral().intValue())
}
implicit def doubleLiteralToDouble(dl: DoubleLiteralContext): Double = dl match {
case num: DoubleNumberContext => num.FP_NUM().getText().toDouble
case bits: DoubleBitsContext => java.lang.Double.longBitsToDouble(bits.intLiteral().longValue())
case _ => dl.getText() match {
case "nan" => java.lang.Double.NaN
case "-inf" => java.lang.Double.NEGATIVE_INFINITY
case "+inf" => java.lang.Double.POSITIVE_INFINITY
case num: DoubleNumberContext => num.FP_NUM.getText.toDouble
case fi: DoubleInfContext => {
if (fi.getText.startsWith("-"))
java.lang.Double.NEGATIVE_INFINITY
else java.lang.Double.POSITIVE_INFINITY
}
case _: DoubleNanContext => java.lang.Double.NaN
case bits: DoubleBitsContext => java.lang.Double.longBitsToDouble(bits.intLiteral().longValue())
}
def read(ir: IrContext): Bundle = {
def read(ir: IrContext, globalBundle: Bundle): Bundle = {
val bundle = new Bundle()
val phase1 = new Later()
def resTy(te: TypeContext): Type = te match {
case rt: ReferencedTypeContext => bundle.typeNs(rt.GLOBAL_ID().getText())
case rt: ReferencedTypeContext => bundle.typeNs.get(rt.GLOBAL_ID()).getOrElse(globalBundle.typeNs(rt.GLOBAL_ID()))
case it: InLineTypeContext => mkType(it.typeConstructor())
}
......@@ -132,7 +113,7 @@ object AntlrUvmIRReader {
}
def resSig(fs: FuncSigContext): FuncSig = fs match {
case rfs: ReferencedFuncSigContext => bundle.funcSigNs(rfs.GLOBAL_ID())
case rfs: ReferencedFuncSigContext => bundle.funcSigNs.get(rfs.GLOBAL_ID()).getOrElse(globalBundle.funcSigNs(rfs.GLOBAL_ID()))
case ilfs: InLineFuncSigContext => mkSig(ilfs.funcSigConstructor())
}
......@@ -145,24 +126,116 @@ object AntlrUvmIRReader {
return sig
}
ir.metaData().foreach { rule =>
rule.getChild(0) match {
case td: TypeDefContext => {
val ty = mkType(td.typeConstructor())
ty.name = Some(td.GLOBAL_ID())
bundle.typeNs.add(ty)
}
case fsd: FuncSigDefContext => {
val sig = mkSig(fsd.funcSigConstructor())
sig.name = Some(fsd.GLOBAL_ID())
bundle.funcSigNs.add(sig)
}
case _ =>
ir.metaData.map(_.getChild(0)).foreach {
case td: TypeDefContext => {
val ty = mkType(td.typeConstructor)
ty.name = Some(td.GLOBAL_ID)
bundle.typeNs.add(ty)
}
case fsd: FuncSigDefContext => {
val sig = mkSig(fsd.funcSigConstructor)
sig.name = Some(fsd.GLOBAL_ID)
bundle.funcSigNs.add(sig)
}
case _ =>
}
phase1.doAll()
val phase2 = new Later()
def resGV(t: Type, ce: ConstantContext): GlobalValue = ce match {
case rcc: ReferencedConstContext => bundle.globalValueNs.get(rcc.GLOBAL_ID).getOrElse(globalBundle.globalValueNs(rcc.GLOBAL_ID))
case icc: InLineConstContext => mkConst(t, icc.constExpr)
}
def mkConst(t: Type, c: ConstExprContext): DeclaredConstant = {
val con = c match {
case icc: IntConstContext => ConstInt(t, icc.intLiteral)
case fcc: FloatConstContext => ConstFloat(t, fcc.floatLiteral)
case dcc: DoubleConstContext => ConstDouble(t, dcc.doubleLiteral)
case scc: StructConstContext => ConstStruct(t, null).later(phase2) {
_.fields = for ((ft, f) <- t.asInstanceOf[TypeStruct].fieldTy.zip(scc.constant)) yield resGV(ft, f)
}
case _: NullConstContext => ConstNull(t)
}
con.id = IDFactory.getID()
return con
}
def mkGlobalData(t: Type): GlobalData = {
val gd = GlobalData(t)
gd.id = IDFactory.getID()
return gd
}
def mkGlobalDataConst(gd: GlobalData): ConstGlobalData = {
val gdc = ConstGlobalData(gd)
return gdc
}
def mkFunc(sig: FuncSig): Function = {
val func = new Function()
func.sig = sig
return func
}
def mkFuncConst(func: Function): ConstFunc = {
val fc = ConstFunc(func)
return fc
}
def tryReuseFuncID(name: String): Option[Int] = {
globalBundle.funcNs.get(name).map(_.id)
}
def declFunc(n: String, s: FuncSigContext): Function = {
val sig = resSig(s)
val func = mkFunc(sig)
val maybeOldID = tryReuseFuncID(n)
func.id = maybeOldID.getOrElse(IDFactory.getID())
func.name = Some(n)
bundle.funcNs.add(func)
if (maybeOldID == None) {
val fc = mkFuncConst(func)
bundle.globalValueNs.add(fc)
}
return func
}
var funcDefs: List[(Function, Seq[String], FuncBodyContext)] = Nil
ir.metaData.map(_.getChild(0)).foreach {
case cdctx: ConstDefContext => {
val ty = resTy(cdctx.`type`)
val con = mkConst(ty, cdctx.constExpr)
con.name = Some(cdctx.GLOBAL_ID)
bundle.declConstNs.add(con)
bundle.globalValueNs.add(con)
}
case gdctx: GlobalDefContext => {
val ty = resTy(gdctx.`type`)
val gd = mkGlobalData(ty)
gd.name = Some(gdctx.GLOBAL_ID)
bundle.globalDataNs.add(gd)
val gdc = mkGlobalDataConst(gd)
bundle.globalValueNs.add(gdc)
}
case fdecl: FuncDeclContext => {
declFunc(fdecl.GLOBAL_ID, fdecl.funcSig)
}
case fdef: FuncDefContext => {
val func = declFunc(fdef.GLOBAL_ID, fdef.funcSig)
funcDefs = (func, fdef.paramList.LOCAL_ID.map(_.getText), fdef.funcBody) :: funcDefs
}
case _ => {}
}
phase2.doAll()
return bundle
}
}
\ No newline at end of file
......@@ -7,6 +7,7 @@ import uvm.ifuncs._
object UvmIRReader {
import UvmIRAST._
import Later.Laterable
def read(ir: CharSequence, globalBundle: Bundle): Bundle = {
val ast = UvmIRParser(ir)
......@@ -27,36 +28,6 @@ object UvmIRReader {
}
}
class Later {
var tooLate = false
var jobs: List[() => Unit] = Nil
def apply(job: () => Unit) {
if (tooLate) {
job()
} else {
jobs = job :: jobs
}
}
def doAll() {
tooLate = true
while (!jobs.isEmpty) {
val job = jobs.head
jobs = jobs.tail
job()
}
}
def isEmpty: Boolean = jobs.isEmpty
}
implicit class Laterable[T](val anything: T) {
def later(lat: Later)(job: T => Unit): T = {
lat(() => job(anything))
anything
}
}
def read(ir: IR, globalBundle: Bundle): Bundle = {
val bundle = new Bundle()
......
package uvm.ir.textinput
class Later {
var tooLate = false
var jobs: List[() => Unit] = Nil
def apply(job: () => Unit) {
if (tooLate) {
job()
} else {
jobs = job :: jobs
}
}
def doAll() {
tooLate = true
while (!jobs.isEmpty) {
val job = jobs.head
jobs = jobs.tail
job()
}
}
def isEmpty: Boolean = jobs.isEmpty
}
object Later {
implicit class Laterable[T](val anything: T) {
def later(lat: Later)(job: T => Unit): T = {
lat(() => job(anything))
anything
}
}
}
\ No newline at end of file
......@@ -5,23 +5,11 @@ import org.scalatest.Matchers
import uvm.Bundle
class AntlrUvmIRReaderSpec extends FlatSpec with Matchers {
class AntlrUvmIRReaderSpec extends AbstractReaderSpec {
override def theSubject = "AntlrUvmIRReader"
def parseFile(fileName: String): Bundle = {
AntlrUvmIRReader.read(new java.io.FileReader(fileName))
}
"The AntlrUvmIRParser" should "parse simple type definitions" in {
parseFile("tests/uvm-parsing-test/types.uir")
}
it should "parse simple constant definitions" in {
parseFile("tests/uvm-parsing-test/constants.uir")
}
it should "parse simple function definitions" in {
parseFile("tests/uvm-parsing-test/functions.uir")
}
it should "parse simple instruction definitions" in {
parseFile("tests/uvm-parsing-test/instructions.uir")
override def parseFile(fileName: String, globalBundle: Bundle): Bundle = {
AntlrUvmIRReader.read(new java.io.FileReader(fileName), globalBundle)
}
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment