【问题标题】:Simple Island Grammar in ANTLR 4: Token Recognition ErrorANTLR 4 中的简单岛语法:令牌识别错误
【发布时间】:2014-05-27 16:22:24
【问题描述】:

显然,我无法从退出有关 Island Grammars 的令牌识别错误的帖子中推断出我的问题的答案,所以我希望有人能给我一个关于如何正确执行此操作的建议。

基本上,我正在尝试编写一种包含预处理器指令的语言。我将问题缩小到一个非常简单的例子。在我的示例语言中,以下应该是有效的语法:

@@some preprocessor text
PRINT some regular text

解析代码时,我希望能够识别标记“some preprocessor text”、“PRINT”和“some regular text em>”。

这是解析器语法:

parser grammar myp;

root: (preprocessor | command)*;
preprocessor: PREPROC PREPROCLINE;
command: PRINT STRINGLINE;

这是词法分析器语法:

lexer grammar myl;

PREPROC: '@@' -> pushMode(PREPROC_MODE);
PRINT: 'PRINT' -> pushMode(STRING_MODE);

WS: [ \t\r\n] -> skip;

mode PREPROC_MODE;

PREPROCLINE:    (~[\r\n])*[\r\n]+ -> popMode;

mode STRING_MODE;

STRINGLINE: (~[\r\n])*[\r\n]+ -> popMode;

当我解析上面的示例代码时,我收到以下错误:

第 1:2 行无关输入“一些预处理器文本\r\n”期待 PREPROCLINE 第 2:5 行标记识别错误:“一些常规文本”

无论“WS: [ \t\r\n] -> skip;”行是否包含在词法分析器语法中,都会发生此错误。我想如果我在标记 PREPROCLINE 和 STRINGLINE 中引入引号而不是行尾,它会起作用(至少我成功地用其他语言实现了常规字符串)。但是在这种特殊的语言中,我真的希望字符串不带引号。

非常感谢您提供有关此错误发生原因或如何使用不带引号的字符串实现预处理器语言的任何帮助。

谢谢

【问题讨论】:

    标签: grammar antlr4 lexer


    【解决方案1】:

    更新:首先,识别错误是因为您的解析器需要引用词法分析器标记。将选项块添加到您的解析器:

    options {
        tokenVocab=MyLexer;
    }
    

    其次,当您生成词法分析器/解析器时,请注意在继续之前通常需要考虑和纠正警告。

    最后,一旦您添加了选项块,这些都是可行的替代方案。

    XXXX: (~[\r\n])*[\r\n]+ -> popMode;
    

    更干净一点:

    XXXX: .*? '\r'? '\n' -> popMode;
    

    要不包括行尾,请尝试

    XXXX: .*? ~[\r\n] -> popMode;
    

    【讨论】:

    • 谢谢你,格罗森伯格。我按照您的建议替换了令牌规则。在第一种情况下 (.*? '\r'? '\n' -> popMode;) 会发生错误。在第二种情况下(.*? ~[\r\n] -> popMode;)我得到line 1:2 extraneous input 's' expecting PREPROCLINE line 2:5 extraneous input ' ' expecting {<EOF>, PREPROC, PRINT}
    猜你喜欢
    • 2022-01-22
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多