|
|||||
|
|||||
Groovy Parser
With Groovy's nice closure support, we can avoid most anonymous class and hence get a much less cluttered parser code. In the [Tutorial] section, we described how a calculator can be built using Java API. We will now present a groovy version that is much shorter. import jfun.parsec.pattern.Patterns; import jfun.parsec.*; import jfun.parsec.tokens.Tokenizers; def getCalculatorParser(){ def s_line_comment = Scanners.javaLineComment(); def s_block_comment = Scanners.isBlockComment("/*","*/"); def s_whitespace = Scanners.isWhitespaces(); def l_number = Lexers.decimal(); def ops = Terms.getOperatorsInstance("+","-","*","/", "(", ")"); def s_delim = [s_line_comment, s_block_comment, s_whitespace].first().many(); def l_tok = ops.getLexer() | l_number; def lexer = Lexers.lexeme(s_delim, l_tok).followedBy(Parsers.eof()); def p_binary_ops = ops.getParser(["+","-","*","/"] as String[]); def p_whitespace_mul = p_binary_ops.not(); def getOperator2 = {k,v->ops.getParser(k).seq(Map2.impl(v))}; def getOperator = {k,v->ops.getParser(k).seq(Map.impl(v))}; def p_plus = getOperator2("+"){a,b->a+b}; def p_minus = getOperator2("-"){a,b->a-b}; def p_mul = (ops.getParser("*") | p_whitespace_mul).seq(Map2.impl{a,b->a*b}); def p_div = getOperator2("/"){a,b->a/b}; def p_neg = getOperator("-"){a->-a}; def p_lparen = ops.getParser("("); def p_rparen = ops.getParser(")"); def p_number = Terms.decimalParser(FromString.impl{ int from, int len, String s -> Double.valueOf(s) }); def p_expr; def p_lazy_expr = {p_expr}.asParser(); def p_term = Parsers.between(p_lparen, p_rparen, p_lazy_expr)|p_number; def optable = new OperatorTable() .infixl(p_plus, 10) .infixl(p_minus, 10) .infixl(p_mul, 20) .infixl(p_div, 20) .prefix(p_neg, 30); p_expr = Expressions.buildExpressionParser(p_term, optable); def parser = Parsers.parseTokens(lexer, p_expr.followedBy(Parsers.eof()), "calculator"); } use(org.codehaus.parsec.groovy.ParserCategory){ def parser = getCalculatorParser(); println(parser.parse("1+(1-0) 3.0")); }
The source code of the ParserCategory class can be downloaded here, binary here |
|||||
|
Copyright 2003-2006 - The Codehaus. All rights reserved unless otherwise noted.
Powered by Atlassian Confluence
|
|||||