如何在Antlr中处理令牌的子集时如何处理令牌?

时间:2012-01-01 21:31:26

标签: antlr antlr3

我正在尝试将为未知工具开发的现有语法移植到Antlr。 语法中有一个用例,其中有两个标记,如TEXT和TEXT_WITHOUT_A 语法中的一些规则应该只允许没有a的文本,但其余的则可以使用文本。

我最初的尝试产生了以下语法,但问题是,当txt实际上是它的超集时,Antlr匹配更具体的语法规则(txtwa)。如果我输入类似'sometextwth'的不包含a的内容,Antlr不遵循文本规则(txt)预期的输入是txt,提供的输入匹配是,但Antlr指出输入匹配txtwa,即使在语法的那一点上没有预料到,选择不使用txt。

    /*------------------------------------------------------------------
 * PARSER RULES
 *------------------------------------------------------------------*/
 expr   :   (  txt)* ;
 txt    :   TEXT ;
 txtwa  :   LETTERS_MINUS_A;
 term   :   factor ( (MULT | DIV) factor)*;
 factor :   NUMBER;

/*------------------------------------------------------------------
 * LEXER RULES
 *------------------------------------------------------------------*/


NUMBER              :   (DIGIT)+ ;

WHITESPACE      :   ( '\t' | ' ' | '\r' | '\n' | '\u000C')+ {$channel = HIDDEN;} ;

fragment LETTER_MINUS_A :   ('b'..'z' | 'B'..'Z');

fragment LETTER :   ('a'..'z' | 'A'..'Z');


fragment DIGIT      :   '0'..'9' ;   



LETTERS_MINUS_A 
    :   LETTER_MINUS_A (LETTER_MINUS_A)*;       

TEXT    :   LETTER (LETTER)* ;

我想自由地使用txt而不必做(txt | txtwa),它的工作原理顺便说一句。 我在这里缺少什么?

1 个答案:

答案 0 :(得分:1)

你必须意识到词法分析器没有考虑解析器在特定时间需要的内容:它只是试图从上到下构建一个通过词法分析器规则的令牌。

由于您在LETTERS_MINUS_A之前定义了TEXT,因此始终会创建LETTERS_MINUS_A而不是TEXT,而'a'只会包含'A'LETTERS_MINUS_A 1}}的。

这就是ANTLR的工作原理。

可以做的只是抛弃txt : TEXT ; txtwa : TEXT { if($TEXT.text.contains("a") || $TEXT.text.contains("A")) { throw new Exception("Eeek, I saw an `[aA]`!"); } } ; 规则并执行以下操作:

{{1}}