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")
}
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))
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)
+ }
}