我正在用grun测试一些语法,我没有看到我的标记被识别为令牌。我最初认为可能是基于这个StackOverflow链路创建了“隐式”令牌。
此外,在查看grun -tokens的输出时,我发现了以下链接: 1)最近的变化到-tokens输出。2)可能是过时的testrig.md --我已经把它分叉了,并且正在深入研究它。
下面是我的简单HelloTC.g4,在这里我探索了以下内容:
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;我用以下方法进行测试:
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]我的令牌中没有一个被识别为令牌。我原以为:
[@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文件:
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}下面是我试图为之创建语法类型的一个例子。
//COMMENTS
;comments
%%DIRECTIVEA
%%DIRECTIVEB
RESERVED_TOKEN(ARGS,ARGS)
%commandA
commandB
commandD
commandE
...
CommandH (only A-H allowed)
// comments
%commandB
%%DIRECTIVEB
%commandD
commandE
%commandA
done我还在挖和做实验。希望这个问题和任何答案都能帮助到其他人。
发布于 2017-02-06 20:06:20
我也很惊讶。在以前的版本中,令牌的名称甚至没有翻译:
[@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:
HELLO
: [a-z]+ {getText().equals("hello")}? ;
ID : [a-z]+ ;有了这个输入
hello %%
...
hello xyz你得到的结果是:
[@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给出:
$ 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规则
INT : [0-9]+ ;然后识别新的令牌:
[@0,0:4='hello',<HELLO>,1:0]
[@1,6:7='%%',<'%%'>,1:6]
[@2,9:11='123',<INT>,1:9]发布于 2017-01-20 17:51:51
这可不完美。grun输出仍然没有输出我的tokens..but --我可以通过插入System.out.printlin()操作继续学习针对System.out.printlin的操作。缺点是,在我做完之后,我必须取出这些调试子句。最终,我的目标解析器将基于python。但我仍在学习Java的过程中。
此链接演示如何使用操作进行调试。
在此之后,我修改了我的HelloTC.gr以:
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产率进行调试:
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的修改,这是一个滑坡。我试着把注意力集中在原来的任务上.正在开发一个解析器。
https://stackoverflow.com/questions/41751325
复制相似问题