Paste: trivial parser in clay
Author: | j |
Mode: | text |
Date: | Wed, 18 Aug 2010 17:58:20 |
Plain Text |
// expr -> subexpr expr1
// subexpr -> Int
// -> "(" expr ")"
// expr1 -> null
// -> "+" expr
// -> "*" expr
record OpenParen { }
record CloseParen { }
record Plus { }
record Times { }
record EOF { }
variant Token = OpenParen | CloseParen | Plus | Times | Int | EOF;
alias ExprPtr = SharedPointer[Expression];
record PlusNode { a: ExprPtr; b: ExprPtr; }
record TimesNode { a: ExprPtr; b: ExprPtr; }
variant Expression = PlusNode | TimesNode | Int;
newExpr(v) r: SharedPointer[Expression] {
r <-- allocateShared(Expression(v));
}
record BadParse {}
instance Exception = BadParse;
nextToken(iter) {
if (hasNext?(iter)) {
return next(iter);
} else {
return Token(EOF());
}
}
expectToken(iter, T) {
var t = nextToken(iter);
if (not variantIs?(t, T)) {
println("unexpected token ", t, " should be ", T);
throw BadParse();
}
}
subexpr(a, iter) ExprPtr { println("subexpr bad token ", a); throw BadParse(); }
overload subexpr(a: Int, iter) ExprPtr = newExpr(a);
overload subexpr(a: OpenParen, iter) ExprPtr = expr(*nextToken(iter), iter);
expr(a, iter) ExprPtr {
var aa = subexpr(a, iter);
return expr1(*nextToken(iter), iter, aa);
}
expr1(b, iter, a) ExprPtr { println("expr1 bad token ", b); throw BadParse(); }
overload expr1(b: Plus, iter, a) ExprPtr = newExpr(PlusNode(a, expr(*nextToken(iter), iter)));
overload expr1(b: Times, iter, a) ExprPtr = newExpr(TimesNode(a, expr(*nextToken(iter), iter)));
overload expr1(b: EOF, iter, a) ExprPtr = a;
overload expr1(b: CloseParen, iter, a) ExprPtr = a;
parse(sequence) {
var iter = iterator(sequence);
return expr(*nextToken(iter), iter);
}
overload printTo(stream, x:ExprPtr) { printTo(stream, *(x^)); }
overload printTo(stream, x:PlusNode) { printTo(stream, "(", x.a, " + ", x.b, ")"); }
overload printTo(stream, x:TimesNode) { printTo(stream, "(", x.a, " * ", x.b, ")"); }
main() {
println(parse([Token(1), Token(Plus()), Token(2)]));
println(parse([Token(1), Token(Plus()), Token(2), Token(Times()), Token(3)]));
println(parse([Token(1), Token(Plus()), Token(OpenParen()), Token(2), Token(Times()), Token(3), Token(CloseParen())]));
println(parse([Token(1), Token(Times()), Token(2), Token(Plus()), Token(3)]));
println(parse([Token(OpenParen()), Token(1), Token(Plus()), Token(2), Token(CloseParen()), Token(Times()), Token(3)]));
println(parse([Token(OpenParen()), Token(1), Token(Plus()), Token(2), Token(CloseParen()), Token(Times()), Token(3)]));
}
New Annotation