我有这样的语法:
xor_expression
: or_expression (XOR or_expression)*
;
如何计算此规则中发生的(XOR or_expression)*
次重复次数。这需要从堆栈有效数量的参数中获取。例如,对于1 xor 1 xor 1
- 1 xor 1
需要3,我需要2,等等。
这给了我全部的孩子,但没有关系。
public override void ExitXor_expression([NotNull] preprintParser.Xor_expressionContext context)
{
Debug.WriteLine(context.ChildCount);
}
答案 0 :(得分:0)
要计算规则中or_expression
个孩子的数量,请使用标签:
xor_expression
: expr+=or_expression (XOR expr+=or_expression)*
;
这将在Xor_expressionContext
内产生一个字段
List<ParseTree> expr;
包含实际匹配的or_expression
个实例。显然,expr.size()
将提供所请求的计数。
答案 1 :(得分:0)
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 : [ \t\r\n]+ -> 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);
}
答案 2 :(得分:0)
我(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
会自动生成xorBaseVisitor.java
中的访问者群,其中包含方法visitXOR( xorParser.XORContext ctx )
。 (2)我扩展了那个类并重新实现了这个方法,在那里我可以获得两种计数 - 令牌或&#34;真实部分&#34; (我不知道他们在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
$
HTH