【问题标题】:How to handle whitespace between tokens in an antlr3 grammar如何在 antlr3 语法中处理标记之间的空格
【发布时间】:2015-03-28 01:23:34
【问题描述】:

我有一个关于 antlr3 语法中的空格处理的问题。这是语法的精简版:

grammar SLiMScript;

inputFile   :
        NEWLINE*
        sectionOutput?
        ;

sectionOutput   :   '#OUTPUT' NEWLINE+ outputLine+ ;
outputLine  :   (output_all) NEWLINE+ ;
output_all  :   NUMBER 'A' STRING? ;

NEWLINE :   ('\r'? '\n') ;

NUMBER :        ('0' | (DIGIT_1 DIGIT_0*)) ('.' DIGIT_0*)? EXPONENT? ;
fragment EXPONENT : ('e'|'E') ('+'|'-')? DIGIT_0+ ;
fragment DIGIT_0    :   '0'..'9' ;
fragment DIGIT_1    :   '1'..'9' ;

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

WS  :       ( ' ' | '\t' ) { skip(); } ;

这是一个简单的输入文件:

#OUTPUT 
1000 A "foo bar baz"

一般来说,我希望去掉空格;因此,语法末尾的空格规则。但是,我确实希望令牌之间需要空格。例如,如果您查看输出文件,我不希望1000A"foo" 合法;我希望令牌之间需要空格。但是,必须明确指定语法中的任何地方都会非常痛苦。我不能吃蛋糕也不能吃;如果我保留我的空格剥离规则,那么我不能将我的语句规则更改为:

output_all  :   NUMBER WS 'A' (WS STRING)? ;

因为此时空白标记已经被剥离;没有留给规则匹配的空格。也许我别无选择,只能摆脱隐式的空格剥离,而是在整个语法中的每一对标记之间放置一个 WS 引用,以获得我想要的行为。但肯定有更好的方法...?

像 C 这样的语言是如何做到的?可以写static int foo,但不能写staticintfoo;为什么不?此类语言的语法如何在这样的标记之间强制使用空格?我猜这是因为staticintfoo 被标记为标识符,大概是因为该规则是第一位的;该字符串还将与标记staticint 和(标识符)foo 匹配,但在此之前,它们会被作为单个大标识符吞噬,这会导致错误,因为该标识符未定义.有没有办法在我的情况下做类似的事情?通过使无空格版本导致导致错误的替代解释来隐式要求令牌之间的空格?我真的没有看到一种优雅的方式来做到这一点。

我读过 Parr 的书 Language Implementation Patterns 和 The Definitive ANTLR Reference ,我认为我或多或少地理解了它们,但我觉得我对如何为各种特定的实际设计实用语法缺乏一个很好的回顾应用的情况。某种书,例如 LL(*) 语法设计的艺术。有这样的书吗?

【问题讨论】:

  • C 示例的工作方式是词法分析器倾向于吃掉与标记匹配的最大可能字符串。所以staticintfoo 是一个标识符,而不是三个标记,“static”、“int”、“foo”。然后错误消息将是 staticintfoo 是一个未声明的标识符,而不是存在语法错误。

标签: grammar antlr3


【解决方案1】:

没有更好的方法。您是否希望空格被剥离或不被剥离。你不能同时弄湿和保持干燥。

如果你真的想在(某些)标记之间强制使用空格,那么你必须在任何地方都使用 WS,这是没有办法的。不过,我质疑你的意图。通常,简单地忽略空格非常有效,除了一些非常奇怪的定义语言,如 Python 或 FORTRAN,其中缩进是语言的一部分。

作为一种解决方法,并且只有当您想要避免非常具体的情况(例如1000A)时,您才能定义一个专门匹配此输入的词法分析器规则,并让它返回一个在任何地方都无效的令牌,从而导致解析器中的语法错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 1970-01-01
    • 2016-01-08
    • 1970-01-01
    相关资源
    最近更新 更多