如何在ANTLR中构造一个干净的Python语法?

Gar*_*idd 8 grammar antlr

天儿真好!

如何构建一个简单的ANTLR语法处理多行表达式而不需要分号或反斜杠?

我正在尝试为表达式编写一个简单的DSL:

# sh style comments
ThisValue = 1
ThatValue = ThisValue * 2
ThisOtherValue = (1 + 2 + ThisValue * ThatValue)
YetAnotherValue = MAX(ThisOtherValue, ThatValue)
Run Code Online (Sandbox Code Playgroud)

总的来说,我希望我的应用程序为脚本提供一些初始命名值并提取最终结果.不过,我对语法感到很沮丧.我想支持多行表达式,如下所示:

# Note: no backslashes required to continue expression, as we're in brackets
# Note: no semicolon required at end of expression, either
ThisValueWithAReallyLongName = (ThisOtherValueWithASimilarlyLongName
                               +AnotherValueWithAGratuitouslyLongName)
Run Code Online (Sandbox Code Playgroud)

我开始使用这样的ANTLR语法:

exprlist
    : ( assignment_statement | empty_line )* EOF!
    ;
assignment_statement
    : assignment NL!?
    ;
empty_line
    : NL;
assignment
    : ID '=' expr
    ;

// ... and so on
Run Code Online (Sandbox Code Playgroud)

看起来很简单,但我已经遇到了新行的麻烦:

warning(200): StackOverflowQuestion.g:11:20: Decision can match input such as "NL" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
Run Code Online (Sandbox Code Playgroud)

在图形上,在org.antlr.works.IDE中:

决策可以使用多种替代方案匹配NL http://img.skitch.com/20090723-ghpss46833si9f9ebk48x28b82.png

我已经开始使用语法,但总是会违反预期的行为:

  • 文件末尾不需要换行符
  • 空行是可以接受的
  • 从英镑符号开始的一行中的所有内容都将作为注释丢弃
  • 作业以行尾结束,而不是以分号结尾
  • 如果用括号括起来,表达式可以跨越多行

我可以找到具有许多这些特征的示例ANTLR语法.我发现当我把它们剪下来以限制它们对我所需要的表现力时,我最终会破坏某些东西.其他人太简单了,当我增加表现力时,我会打破它们.

我应该用这个语法采用哪个角度?你能指出任何不是琐碎的或完整的图灵完整语言的例子吗?

Joh*_*ica 6

我会让你的标记器完成繁重的工作,而不是将你的换行规则混合到你的语法中:

  • 计算括号,括号和大括号,并且在存在未闭合组时不生成NL令牌.这将免费为您提供线路延续,而您的语法则不会更明智.

  • 始终在文件末尾生成一个NL令牌,无论最后一行是否以'\n'字符结尾,那么您不必担心没有NL的语句的特殊情况.语句总是以NL结尾.

第二点可以让你简化你的语法:

exprlist
    : ( assignment_statement | empty_line )* EOF!
    ;
assignment_statement
    : assignment NL
    ;
empty_line
    : NL
    ;
assignment
    : ID '=' expr
    ;
Run Code Online (Sandbox Code Playgroud)