grammar AdifyMapReducePredicate;
PREDICATE
: PREDICATE_BRANCH
| EXPRESSION
;
PREDICATE_BRANCH
: '(' PREDICATE (('&&' PREDICATE)+ | ('||' PREDICATE)+) ')'
;
EXPRESSION
: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
尝试在ANTLRWorks 1.4中解释这一点,并收到以下错误:
[12:18:21] error(211): <notsaved>:1:8: [fatal] rule Tokens has non-LL(*) decision due to recursive rule invocations reachable from alts 1,2. Resolve by left-factoring or using syntactic predicates or using backtrack=true option.
[12:18:21] Interpreting...
当我解释时,我正试图解释一个预测,我的测试用例是(A || B)
我错过了什么?
答案 0 :(得分:5)
根据ANTLR的约定,解析器规则名称以小写字母开头,而词法分析器规则以大写字母开头。所以语法就像你写的一样,有三个词法规则,定义了令牌。这可能不是你想要的。
错误消息的原因显然是这些令牌之间存在歧义:您的输入模式与PREDICATE和PREDICATE_BRANCH的定义相匹配。
只使用以小写字母开头的名称而不是PREDICATE和PREDICATE_BRANCH。您可能还需要为目标符号添加一个额外的规则,该规则不直接参与递归。
顺便说一句,这个语法是递归的,但不是左递归的,当使用解析器规则时,它绝对是LL(1)。
答案 1 :(得分:1)
你没有解析器规则(解析器规则以小写字母开头),虽然在解释ANTLRWorks中的一些测试用例时我不确定最后一部分是否必要。
无论如何,尝试这样的事情:
grammar AdifyMapReducePredicate;
parse
: (p=predicate {System.out.println("parsed :: "+$p.text);})+ EOF
;
predicate
: expression
;
expression
: booleanExpression
;
booleanExpression
: atom ((AND | OR) atom)*
;
atom
: ID
| '(' predicate ')'
;
AND
: '&&'
;
OR
: '||'
;
ID
: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
SPACE
: (' ' | '\t' | '\r' | '\n') {skip();}
;
使用以下测试类:
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;
public class Main {
public static void main(String[] args) throws Exception {
ANTLRStringStream in = new ANTLRStringStream("(A || B) (C && (D || F || G))");
AdifyMapReducePredicateLexer lexer = new AdifyMapReducePredicateLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
AdifyMapReducePredicateParser parser = new AdifyMapReducePredicateParser(tokens);
parser.parse();
}
}
在生成词法分析器&amp;解析器(a),编译所有.java
个文件(b)并运行测试类(c),产生以下输出:
parsed :: (A||B) parsed :: (C&&(D||F||G))
java -cp antlr-3.2.jar org.antlr.Tool AdifyMapReducePredicate.g
javac -cp antlr-3.2.jar *.java
java -cp .:antlr-3.2.jar Main
java -cp .;antlr-3.2.jar Main
HTH