如何控制语法不同部分的布局?
How to control layout in different parts of syntax?
我正在查看教程中的 Exp 示例。
是否可以有条件地控制布局?例如,考虑 Python 表达式:
- 括号表达式中的换行符无关紧要
- 否则,换行符是statement/expression终止符
例如:
(1 + \n 3)
是一个有效的表达式,但是
1 +\n 3
不是。
如果没有,除了在我的语法中添加换行符之外,获得相同结果的最简单方法是什么?
是的,这是可能的:
- 如果你在两个普通符号
A
和 B
之间的 syntax
规则中使用 layout
非终结符 L
,如下所示:syntax NY = "foo" A L B "bar",那么Rascal不会在A
和L
之间或L
和B
[之间添加更多布局非终结符=31=]
- 您可以将布局非终结符添加到您的语法中,这些非终结符不会始终自动插入(用于第一点),如下所示:
layout NoNewLineLayout = @manual [\t\ ]*;
所以这需要在语法中加入 NoNewLineLayout 符号的实例,而不是加入换行符。我通常使用像 NNL 这样的短名称来减少干扰。我们使用此解决方法来试验 Javascript 语法和其他对布局敏感的语言。总的来说,虽然它并不完美并且我们一直在研究更优雅的解决方案,但请参阅 http://dl.acm.org/citation.cfm?id=2814242 进行预览。
第二种不太灵活的解决方案是使用 layout
定义的范围(这是模块范围的)。当前模块中的布局定义优先于任何导入的布局定义。以这种方式,可以影响在哪些规则中编织非终端的布局。这在将语言嵌入到可能具有不同注释约定等的其他语言中时非常有用;对于当前的用例,我不建议这样做。
我正在查看教程中的 Exp 示例。
是否可以有条件地控制布局?例如,考虑 Python 表达式:
- 括号表达式中的换行符无关紧要
- 否则,换行符是statement/expression终止符
例如: (1 + \n 3)
是一个有效的表达式,但是 1 +\n 3
不是。
如果没有,除了在我的语法中添加换行符之外,获得相同结果的最简单方法是什么?
是的,这是可能的:
- 如果你在两个普通符号
A
和B
之间的syntax
规则中使用layout
非终结符L
,如下所示:syntax NY = "foo" A L B "bar",那么Rascal不会在A
和L
之间或L
和B
[之间添加更多布局非终结符=31=] - 您可以将布局非终结符添加到您的语法中,这些非终结符不会始终自动插入(用于第一点),如下所示:
layout NoNewLineLayout = @manual [\t\ ]*;
所以这需要在语法中加入 NoNewLineLayout 符号的实例,而不是加入换行符。我通常使用像 NNL 这样的短名称来减少干扰。我们使用此解决方法来试验 Javascript 语法和其他对布局敏感的语言。总的来说,虽然它并不完美并且我们一直在研究更优雅的解决方案,但请参阅 http://dl.acm.org/citation.cfm?id=2814242 进行预览。
第二种不太灵活的解决方案是使用 layout
定义的范围(这是模块范围的)。当前模块中的布局定义优先于任何导入的布局定义。以这种方式,可以影响在哪些规则中编织非终端的布局。这在将语言嵌入到可能具有不同注释约定等的其他语言中时非常有用;对于当前的用例,我不建议这样做。