真的希望有人能夠幫助解決這個問題。我一直在玩羅伯特史蒂文的ANTLR腳本,爲excel公式創建AST。ANTLR ActionScript到Java問題
http://arcanecoder.blogspot.co.uk/2008/04/using-antlr-to-create-excel-like.html
雖然它看起來動作腳本運行時,如生成的代碼是好的,當我到渣口,我發現一個有趣的小問題。
下面的公式有一個「+」而不是「(+ 1 2)」的樹。這是我能找到的最簡單的情況,但其他公式也無法創建正確的樹。
(1 + 2)
但是,下面的工作正常:
1 + 2
任何想法可能是造成這個?提前謝謝了!!
對於下面的代碼轉儲道歉,我不知道我怎麼能簡單地解釋這個問題。這裏是我用來拉出樹字符串的代碼:
ANTLRStringStream input = new ANTLRStringStream("(1 + 2)");
FormulaLexer lexer = new FormulaLexer(input);
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
FormulaParser parser = new FormulaParser(tokenStream);
ParserRuleReturnScope scope = parser.formula();
CommonTree expressionTree = (CommonTree) scope.getTree();
System.out.println(expressionTree.toStringTree());
這裏是最後的ANTLR腳本。這幾乎等同於原,去除動作腳本選項:
/*
Originally written by Robert Stehwien
*/
grammar Formula;
options {
output=AST;
ASTLabelType=CommonTree;
}
tokens {
POS;
NEG;
CALL;
}
@package {com.arcanearcade.antlr}
@lexer::package {com.arcanearcade.antlr}
formula
: (EQ!)? expression
;
//The highest precedence expression is the most deeply nested
//Precedence ties are parsed left to right
//Expression starts with the lowest precedece rule
expression
: boolExpr
;
boolExpr
: concatExpr ((AND | OR | LT | LTEQ | GT | GTEQ | EQ | NOTEQ)^ concatExpr)*
;
concatExpr
: sumExpr (CONCAT^ sumExpr)*
;
sumExpr
: productExpr ((SUB | ADD)^ productExpr)*
;
productExpr
: expExpr ((DIV | MULT)^ expExpr)*
;
expExpr
: unaryOperation (EXP^ unaryOperation)*
;
unaryOperation
: NOT^ operand
| ADD o=operand -> ^(POS $o)
| SUB o=operand -> ^(NEG $o)
| operand
;
// the highest precedence rule uses operand
operand
: literal
| functionExpr -> ^(CALL functionExpr)
| percent
| VARIABLE
| LPAREN expression RPAREN -> ^(expression)
;
functionExpr
: FUNCNAME LPAREN! (expression (COMMA! expression)*)? RPAREN!
;
literal
: NUMBER
| STRING
| TRUE
| FALSE
;
percent
: NUMBER PERCENT^
;
STRING
:
'\"'
(options {greedy=false;}
: ESCAPE_SEQUENCE
| ~'\\'
)*
'\"'
;
WHITESPACE
: (' ' | '\n' | '\t' | '\r')+ {skip();};
TRUE
: ('t'|'T')('r'|'R')('u'|'U')('e'|'E')
;
FALSE
: ('f'|'F')('a'|'A')('l'|'L')('s'|'S')('e'|'E')
;
NOTEQ : '<>';
LTEQ : '<=';
GTEQ : '>=';
AND : '&&';
OR : '||';
NOT : '!';
EQ : '=';
LT : '<';
GT : '>';
EXP : '^';
MULT : '*';
DIV : '/';
ADD : '+';
SUB : '-';
CONCAT : '&';
LPAREN : '(';
RPAREN : ')';
COMMA : ',';
PERCENT : '%';
VARIABLE
: '[' ~('[' | ']')+ ']'
;
FUNCNAME
: (LETTER)+
;
NUMBER
: (DIGIT)+ ('.' (DIGIT)+)?
;
fragment
LETTER
: ('a'..'z') | ('A'..'Z')
;
fragment
DIGIT
: ('0'..'9')
;
fragment
ESCAPE_SEQUENCE
: '\\' 't'
| '\\' 'n'
| '\\' '\"'
| '\\' '\''
| '\\' '\\'
;
救星。謝謝! – Blueberry
不客氣@Blueberry。 –