这个语法有什么问题? (ANTLRWorks 1.4) [英] What is wrong with this grammar? (ANTLRWorks 1.4)
问题描述
我用ANTLRWorks 1.4编写了以下代码
I have the following code written in ANTLRWorks 1.4
grammar hmm;
s : (put_a_in_b)|(put_out_a)|(drop_kick)|(drop_a)|(put_on_a);
put_a_in_b : (PUT_SYN)(ID)(IN_SYN)(ID);
put_out_a : (PUT2_SYN)(OUT_SYN)(ID) | (E1)(ID);
drop_kick : ('drop')('kick')(ID);
drop_a : (DROP_SYN)(ID);
put_on_a : (E2)(ID);
PUT_SYN : 'put' | 'place' | 'drop';
PUT2_SYN : 'put' | 'douse';
IN_SYN : 'in' | 'into' | 'inside' | 'within';
OUT_SYN : 'out';
E1 : 'extinguish'|'douse';
DROP_SYN : 'drop' | 'throw' | 'relinquish';
WS : ( ' ' | '\t' | '\r' | '\n' ) {$channel=HIDDEN;};
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
E2 : 'put on'|'don'|'wear';
COMMENT
: '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
| '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
;
当我用输入运行它时:
drop object
我收到了MismatchedTokenException(5!= 15).
I get a MismatchedTokenException(5 != 15).
并输入:
put o1 in o2
我收到一个NoViableAltException.
I get a NoViableAltException.
尽管可以正常运行
place o2 in o2
我对此并不陌生,但似乎有歧义吗?也许我对ANTLR的使用不正确?
I'm new to this, but it seems like there's ambiguities? Or maybe my usage of ANTLR is incorrect?
推荐答案
您已将'drop'
和'put'
放入了两个不同的词法规则:
You've put 'drop'
and 'put'
in two different lexer-rules:
PUT_SYN : 'put' | 'place' | 'drop'; // drop & put
PUT2_SYN : 'put' | 'douse'; // put
...
DROP_SYN : 'drop' | 'throw' | 'relinquish'; // drop
当词法分析器遇到put
时,PUT_SYN
将始终是与之匹配的规则,因此'put'
可以(或应该)从PUT2_SYN
规则中删除.
When put
is encountered by the lexer, PUT_SYN
will always be the rule that matches it, so 'put'
could (or should) be removed from the PUT2_SYN
rule.
因此,您在解析字符串drop object
时遇到的问题:解析器将尝试匹配drop_a : (DROP_SYN)(ID);
,但是在词法分析器规则PUT_SYN
中将匹配"drop"
.
So, your problem with parsing the string drop object
: the parser will try to match drop_a : (DROP_SYN)(ID);
but the "drop"
will be matched in the lexer rule PUT_SYN
.
编辑
可以更好地将这些同义词列表设置为解析器规则(而不是词法规则).这是一个小演示:
Those synonym-lists can be better made into parser rules (instead of lexer-rules). Here's a small demo:
grammar TextAdventure;
parse
: command (EndCommand command)* EOF
;
command
: put_syn_1 OtherWord in_syn OtherWord
| put_syn_2 out_syn_1 OtherWord
| out_syn_2 OtherWord
| Drop Kick OtherWord
| drop_syn OtherWord
;
drop_syn
: Drop
| Throw
| Relinquish
;
in_syn
: In
| Into
| Inside
| Within
;
put_syn_1
: Put
| Place
| Drop
;
put_syn_2
: Put
| Douse
;
out_syn_1
: Out
;
out_syn_2
: Extinguish
| Douse
;
Space : (' ' | '\t' | '\r' | '\n'){$channel=HIDDEN;};
EndCommand : ';';
Put : 'put';
Place : 'place';
Drop : 'drop';
Douse : 'douse';
In : 'in';
Into : 'into';
Inside : 'inside';
Within : 'within';
Out : 'out';
Extinguish : 'extinguish';
Throw : 'throw';
Relinquish : 'relinquish';
Kick : 'kick';
OtherWord : ('a'..'z' | 'A'..'Z')+;
解释以下来源时:
drop object ; put yourself in myshoes ; place it in avase
您将看到ANTLRWorks生成以下解析树:
you'll see ANTLRWorks generate the following parse-tree:
这篇关于这个语法有什么问题? (ANTLRWorks 1.4)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!