如何在不同的可选Lexer令牌中使用相同的单词

时间:2017-11-17 20:22:34

标签: c# antlr4 antlrworks

我将我的Antlr4语法简化为:

grammar test;

directives:
    ('[' directive ']')* EOF;


directive:      
      KEY1 OPERATOR OPTIONS1
    | KEY2 OPERATOR OPTIONS2;
OPERATOR: '=';

KEY1: 'Key1';
KEY2: 'Key2';

OPTIONS1: 'a'|'b'|'c';
OPTIONS2: 'c'|'d'|'e';

当我尝试使用此语法进行解析时:

[Key1=a][Key2=c]

Parser发出错误:

line 1:14 mismatched input 'c' expecting OPTIONS2

在我的实际工作中,OPTIONS1和OPTIONS2是不同的枚举数据类型,' c'是两者中的一个。

1 个答案:

答案 0 :(得分:1)

你应该拆分交叉点:

OPTIONS1: 'a'|'b';
OPTIONS2: 'd'|'e';
OPTIONS3: 'c';

所以,你的规则是:

directive:      
      KEY1 OPERATOR (OPTIONS1 | OPTIONS3)
    | KEY2 OPERATOR (OPTIONS2 | OPTIONS3)

directive:      
      KEY1 OPERATOR ('a'|'b'|'c')
    | KEY2 OPERATOR ('c'|'d'|'e');

这种情况发生了,因为Lexer从树叶中执行令牌识别,因此,您的' c'由词法分析器将其解释为OPTIONS1而不是OPTIONS2的语法顺序。

我忘了你的标记是如何被内联的(解释为宏),所以它在预处理器中看起来像这样(它也会起作用):

{{1}}

你最好阅读他们当前的语法,它可以内联。缺点是你不会在AST视图中看到OPERATOR1和OPERATOR2。