首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ANTLR4 grun钻机似乎没有正确报告令牌.我明白了吗?

ANTLR4 grun钻机似乎没有正确报告令牌.我明白了吗?
EN

Stack Overflow用户
提问于 2017-01-19 20:42:36
回答 2查看 666关注 0票数 1

我正在用grun测试一些语法,我没有看到我的标记被识别为令牌。我最初认为可能是基于这个StackOverflow链路创建了“隐式”令牌。

此外,在查看grun -tokens的输出时,我发现了以下链接: 1)最近的变化到-tokens输出。2)可能是过时的testrig.md --我已经把它分叉了,并且正在深入研究它。

下面是我的简单HelloTC.g4,在这里我探索了以下内容:

代码语言:javascript
复制
grammar HelloTC;
r  : HELLO id; 
WS : [ \r\t\n]+ -> skip ;
CMD: '%';
DIR: '%%';
A:   'A'; 
AA:  'AA';
HELLO:'hello';
ID : [a-z]+ ;
id :  DIR | CMD | A | AA;

我用以下方法进行测试:

代码语言:javascript
复制
grun HelloTC r -tokens
hello %%
hello %
hello A
hello AA
^Z

[@0,0:4='hello',<'hello'>,1:0]
[@1,6:7='%%',<'%%'>,1:6]
[@2,10:14='hello',<'hello'>,2:0]
[@3,16:16='%',<'%'>,2:6]
[@4,19:23='hello',<'hello'>,3:0]
[@5,25:25='A',<'A'>,3:6]
[@6,28:32='hello',<'hello'>,4:0]
[@7,34:35='AA',<'AA'>,4:6]
[@8,38:37='<EOF>',<EOF>,5:0]

我的令牌中没有一个被识别为令牌。我原以为:

代码语言:javascript
复制
[@0,0:4='hello',<HELLO>,1:0]
[@1,6:7='%%',<DIR>,1:6]
[@2,10:14='hello',<HELLO>,2:0]
[@3,16:16='%',<CMD>,2:6]
[@4,19:23='hello',<HELLO>,3:0]
[@5,25:25='A',<A>,3:6]
[@6,28:32='hello',<HELLO>,4:0]
[@7,34:35='AA',<AA>,4:6]
[@8,38:37='<EOF>',<EOF>,5:0]

在我的预期结果中,我用令牌名替换了“chars”。

我使用antlr4运行-Xlog,并且声明了令牌(仅次于最后一行),所以现在我想知道我是否误解了grun报告的内容。我期望<>中的数据是由lexer传递的令牌名。我是不是搞错了?

我能对我的语法做些什么来使标记被识别为标记呢?或者..。如何调试语法以确保lexer正确识别标记?

这是我的-Xlog文件:

代码语言:javascript
复制
2017-01-20 06:57:29:640 grammar LogManager.java:25 before: (COMBINED_GRAMMAR HelloTC (RULES (RULE r (BLOCK (ALT HELLO id))) (RULE WS (BLOCK (LEXER_ALT_ACTION (ALT (+ (BLOCK (ALT [ \r\t\n])))) skip))) (RULE CMD (BLOCK (ALT '%cat'))) (RULE DIR (BLOCK (ALT '%%'))) (RULE A (BLOCK (ALT 'A'))) (RULE AA (BLOCK (ALT 'AA'))) (RULE HELLO (BLOCK (ALT 'hello'))) (RULE id (BLOCK (ALT DIR) (ALT CMD) (ALT A) (ALT AA)))))
2017-01-20 06:57:29:661 grammar LogManager.java:25 after: (COMBINED_GRAMMAR HelloTC (RULES (RULE r (BLOCK (ALT HELLO id))) (RULE WS (BLOCK (LEXER_ALT_ACTION (ALT (+ (BLOCK (ALT [ \r\t\n])))) skip))) (RULE CMD (BLOCK (ALT '%cat'))) (RULE DIR (BLOCK (ALT '%%'))) (RULE A (BLOCK (ALT 'A'))) (RULE AA (BLOCK (ALT 'AA'))) (RULE HELLO (BLOCK (ALT 'hello'))) (RULE id (BLOCK (ALT (SET DIR CMD A AA))))))
2017-01-20 06:57:29:694 grammar LogManager.java:25 after extract implicit lexer =(COMBINED_GRAMMAR HelloTC (RULES (RULE r (BLOCK (ALT HELLO id))) (RULE id (BLOCK (ALT (SET DIR CMD A AA))))))
2017-01-20 06:57:29:694 grammar LogManager.java:25 lexer =(LEXER_GRAMMAR HelloTCLexer (RULES (RULE WS (BLOCK (LEXER_ALT_ACTION (ALT (+ (BLOCK (ALT [ \r\t\n])))) skip))) (RULE CMD (BLOCK (ALT '%cat'))) (RULE DIR (BLOCK (ALT '%%'))) (RULE A (BLOCK (ALT 'A'))) (RULE AA (BLOCK (ALT 'AA'))) (RULE HELLO (BLOCK (ALT 'hello')))))
2017-01-20 06:57:30:040 semantics LogManager.java:25 tokens={EOF=-1, WS=1, CMD=2, DIR=3, A=4, AA=5, HELLO=6}
2017-01-20 06:57:30:040 semantics LogManager.java:25 strings={'%cat'=2, '%%'=3, 'A'=4, 'AA'=5, 'hello'=6}

