我有这样的语法:
xor_expression
: or_expression (XOR or_expression)*
;
我如何计算此规则中发生了多少次(XOR or_expression)*
重复。这需要从堆栈中获取有效数量的参数。例如,对于1 xor 1 xor 1
- 我需要 3 个1 xor 1
我需要 2 个,依此类推。
这给了我总的孩子,但这无关紧要。
public override void ExitXor_expression([NotNull] preprintParser.Xor_expressionContext context)
{
Debug.WriteLine(context.ChildCount);
}
要计算规则中or_expression
子级的数量,请使用标签:
xor_expression
: expr+=or_expression (XOR expr+=or_expression)*
;
这将在Xor_expressionContext
内产生一个字段
List<ParseTree> expr;
包含实际匹配的实例or_expression
。显然,expr.size()
随后将给出请求的计数。
grammar Question;
/* Count xor. */
question
@init {System.out.println("Question last update 1950");}
: expr+ EOF
;
expr
: xor_expression
;
xor_expression
: or_expression ( xors+='xor' or_expression )*
{System.out.println($text + " : " + $ctx.or_expression().size() + " or_expression with " + $ctx.xors.size() + " XOR" );}
;
or_expression
: atom
;
atom
: ID
| NUMBER
;
ID : [a-z]+ ;
NUMBER : [0-9]+ ;
WS : [ trn]+ -> channel(HIDDEN) ;
输入文件 t.text :
1 xor 1
1 xor 1 xor 1
使用 ANTLr 4.6 执行:
$ grun Question question -tokens -diagnostics t.text
[@0,0:0='1',<NUMBER>,1:0]
[@1,1:1=' ',<WS>,channel=1,1:1]
[@2,2:4='xor',<'xor'>,1:2]
[@3,5:5=' ',<WS>,channel=1,1:5]
[@4,6:6='1',<NUMBER>,1:6]
...
[@16,22:21='<EOF>',<EOF>,3:0]
Question last update 1950
1 xor 1 : 2 or_expression with 1 XOR
1 xor 1 xor 1 : 3 or_expression with 2 XOR
这些数字应该可以从侦听器访问。它们属于规则上下文。从解析器中提取:
public static class Xor_expressionContext extends ParserRuleContext {
public Token s1;
public List<Token> xors = new ArrayList<Token>();
public List<Or_expressionContext> or_expression() {
return getRuleContexts(Or_expressionContext.class);
}
我(1)稍微修改了你的语法,增加了一个访问者规则,称之为XOR
:
// file xor.g4
grammar: xor ;
prog : xor_expression+ EOF ;
xor_expression
: or_expression (XOR or_expression)* NEWLINE #XOR
;
or_expression : 'true' | 'false' ;
XOR : 'XOR' ;
WS : [ t]+ -> skip ; // toss out whitespace
NEWLINE : 'r'? 'n' ;
接下来,antlr xor.g4 -visitor
自动生成一个访问者群 impl inxorBaseVisitor.java
其中包括一个方法visitXOR( xorParser.XORContext ctx )
。(2)我扩展了该类并重新实现了此方法,我可以在其中获得两种计数 - 令牌或"真实部分"(我不知道它们在CS中叫什么)
public Integer visitXOR( xorParser.XORContext ctx ) {
List<xorParser.Or_expressionContext> mylist = ctx.or_expression();
System.out.println("visitXOR - #or children = " + mylist.size());
System.out.println("visitXOR - #getChildCount() = " + ctx.getChildCount());
for( xorParser.Or_expressionContext x : mylist ) {
System.out.println( "t" + x.getText() );
}
return 0;
}
关键在于xorParser.java
它生成一个规则上下文类,其中包含返回or_expression
列表的方法
public static class XORContext extends Xor_expressionContext {
public List<Or_expressionContext> or_expression() {
return getRuleContexts(Or_expressionContext.class);
}
...
下面是一个运行示例
$ antlr4 -visitor -no-listener xor.g4 && javac -g XorTest.java *xor*java
Note: XorTest.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
$ java XorTest
true
true XOR false XOR true
^D
visitXOR - #or children = 1
visitXOR - #getChildCount() = 2
true
visitXOR - #or children = 3
visitXOR - #getChildCount() = 6
true
false
true
$
呵呵