/* * I found it very cool to be able to build a parser incrementally, e.g, * first define the expressions for booleans, then arithmetics, and comparison, * and so on. Well, the comparison is not going very well yet, as I am not * parsing numbers right. * One of the downsides of this system is that the error messages are not * clear. When the match fails, I cannot really tell why. */ ometa B1 <: Parser { oExp = oExp "|" aExp | aExp, aExp = aExp "&" bExp | bExp, bExp = "(" oExp ")" | "true" | "false" } // B1.matchAll("true | false", "oExp") /* * Evaluates arithmetic expressions. */ ometa A1 <: Parser { digit = super(#digit):d -> d.digitValue(), number = number:n digit:d -> (n * 10 + d) | digit, addExpr = addExpr:x "+" mulExpr:y -> (x + y) | addExpr:x "-" mulExpr:y -> (x - y) | mulExpr, mulExpr = mulExpr:x "*" primExpr:y -> (x * y) | mulExpr:x "/" primExpr:y -> (x / y) | primExpr, primExpr = "(" expr:x ")" -> x | spaces number, expr = addExpr } // A1.matchAll("6 * (4+3)", "expr") /* * Evaluates numeric comparisons. These take as input a boolean * expression involving numeric values. */ ometa C1 <: A1 { cExpr = addExpr:x ">" addExpr:y -> (x > y) | addExpr:x "<" addExpr:y -> (x < y) | addExpr:x "<=" addExpr:y -> (x <= y) | addExpr:x ">=" addExpr:y -> (x >= y) | addExpr:x -> x } // C1.matchAll("23<24", "cExpr") /* * Evaluates boolean expressions. */ ometa B2 <: C1 { nExp = "!" nExp:e -> (!e) | xExp, xExp = xExp:e1 "^" oExp:e2 -> (e1 != e2) | oExp, oExp = oExp:e1 "|" aExp:e2 -> (e1 || e2) | aExp, aExp = aExp:e1 "&" bExp:e2 -> (e1 && e2) | bExp, bExp = "(" xExp:e ")" -> e | "true" -> 1 | "false" -> 0 | cExpr } B2.matchAll("23 < 24", "nExp") true