天!
如何构建一个简单的 ANTLR 语法来处理多行表达式而不需要分号或反斜杠?
我正在尝试为表达式编写一个简单的 DSL:
# sh style comments
ThisValue = 1
ThatValue = ThisValue * 2
ThisOtherValue = (1 + 2 + ThisValue * ThatValue)
YetAnotherValue = MAX(ThisOtherValue, ThatValue)
总的来说,我希望我的应用程序为脚本提供一些初始命名值并提取最终结果。但是,我对语法很感兴趣。我想支持多行表达式,如下所示:
# Note: no backslashes required to continue expression, as we're in brackets
# Note: no semicolon required at end of expression, either
ThisValueWithAReallyLongName = (ThisOtherValueWithASimilarlyLongName
+AnotherValueWithAGratuitouslyLongName)
我从这样的 ANTLR 语法开始:
exprlist
: ( assignment_statement | empty_line )* EOF!
;
assignment_statement
: assignment NL!?
;
empty_line
: NL;
assignment
: ID '=' expr
;
// ... and so on
看起来很简单,但我已经遇到了换行的麻烦:
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
以图形方式,在 org.antlr.works.IDE 中:
决策可以使用多种选择匹配 NL http://img.skitch.com/20090723-ghpss46833si9f9ebk48x28b82.png
我已经踢了语法,但总是以违反预期行为而告终:
- 文件末尾不需要换行符
- 空行是可以接受的
- 从井号开始的一行中的所有内容都被丢弃为注释
- 作业以换行符结尾,而不是分号
- 如果用括号括起来,表达式可以跨越多行
我可以找到具有许多这些特征的示例 ANTLR 语法。我发现当我削减它们以将它们的表现力限制在我需要的范围内时,我最终会破坏某些东西。其他的太简单了,我在添加表现力的同时打破它们。
我应该从哪个角度来理解这个语法?你能指出任何不是琐碎或完整的图灵完备语言的例子吗?