ANTLR C#4语法-优先级
我有下面的语法(为了演示而简化),在一个与逻辑运算符相关的特殊情况下,我遇到了一个问题 除了逻辑运算符在我引用的标识符内的情况外,我测试的所有内容都有效。例如,这项工作: @M=“ABC12345” 但这并不是: @M=“ABC12OR345” 发生的情况是字符串中的OR导致以下错误 “外部输入”或“预期{'”,LOWCHARANTLR C#4语法-优先级,antlr,grammar,Antlr,Grammar,我有下面的语法(为了演示而简化),在一个与逻辑运算符相关的特殊情况下,我遇到了一个问题 除了逻辑运算符在我引用的标识符内的情况外,我测试的所有内容都有效。例如,这项工作: @M=“ABC12345” 但这并不是: @M=“ABC12OR345” 发生的情况是字符串中的OR导致以下错误 “外部输入”或“预期{'”,LOWCHAR
grammar PRDL;
options
{
language=CSharp;
}
statement
: expression ( logicalOperator expression )*
;
logicalOperator
: logicalOR | logicalAND
;
logicalOR
: OR
;
logicalAND
: AND
;
expression
: mVar
| nVar
| parenStatement
| notExpression
;
parenStatement
: LPAREN statement RPAREN
;
notExpression
: NOT expression
;
mVar
: M equalityOperator quotedIdentifier
;
nVar
: N equalityOperator quotedIdentifier
;
equalityOperator
: EQUAL
;
quotedIdentifier
: '"' identifier '"'
;
identifier
: (HIGHCHAR | LOWCHAR | DIGIT)+
;
// ============ Lexer Defintions ========================
// OPERATORS
NOT_ALLOWED : '*' | '/' | '+' | '-' | '#' | '$' | '%' | '^';
EQUAL : '=';
COMMA : ',';
LPAREN : '(';
RPAREN : ')';
LPARENSQ : '[';
RPARENSQ : ']';
OR : ('OR' | 'or' | '||');
AND : ('AND' | 'and' | '&&');
NOT : ('NOT' | 'not' | '!') ;
M : '@M';
N : '@N';
LOWCHAR : 'a'..'z';
HIGHCHAR : 'A'..'Z';
DIGIT : '0'..'9';
// Whitespace -- ignored
WS : [ \n\t\r\f]+ -> skip;
你把lexer和parser之间的条放错地方了
quotedIdentifier
: '"' identifier '"'
;
identifier
: (HIGHCHAR | LOWCHAR | DIGIT)+
;
现在,每一封信都成为一种象征。这不会很好地工作,正如你所看到的,因为你会犯错误
这两个解析器规则实际上应该是lexer规则:
QUOTED_IDENTIFIER
: '"' (HIGHCHAR | LOWCHAR | DIGIT)+ '"'
;
IDENTIFIER
: (HIGHCHAR | LOWCHAR | DIGIT)+
;
和HIGHCHAR
,LOWCHAR
和DIGIT
应该是片段,以防止在单个字符上获得不同的令牌类型:
fragment LOWCHAR : 'a'..'z';
fragment HIGHCHAR : 'A'..'Z';
fragment DIGIT : '0'..'9';
使用这样的lexer,每个标识符将获得一个令牌,这对于解析来说更好
而且,像这样的规则几乎毫无用处:
equalityOperator
: EQUAL
;
因为这只是将lexer规则与解析器规则混淆。嗨,卢卡斯,谢谢你的回复。根据您的信息,我尝试了几种变体,但仍然存在问题。抱歉,按enter键后无法及时返回。我没有提到的一点是,我使用的是一个侦听器,因此在解析器中有更多的规则(例如,public override void ExitQuotedIdentifier…)。在解析时,我正在构建一个内部列表,稍后我可以将实值应用于变量并计算真/假条件。看起来我需要做更多的阅读来更好地理解使用这个版本的antlr-与我8年或10年前使用的版本有些不同。好的,我明白了。通过更改:标识符:(高字符|低字符|数字)+;对此:标识符:标识符+;然后像这样把标识符放在lexer中:IDENTIFIER:(HIGHCHAR | LOWCHAR | DIGIT)+;我能让事情顺利进行。谢谢