Antlr 语法不起作用(NoViableAltException)
我是ANTLR的新手,我正试着和它一起玩。这是我所能想到的最简单的语法,当我解析变量“id123”时,它仍然不起作用(NoViableAltException),但它适用于“abc1”、“ab”、“c1d2f3” 我使用的是AntlR3.1.3和ANTLRWorks 1.4Antlr 语法不起作用(NoViableAltException),antlr,antlr3,Antlr,Antlr3,我是ANTLR的新手,我正试着和它一起玩。这是我所能想到的最简单的语法,当我解析变量“id123”时,它仍然不起作用(NoViableAltException),但它适用于“abc1”、“ab”、“c1d2f3” 我使用的是AntlR3.1.3和ANTLRWorks 1.4 options { language = 'CSharp2'; output = AST; } assign : variable '=' value; value : (variable|
options
{
language = 'CSharp2';
output = AST;
}
assign : variable '=' value;
value : (variable|constant);
variable: LETTER (LETTER|DIGIT)*;
constant: (STRING|INTEGER);
DIGIT : '0'..'9';
NATURAL : (DIGIT)+;
INTEGER : ('-')? NATURAL;
REAL : (INTEGER '.' NATURAL);
LETTER : ('a'..'z'|'A'..'Z');
CR : '\r' { $channel = HIDDEN; };
LF : '\n' { $channel = HIDDEN; };
CRLF : CR LF { $channel = HIDDEN; };
SPACE : (' '|'\t') { $channel = HIDDEN; };
STRING : '"' (~'"')* '"';
ANTLR的lexer尽量匹配。每当两个(或更多)规则匹配相同数量的字符时,首先定义的规则将“获胜”。因此,每当词法分析器偶然发现单个数字时,就会创建一个
数字
标记,因为它是在自然
之前定义的:
DIGIT : '0'..'9';
NATURAL : (DIGIT)+;
但是对于输入“id123”
,lexer生成了以下3个令牌:
LETTER 'i'
LETTER 'd'
NATURAL '123'
因为lexer贪婪地匹配,因此创建了一个NATURAL
,而不是三个数字
标记
您应该做的是将lexer规则改为变量
:
assign : VARIABLE '=' value;
value : (VARIABLE | constant);
constant : (STRING | INTEGER | REAL);
VARIABLE : LETTER (LETTER|DIGIT)*;
INTEGER : ('-')? NATURAL;
REAL : (INTEGER '.' NATURAL);
SPACE : (' ' | '\t' | '\r' | '\n') { $channel = HIDDEN; };
STRING : '"' (~'"')* '"';
fragment NATURAL : (DIGIT)+;
fragment DIGIT : '0'..'9';
fragment LETTER : ('a'..'z' | 'A'..'Z');
还要注意,我制定了两条lexer规则fragment
s。这意味着lexer永远不会产生自然
、数字
或字母
标记。这些fragment
规则只能由其他lexer规则使用。换句话说,你的lexer只会产生变量
、整数
、实数
、和字符串
标记*(所以你只能在解析器规则中使用这些标记!)
*当然,还有
'='
令牌…谢谢您的解释,但是现在分配不起作用。我正在尝试“id123=2222”。我只是复制并粘贴了你的答案。