1

我真正的语法要复杂得多,但我可以解决我的问题。所以这是语法:

grammar test2;
options {language=CSharp3;}

@parser::namespace { Test.Parser }
@lexer::namespace { Test.Parser }

start   : 'VERSION' INT INT project;

project :   START 'project' NAME TEXT END 'project';

START: '/begin';
END: '/end';

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

    INT :   '0'..'9'+;

    NAME:   ('a'..'z' | 'A'..'Z')+;

    TEXT  :  '"'  ( '\\' (.) |'"''"' |~( '\\' | '"' | '\n' | '\r' ) )* '"';

    STARTA 
        :   '/begin hello';

我想解析这个(例如):

版本 1 1

/开始项目

测试项目“描述在这里”

/结尾

项目

现在它不会像这样工作(不匹配的令牌异常)。如果我删除最后一个令牌 STARTA,它就可以工作。但为什么?我不明白。

非常感谢您的帮助。谢谢。

4

1 回答 1

2

当词法分析器看到输入"/begin "(包括空格!)时,它会提交到规则STARTA。当它无法匹配所述规则时,因为输入中的下一个字符是"p"(from "project") 而不是"h"(from "hello"),它会尝试匹配另一个可以匹配"/begin "的规则(包括空格!)。但是没有这样的规则,会产生错误:

mismatched character 'p' expecting 'h'

并且词法分析器不会放弃空间并匹配START规则。

记住最后一部分:一旦词法分析器匹配了某些东西,它就不会放弃它。它可能会尝试匹配相同输入的其他规则,但它不会回溯匹配匹配较少字符的规则!

这就是词法分析器在 ANTLR 3.x 中的工作方式,无法绕过它。

于 2012-09-10T12:52:23.557 回答