]> git.unchartedbackwaters.co.uk Git - francis/ofc.git/commitdiff
Handle parse errors more nicely.
authorFrancis Russell <francis@unchartedbackwaters.co.uk>
Tue, 20 Dec 2011 19:56:33 +0000 (19:56 +0000)
committerFrancis Russell <francis@unchartedbackwaters.co.uk>
Tue, 20 Dec 2011 19:56:33 +0000 (19:56 +0000)
src/ofc/OFC.scala
src/ofc/parser/Parser.scala

index 7d42620086b8ea2959ff3d276a8aa0a26de15ca9..9653e709df620efa743311598145364fecc61d79 100644 (file)
@@ -1,12 +1,26 @@
 package ofc
 import java.io.FileReader
-import parser.Parser
+import parser.{Parser,Statement,ParseException}
 
 object OFC extends Parser {
 
   def main(args: Array[String]) {
     if (args.isEmpty) throw new IllegalArgumentException("Unspecified input file.")
+
     val reader = new FileReader(args(0))
-    println(parseAll(program, reader))
+
+    try {
+      val program = parseProgram(reader)
+      processAST(program)
+    } catch {
+      case e: ParseException => {
+        Console.err.println("Parse failure: "+e)
+        System.exit(1)
+      }
+    } finally {
+      reader.close
+    }
   }
+
+  def processAST(statements : List[Statement]) = print(statements.mkString("\n") + "\n")
 }
index 92fe8922b46d345949f9a3e2c1a0d1d8d43f9960..b22ea74ee62514e18399a4c0775d85fa1ea1c157 100644 (file)
@@ -1,11 +1,17 @@
 package ofc.parser
-
 import scala.util.parsing.combinator._
+import scala.util.parsing.input.Position
+import java.io.Reader
 
 sealed abstract class ScalarOperationTag
 case class MultiplicationTag() extends ScalarOperationTag
 case class DivisionTag() extends ScalarOperationTag
 
+class ParseException(message: String, pos: Position) extends Exception {
+  override def toString : String = 
+    message + " at line " + pos.line + ", column " + pos.column + "."
+}
+
 class Parser extends JavaTokenParsers {
   def program : Parser[List[Statement]] = rep(comment | declarations | definition | target | comment | specifics)
   def comment : Parser[Comment] = "#"~!".*".r ^^ (v => new Comment(v._2))
@@ -51,4 +57,11 @@ class Parser extends JavaTokenParsers {
   def stringParameter : Parser[StringParameter] = stringLiteral ^^ (x => new StringParameter(x.slice(1, x.length-1)))
   def numericParameter : Parser[NumericParameter] = floatingPointNumber ^^ (x => new NumericParameter(x.toDouble))
   def parameterList : Parser[ParameterList] = "["~>repsep(functionParameter, ",")<~"]" ^^ (x => new ParameterList(x))
+
+  def parseProgram(in: Reader) : List[Statement] =
+    parseAll(program, in) match {
+      case Success(result, _) => result
+      case r : NoSuccess => 
+        throw new ParseException(r.msg, r.next.pos)
+    }
 }