天儿真好!
如何构建一个简单的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语法.我发现当我把它们剪下来以限制它们对我所需要的表现力时,我最终会破坏某些东西.其他人太简单了,当我增加表现力时,我会打破它们.
我应该用这个语法采用哪个角度?你能指出任何不是琐碎的或完整的图灵完整语言的例子吗?
我会让你的标记器完成繁重的工作,而不是将你的换行规则混合到你的语法中:
计算括号,括号和大括号,并且在存在未闭合组时不生成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)