Commit ca9e751e authored by Kunshan Wang's avatar Kunshan Wang

Nicer parser error messages. CA allows loading bundles from strings directly.

parent 683bfb90
......@@ -10,37 +10,60 @@ import uvm.ssavariables._
import uvm.types._
import scala.collection.JavaConversions._
import scala.collection.mutable.ArrayBuffer
import scala.collection.immutable.Stream
import java.io.StringWriter
import java.nio.CharBuffer
class UIRTextReader(val idFactory: IDFactory) {
import uvm.ir.textinput.Later.Laterable
def read(ir: String, globalBundle: Bundle): Bundle = {
val input = new ANTLRInputStream(ir)
read(input, globalBundle)
read(ir, input, globalBundle)
}
def read(ir: java.io.Reader, globalBundle: Bundle): Bundle = {
val input = new ANTLRInputStream(ir)
read(input, globalBundle)
val sb = new StringBuilder()
val cb = new Array[Char](4096)
var finished = false
while (!finished) {
val actualRead = ir.read(cb, 0, 4096)
if (actualRead > 0) {
sb.appendAll(cb, 0, actualRead)
} else {
finished = true
}
}
read(sb.toString(), globalBundle)
}
class AccumulativeAntlrErrorListener extends BaseErrorListener {
class AccumulativeAntlrErrorListener(source: String) extends BaseErrorListener {
val buf = new ArrayBuffer[String]()
var hasError = false
lazy val sourceLines = ArrayBuffer(source.lines.toSeq: _*)
override def syntaxError(recognizer: Recognizer[_, _], offendingSymbol: Object,
line: Int, charPositionInLine: Int, msg: String, e: RecognitionException): Unit = {
buf.add("line %d:%d %s".format(line, charPositionInLine, msg))
val theLine = sourceLines(line - 1)
val marker = " " * charPositionInLine + "^"
buf.add("line %d:%d %s\n%s\n%s".format(line, charPositionInLine, msg, theLine, marker))
hasError = true
}
def getMessages(): String = buf.mkString("\n")
}
def read(ir: ANTLRInputStream, globalBundle: Bundle): Bundle = {
val lexer = new UIRLexer(ir)
def read(source: String, ais: ANTLRInputStream, globalBundle: Bundle): Bundle = {
val ea = new AccumulativeAntlrErrorListener(source)
val lexer = new UIRLexer(ais)
lexer.removeErrorListeners()
lexer.addErrorListener(ea)
val tokens = new CommonTokenStream(lexer)
val parser = new UIRParser(tokens)
val ea = new AccumulativeAntlrErrorListener()
parser.removeErrorListeners()
parser.addErrorListener(ea)
val ast = parser.ir()
......
......@@ -43,6 +43,11 @@ class ClientAgent(microVM: MicroVM) {
val bundle = microVM.irReader.read(r, microVM.globalBundle)
microVM.addBundle(bundle)
}
def loadBundle(s: String): Unit = {
val bundle = microVM.irReader.read(s, microVM.globalBundle)
microVM.addBundle(bundle)
}
private def newHandle(t: Type, vb: ValueBox): Handle = {
val handle = Handle(t, vb)
......
package uvm.ir.textinput
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import uvm.Bundle
class NicerErrorMessage extends FlatSpec with Matchers
with TestingBundlesValidators {
def parseFile(fileName: String, globalBundle: Bundle, fac: Option[IDFactory] = None): Bundle = {
val idf = fac.getOrElse(new IDFactory())
val r = new UIRTextReader(idf)
val ir = r.read(new java.io.FileReader(fileName), globalBundle)
ir
}
val EMPTY_BUNDLE = new Bundle()
behavior of "UIRTextReader"
it should "give nice error messages" in {
try {
val b = parseFile("tests/uvm-parsing-test/bundle-with-error.uir", EMPTY_BUNDLE)
} catch {
case e: TextIRParsingException => // expected
e.printStackTrace()
}
}
}
\ No newline at end of file
......@@ -43,7 +43,7 @@ class UvmInterpreterTestBigFunc extends UvmBundleTesterBase {
for(i <- 0 until 100) {
val miniBundle = s".global @h${i} <@i64>"
ca.loadBundle(new StringReader(miniBundle))
ca.loadBundle(miniBundle)
}
val sb = new StringBuilder()
......@@ -52,11 +52,11 @@ class UvmInterpreterTestBigFunc extends UvmBundleTesterBase {
for(i <- 0 until 100) {
sb ++= s" %r${i} = STORE <@i64> @h${i} %p\n"
}
// sb ++= " TRAP <@void>\n"
sb ++= " TRAP <@void>\n"
sb ++= " COMMINST @uvm.thread_exit\n"
sb ++= "}"
ca.loadBundle(new StringReader(sb.toString()))
ca.loadBundle(sb.toString())
val func = ca.putFunction("@bigger")
val hParam = ca.putInt("@i64", 42)
......
.typedef @i64 = int<64>
.const @I64_42 <@i64> = 42
.global @gv <@i64>
.funcsig @foo.sig = @i64 (@i64 @i64)
.funcdef @foo VERSION @foo.v1 <@foo.sig> (%p0 %p1) {
%entry:
STORE <@i64> gv @I64_42
RET <@i64> @I64_42
}
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