如何计算 antlr 侦听器退出函数中的元素数量?



我有这样的语法:

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
$

呵呵

相关内容

  • 没有找到相关文章

最新更新