作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
以下语法有效,但也会给出警告:
grammar test;
options {
language = Java;
output = AST;
ASTLabelType = CommonTree;
}
program
: expr ';'!
;
term: ID | INT
;
assign
: term ('='^ expr)?
;
add : assign (('+' | '-')^ assign)*
;
expr: add
;
// T O K E N S
ID : (LETTER | '_') (LETTER | DIGIT | '_')* ;
INT : DIGIT+ ;
WS :
( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
DOT : '.' ;
fragment
LETTER : ('a'..'z'|'A'..'Z') ;
fragment
DIGIT : '0'..'9' ;
[15:08:20] warning(200): C:\Users\Charles\Desktop\test.g:21:34:
Decision can match input such as "'+'..'-'" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
再说一次,它确实按照我想要的方式生成一棵树:
Input: 0 + a = 1 + b = 2 + 3;
ANTLR produces | ... but I think it
this tree: | gives the warning
| because it _could_
+ | also be parsed this
/ \ | way:
0 = |
/ \ | +
a + | / \
/ \ | + 3
1 = | / \
/ \ | + =
b + | / \ / \
/ \ | 0 = b 2
2 3 | / \
| a 1
我如何明确告诉 ANTLR 我希望它在左侧创建 AST,从而明确我的意图并消除警告?
最佳答案
Charles wrote:
How can I explicitly tell ANTLR that I want it to create the AST on the left, thus making my intent clear and silencing the warning?
您不应为分配
和添加
创建两个单独的规则。按照您现在的规则,assign
优先于您不希望的 add
:通过查看您想要的 AST,它们应该具有相同的优先级。因此,您需要将所有运算符 +
、-
和 =
包装在一条规则中:
program
: expr ';'!
;
expr
: term (('+' | '-' | '=')^ expr)*
;
但是现在语法仍然有歧义。您需要“帮助”解析器超越这种歧义,以确保在解析 (('+' | '-' | '=') expr 时确实前面存在
。这可以使用 syntactic predicate 来完成,看起来像这样:operator expr
)*
(look_ahead_rule(s)_in_here)=> rule(s)_to_actually_parse
(( ... )=>
是谓词语法)
一个小演示:
grammar test;
options {
output=AST;
ASTLabelType=CommonTree;
}
program
: expr ';'!
;
expr
: term ((op expr)=> op^ expr)*
;
op
: '+'
| '-'
| '='
;
term
: ID
| INT
;
ID : (LETTER | '_') (LETTER | DIGIT | '_')* ;
INT : DIGIT+ ;
WS : (' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;};
fragment LETTER : ('a'..'z'|'A'..'Z');
fragment DIGIT : '0'..'9';
可以使用以下类进行测试:
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;
public class Main {
public static void main(String[] args) throws Exception {
String source = "0 + a = 1 + b = 2 + 3;";
testLexer lexer = new testLexer(new ANTLRStringStream(source));
testParser parser = new testParser(new CommonTokenStream(lexer));
CommonTree tree = (CommonTree)parser.program().getTree();
DOTTreeGenerator gen = new DOTTreeGenerator();
StringTemplate st = gen.toDOT(tree);
System.out.println(st);
}
}
并且Main类的输出对应于以下AST:
其创建时没有来自 ANTLR 的任何警告。
关于parsing - ANTLR 赋值表达式消歧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7354124/
我是一名优秀的程序员,十分优秀!