下面是我试图为之创建语法类型的一个例子。

代码语言:javascript
复制
//COMMENTS
;comments
%%DIRECTIVEA
%%DIRECTIVEB
RESERVED_TOKEN(ARGS,ARGS)
%commandA
 commandB
 commandD
 commandE
 ...
 CommandH  (only A-H allowed)
// comments
%commandB
%%DIRECTIVEB
%commandD
 commandE
%commandA
 done

我还在挖和做实验。希望这个问题和任何答案都能帮助到其他人。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-06 20:06:20

我也很惊讶。在以前的版本中,令牌的名称甚至没有翻译:

代码语言:javascript
复制
[@0,0:4='hello',<6>,1:0]
[@1,6:7='%%',<3>,1:6]
[@2,9:13='hello',<6>,2:0]
[@3,15:15='%',<2>,2:6]
[@4,17:21='hello',<6>,3:0]
[@5,23:23='A',<4>,3:6]
[@6,25:29='hello',<6>,4:0]
[@7,31:32='AA',<5>,4:6]
[@8,34:33='<EOF>',<-1>,5:0]

几年前,我编写了一个Ruby脚本,通过获取<n>文件将<grammar>.tokens转换为名称。它现在已经在4.6中完成了。

如果您以这种方式并按照以下顺序定义HELLO和ID:

代码语言:javascript
复制
HELLO
    : [a-z]+ {getText().equals("hello")}? ;
ID  : [a-z]+ ;

有了这个输入

代码语言:javascript
复制
    hello %%
...
    hello xyz

你得到的结果是:

代码语言:javascript
复制
    [@0,0:4='hello',<HELLO>,1:0]
    [@1,6:7='%%',<'%%'>,1:6]
...
    [@8,34:38='hello',<HELLO>,5:0]
    [@9,40:42='xyz',<ID>,5:6]

输入hello是模棱两可的,它可以由两个规则匹配。当输入为HELLO时,lexer规则中的语法谓词允许lexer选择hello

我们可以得出结论,常量由它们自己表示,而其他输入则由令牌名称表示。尽管有这种好奇,你的代币还是被正确识别了。如果不是这样的话,解析器就会抱怨:输入hello %% 123给出:

代码语言:javascript
复制
$ grun Question r -tokens data.txt 
line 1:9 token recognition error at: '1'
line 1:10 token recognition error at: '2'
line 1:11 token recognition error at: '3'
[@0,0:4='hello',<HELLO>,1:0]
[@1,6:7='%%',<'%%'>,1:6]

如果在语法中添加INT规则

代码语言:javascript
复制
INT : [0-9]+ ;

然后识别新的令牌:

代码语言:javascript
复制
[@0,0:4='hello',<HELLO>,1:0]
[@1,6:7='%%',<'%%'>,1:6]
[@2,9:11='123',<INT>,1:9]
票数 1
EN

Stack Overflow用户

发布于 2017-01-20 17:51:51

这可不完美。grun输出仍然没有输出我的tokens..but --我可以通过插入System.out.printlin()操作继续学习针对System.out.printlin的操作。缺点是,在我做完之后,我必须取出这些调试子句。最终,我的目标解析器将基于python。但我仍在学习Java的过程中。

链接演示如何使用操作进行调试。

在此之后,我修改了我的HelloTC.gr以:

代码语言:javascript
复制
grammar HelloTC;
r  : HELLO id+ {System.out.println("r rule encountered");};
WS : [ \r\t\n]+ -> skip ;
CMD: '%' {System.out.println("Lexer found a CMD");};
DIR: '%%'{System.out.println("Lexer found a DIR");};
A:   'A';
AA:  'AA';
HELLO:'hello'{System.out.println("Lexer found a HELLO");};
ID : [a-z]+ ;
id :  DIR | CMD | A | AA { System.out.println("Parser found rule match "+$text);};

并使用grun产率进行调试:

代码语言:javascript
复制
java org.antlr.v4.gui.TestRig HelloTC r -tokens
hello%%
hello %%
^Z
Lexer found a HELLO
Lexer found a DIR
Lexer found a HELLO
Lexer found a DIR
[@0,0:4='hello',<'hello'>,1:0]
[@1,5:6='%%',<'%%'>,1:5]
[@2,9:13='hello',<'hello'>,2:0]
[@3,15:16='%%',<'%%'>,2:6]
[@4,19:18='<EOF>',<EOF>,3:0]
line 2:0 extraneous input 'hello' expecting {<EOF>, '%', '%%', 'A', 'AA'}
r rule encountered

因此,好消息是,人们看到了Lexer规则,我有一种分析/调试的技术。我想要理解/破译更多的grun,我将不得不查看源代码more...thatleads,希望“构建/测试”对antlr的修改,这是一个滑坡。我试着把注意力集中在原来的任务上.正在开发一个解析器。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41751325

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档