ANTLR:由于可以从alts 1,2访问递归规则调用,规则标记具有非LL(*)决策
试图在ANTLRWorks 1.4中解释此问题,并出现以下错误:ANTLR:由于可以从alts 1,2访问递归规则调用,规则标记具有非LL(*)决策,antlr,Antlr,试图在ANTLRWorks 1.4中解释此问题,并出现以下错误: grammar AdifyMapReducePredicate; PREDICATE : PREDICATE_BRANCH | EXPRESSION ; PREDICATE_BRANCH : '(' PREDICATE (('&&' PREDICATE)+ | ('||' PREDICATE)+) ')' ; EXPRESSION : ('a
grammar AdifyMapReducePredicate;
PREDICATE
: PREDICATE_BRANCH
| EXPRESSION
;
PREDICATE_BRANCH
: '(' PREDICATE (('&&' PREDICATE)+ | ('||' PREDICATE)+) ')'
;
EXPRESSION
: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
[12:18:21]错误(211)::1:8:[致命]规则令牌具有非LL(*)决策,因为可以从alts 1,2访问递归规则调用。通过左因子分解或使用语法谓词或使用backtrack=true选项进行解析。
[12:18:21]口译。。。
当我插入谓词时,我试图解释一个谓词,我的测试用例是(a | | B)
我遗漏了什么?您没有语法分析器规则(语法分析器规则以小写字母开头),尽管我不确定在解释AntlWorks中的一些测试用例时是否需要最后一部分 无论如何,请尝试以下方法:
[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...
使用以下测试类:
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();}
;
生成lexer&parser(a)、编译所有.java
文件(b)并运行测试类(c)后,生成以下输出:
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();
}
}
解析::(A | | B)
解析::(C&(D|F|G))
A.
java-cp antlr-3.2.jar org.antlr.Tool AdifyMapReducePredicate.g
B
javac-cp antlr-3.2.jar*.java
c(*nix/MacOS)
java-cp.:antlr-3.2.jar Main
c(Windows)
java-cp。;antlr-3.2.jar主管道
HTH根据ANTLR的约定,解析器规则名称以小写字母开头,而lexer规则以大写字母开头。因此,正如您所写的,语法有三条lexer规则,定义标记。这可能不是你想要的 错误消息的原因显然是这些标记之间的歧义:您的输入模式匹配谓词和谓词分支的定义 只需使用以小写字母开头的名称,而不是谓词和谓词分支。您可能还必须为目标符号添加一个额外的规则,该规则不直接涉及递归
顺便说一下,这种语法是递归的,但不是左递归的,当使用解析器规则时,它肯定是LL(1)。Wow,非常完整。我会尝试一下,但是当我集成它时,您能解释一下“左递归”的实际含义以及如何识别左递归吗?@Hounshell,@Gunther是对的:它不是左递归的,因为您的令牌谓词分支匹配一个
(
在它匹配谓词之前。很抱歉造成混淆!lexer和解析器之间有什么区别?可以在这篇文章中找到一个很好的解释:
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