我正在寻找分析两种句子的语法 表示由空格分隔的单词:
基本上,语法的结构应该看起来像
ID1 separator ID2
ID1: Word can contain number like Var1234 but not start with a number
ID2: Same as above but 1234 is allowed
separator: e. g. '='
@Bart
我只是尝试添加两个令牌'_'
和'"'
作为词法规则Special
,以便稍后在词法规则Word
中使用。
即使我没有在下面的语法中使用Special
,我在ANTLRWorks 1.4.2中也会出现以下错误:
以下令牌定义永远不能匹配,因为先前的令牌匹配相同的输入:特殊
但是当我在fragment
之前添加 Special
时,我没有收到该错误。为什么?
grammar Sentence1b1;
tokens
{
TCUnderscore = '_' ;
TCQuote = '"' ;
}
assignment
: id1 '=' id2
;
id1
: Word+
;
id2
: ( Word | Int )+
;
Int
: Digit+
;
// A word must start with a letter
Word
: ( 'a'..'z' | 'A'..'Z') ('a'..'z' | 'A'..'Z' | Digit )*
;
Special
: ( TCUnderscore | TCQuote )
;
Space
: ( ' ' | '\t' | '\r' | '\n' ) { $channel = HIDDEN; }
;
fragment Digit
: '0'..'9'
;
Lexer-rule Special
将在词法分析器Word
中使用:
Word
: ( 'a'..'z' | 'A'..'Z' | Special ) ('a'..'z' | 'A'..'Z' | Special | Digit )*
;
答案 0 :(得分:1)
我会选择这样的事情:
grammar Sentence;
assignment
: id1 '=' id2
;
id1
: Word+
;
id2
: (Word | Int)+
;
Int
: Digit+
;
// A word must start with a letter
Word
: ('a'..'z' | 'A'..'Z') ('a'..'z' | 'A'..'Z' | Digit)*
;
Space
: (' ' | '\t' | '\r' | '\n') {skip();}
;
fragment Digit
: '0'..'9'
;
将解析输入:
Word可以包含类似Var1234的数字,但不能以数字开头=与上述相同但允许1234
如下:
为了将lexer规则很好地打包在一起,我将它们全部放在语法的底部,而不是部分地放在tokens { ... }
块中,我只用它来定义“虚构标记”(用于创建AST) ):
// wrong!
Special : (TCUnderscore | TCQuote);
TCUnderscore : '_';
TCQuote : '"';
现在,根据上述规则,TCUnderscore
和TCQuote
永远不会成为令牌,因为当词法分析器偶然发现_
或"
时,{{1}令牌已创建。或者在这种情况下:
Special
永远不会创建// wrong!
TCUnderscore : '_';
TCQuote : '"';
Special : (TCUnderscore | TCQuote);
令牌,因为词法分析器会首先创建Special
和TCUnderscore
令牌。因此错误:
TCQuote
如果您使The following token definitions can never be matched because prior tokens match the same input: ...
和TCUnderscore
成为TCQuote
规则,则不会出现此问题,因为fragment
规则仅“提供”其他词法规则。所以这有效:
fragment
此外,// good!
Special : (TCUnderscore | TCQuote);
fragment TCUnderscore : '_';
fragment TCQuote : '"';
规则可能永远不会在任何解析器规则中“可见”(词法分析器永远不会创建fragment
或TCUnderscore
令牌!)。
TCQuote
答案 1 :(得分:0)
我不确定这是否符合您的需求,但在我的帖子中有Bart的帮助 ANTLR - identifier with whitespace 我来到这个语法:
grammar PropertyAssignment;
assignment
: id_nodigitstart '=' id_digitstart EOF
;
id_nodigitstart
: ID_NODIGITSTART+
;
id_digitstart
: (ID_DIGITSTART|ID_NODIGITSTART)+
;
ID_NODIGITSTART
: ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9')*
;
ID_DIGITSTART
: ('0'..'9'|'a'..'z'|'A'..'Z')+
;
WS : (' ')+ {skip();}
;
“a name = my 4value”有效,而“4a name = my 4value”会导致异常。