ANTLR4。评论不被词法分子吞噬

时间:2014-10-25 01:52:13

标签: comments antlr4 lexer

我有以下Antlr4语法:

grammar Smarty;

/*
 * Parser Rules
 */

parse: smartyBody
     ;

smartyBody: include
          | bodyText?
          ;

include: INCLUDE fileName CB
          ;

bodyText: BODY_TEXT
         ;

fileName: FILENAME
        ; 
/*
 * Lexer Rules
 */
COMMENT: '{*' .*? '*}'      -> skip;

INCLUDE: '{include' SPACE+ 'file='?;

BODY_TEXT: ANY_CHAR+;

CB: SPACE? '}';

FILENAME: '\'' FILE_NAME '\''
     |    '"' FILE_NAME '"';

SPACE: [ \t];
NEW_LINE:   [\r\n]+         -> skip;

fragment FILE_NAME: PATH_CHARACTERS+;
fragment PATH_CHARACTERS: ~[\u0000-\u001f"*:<>?\\/|\u007f-\uffff];
fragment ANY_CHAR: [ -~];

现在,如果我尝试使用评论,他们会被传回而不会被吞下。

传递给解析器的文本:{* {include file ='xxxxx'} *} zzzzzzzz

如果我覆盖EnterBodyText并将文本字符串传递给解析器,则侦听器中的Text变量将获取包含注释的原始文本。

internal partial class BaseListener : SmartyBaseListener
{
    public override void EnterBodyText( SmartyParser.BodyTextContext context )
    {
       var Text = context.BODY_TEXT().GetText();
       // Text gets: {* {include file='xxxxx'} *} zzzzzzzz
       // not just zzzzzzzz
    }
}

任何帮助表示感谢。

1 个答案:

答案 0 :(得分:2)

ANTLR的词法分析者会尝试尽可能地匹配。因此,输入{* {include file='xxxxx'} *} zzzzzzzz完全由BODY_TEXT匹配。

解决此问题的一种方法是使BODY_TEXT成为解析器规则:

body_text: ANY_CHAR+;

...

COMMENT: '{*' .*? '*}' -> skip;

...

// No fragment anymore. And keep this as the last lexer rule!
ANY_CHAR: [ -~];