为什么围绕作品的可选部分进行布局会导致歧义?
Why is layout around optional parts of a production causing ambiguity?
在Rascal中,为什么在一个产生式的可选部分位置有布局时,会出现歧义?例如。 "{ }"
与 Start1
不明确,而它从以下语法中解析为 Start2
,我希望它完全相同。
layout Layout = " "?;
start syntax Start1 = "{" "c"? "}";
start syntax Start2 = "{" "c" "}"
| "{" "}";
此外,我想知道是否有另一种表示 Start2
而不重复 Start1
的方法,它不会引起同样的歧义。
显然这段代码没有大量重复,Start2
是一个不错的选择,但这只是一个例子。我正在处理一个语法,其中包含许多包含三个或四个可选部分的作品,在最后一种情况下,Start2
中显示的符号已经需要将作品的非可选部分复制 2^4=16 次,这确实在我看来很麻烦
在生成解析器之前,您的语法首先被扩展为与此类似的内容:
layout Layout = " "?;
syntax " "? = | " ";
syntax Start1 = "{" Layout "c"? Layout "}";
syntax "c"? = | "c";
lexical " " = [\ ];
lexical "c" = [c];
lexical "{" = [{];
lexical "}" = [}];
syntax Start2 = "{" Layout "c" Layout "}"
| "{" Layout "}";
syntax start[Start1] = Layout Start1 Layout;
syntax start[Start2] = Layout Start2 Layout;
所以对于像{ }
这样的输入(space在卷曲之间),space可以由Start1右侧的第一个Layout实例导出规则,或由 Layout 的第二个实例。由于解析器生成所有派生树,在这种情况下,解析是模棱两可可以这么说。
通常情况下,通过引入 贪婪 来解决歧义,使用如下限制:
layout Layout = " "? !>> " "
或(等价地)像这样:
layout Layout = " "? !>> [\ ]
限制作为对布局规则的约束:如果后面有 space,它不会派生任何东西(甚至不是空字符串)。这使得只有第一个推导有效,其中 space 进入 Start1 的第一个 Layout 实例。在这之后有 }
满足约束并且解析是明确的。
在Rascal中,为什么在一个产生式的可选部分位置有布局时,会出现歧义?例如。 "{ }"
与 Start1
不明确,而它从以下语法中解析为 Start2
,我希望它完全相同。
layout Layout = " "?;
start syntax Start1 = "{" "c"? "}";
start syntax Start2 = "{" "c" "}"
| "{" "}";
此外,我想知道是否有另一种表示 Start2
而不重复 Start1
的方法,它不会引起同样的歧义。
显然这段代码没有大量重复,Start2
是一个不错的选择,但这只是一个例子。我正在处理一个语法,其中包含许多包含三个或四个可选部分的作品,在最后一种情况下,Start2
中显示的符号已经需要将作品的非可选部分复制 2^4=16 次,这确实在我看来很麻烦
在生成解析器之前,您的语法首先被扩展为与此类似的内容:
layout Layout = " "?;
syntax " "? = | " ";
syntax Start1 = "{" Layout "c"? Layout "}";
syntax "c"? = | "c";
lexical " " = [\ ];
lexical "c" = [c];
lexical "{" = [{];
lexical "}" = [}];
syntax Start2 = "{" Layout "c" Layout "}"
| "{" Layout "}";
syntax start[Start1] = Layout Start1 Layout;
syntax start[Start2] = Layout Start2 Layout;
所以对于像{ }
这样的输入(space在卷曲之间),space可以由Start1右侧的第一个Layout实例导出规则,或由 Layout 的第二个实例。由于解析器生成所有派生树,在这种情况下,解析是模棱两可可以这么说。
通常情况下,通过引入 贪婪 来解决歧义,使用如下限制:
layout Layout = " "? !>> " "
或(等价地)像这样:
layout Layout = " "? !>> [\ ]
限制作为对布局规则的约束:如果后面有 space,它不会派生任何东西(甚至不是空字符串)。这使得只有第一个推导有效,其中 space 进入 Start1 的第一个 Layout 实例。在这之后有 }
满足约束并且解析是明确的。