如何消除这段 Delphi 语法中的歧义
How to remove ambiguity from this piece of Delphi grammar
我正在研究 Rascal 中的 Delphi 语法,我在解析其“记录”类型时遇到了一些问题。 Delphi 代码的相关部分如下所示:
record
private
a,b,c : Integer;
x : Cardinal;
end
其中"private"可以是可选的,变量声明行也可以是可选的
我尝试使用以下规则解释此部分:
syntax FieldDecl = IdentList ":" Type
| IdentList ":" Type ";"
;
syntax FieldSection = FieldDecl
| "var" FieldDecl
| "class" "var" FieldDecl
;
syntax Visibility = "private" | "protected" | "public"| "published" ;
syntax VisibilitySectionContent = FieldSection
| MethodOrProperty
| ConstSection
| TypeSection
;
syntax VisibilitySection = Visibility? VisibilitySectionContent+
;
syntax RecordType = "record" "end"
| "record" VisibilitySection+ "end"
;
问题是歧义。 “record”和“end”之间的整个文本可以在单个 VisibilitySection 中解析,但每一行本身也可以是一个单独的 VisibilitySection。
我可以将规则 VisibilitySection 更改为
syntax VisibilitySection = Visibility
| VisibilitySectionContent
;
然后语法不再有歧义,但 VisibilitySection 变得平坦,在可选的 'private' 节点下不再有可变行的嵌套,我更喜欢这样。
关于如何解决这个问题有什么建议吗?我想要做的是要求对 VisibilitySection 的 VisibilitySectionContent+ 符号进行最长/贪婪匹配。
但是改变
syntax VisibilitySection = Visibility? VisibilitySectionContent+
到
syntax VisibilitySection = Visibility? VisibilitySectionContent+ !>> VisibilitySectionContent
似乎不适用于此。
我也 运行 Rascal 上的歧义报告工具,但它没有为我提供任何见解。
有什么想法吗?
谢谢
VisibilitySection
中的VisibilitySectionContent+
应该是VisibilitySectionContent
(没有Kleene plus)。
我在这里猜测,但您的意图可能是在记录类型中允许多个 sections/declarations,并且其中任何一个可能有也可能没有 Visibility
修饰符。为了避免在每个部分中放置这个可选的 Visibility
,您创建了一个 VisibilitySectionContent
非终结符,它基本上模拟“记录类型定义中可能发生的事情”,每个非终结符一个,而不用担心可见性修饰符。在这种情况下,每个 VisibilitySection
使用一个 VisibilitySectionContent
就可以了,因为无论如何,当您从 RecordType
引用 VisibilitySection
时存在明确的重复。
我无法检查,因为你没有提供完整的语法,但我相信这应该可以让你的 "longest match" 行为:
syntax VisibilitySection
= Visibility? VisibilitySectionContent+ ()
>> "public"
>> "private"
>> "published"
>> "protected"
>> "end"
;
在我看来,这应该消除嵌套 VisibilitySections 被缩短的解释。现在我们只接受这些部分,如果它们紧跟在记录的末尾或下一部分。我很想知道它是否真的有效,因为总是很难预测语法的行为:-)
规则末尾的 ()
(空非终结符)确保我们可以在应用限制之前跳到下一部分的开头。仅当您在语法中某处已有最长的布局匹配规则时才有效。
我正在研究 Rascal 中的 Delphi 语法,我在解析其“记录”类型时遇到了一些问题。 Delphi 代码的相关部分如下所示:
record
private
a,b,c : Integer;
x : Cardinal;
end
其中"private"可以是可选的,变量声明行也可以是可选的
我尝试使用以下规则解释此部分:
syntax FieldDecl = IdentList ":" Type
| IdentList ":" Type ";"
;
syntax FieldSection = FieldDecl
| "var" FieldDecl
| "class" "var" FieldDecl
;
syntax Visibility = "private" | "protected" | "public"| "published" ;
syntax VisibilitySectionContent = FieldSection
| MethodOrProperty
| ConstSection
| TypeSection
;
syntax VisibilitySection = Visibility? VisibilitySectionContent+
;
syntax RecordType = "record" "end"
| "record" VisibilitySection+ "end"
;
问题是歧义。 “record”和“end”之间的整个文本可以在单个 VisibilitySection 中解析,但每一行本身也可以是一个单独的 VisibilitySection。
我可以将规则 VisibilitySection 更改为
syntax VisibilitySection = Visibility
| VisibilitySectionContent
;
然后语法不再有歧义,但 VisibilitySection 变得平坦,在可选的 'private' 节点下不再有可变行的嵌套,我更喜欢这样。
关于如何解决这个问题有什么建议吗?我想要做的是要求对 VisibilitySection 的 VisibilitySectionContent+ 符号进行最长/贪婪匹配。
但是改变
syntax VisibilitySection = Visibility? VisibilitySectionContent+
到
syntax VisibilitySection = Visibility? VisibilitySectionContent+ !>> VisibilitySectionContent
似乎不适用于此。
我也 运行 Rascal 上的歧义报告工具,但它没有为我提供任何见解。
有什么想法吗?
谢谢
VisibilitySection
中的VisibilitySectionContent+
应该是VisibilitySectionContent
(没有Kleene plus)。
我在这里猜测,但您的意图可能是在记录类型中允许多个 sections/declarations,并且其中任何一个可能有也可能没有 Visibility
修饰符。为了避免在每个部分中放置这个可选的 Visibility
,您创建了一个 VisibilitySectionContent
非终结符,它基本上模拟“记录类型定义中可能发生的事情”,每个非终结符一个,而不用担心可见性修饰符。在这种情况下,每个 VisibilitySection
使用一个 VisibilitySectionContent
就可以了,因为无论如何,当您从 RecordType
引用 VisibilitySection
时存在明确的重复。
我无法检查,因为你没有提供完整的语法,但我相信这应该可以让你的 "longest match" 行为:
syntax VisibilitySection
= Visibility? VisibilitySectionContent+ ()
>> "public"
>> "private"
>> "published"
>> "protected"
>> "end"
;
在我看来,这应该消除嵌套 VisibilitySections 被缩短的解释。现在我们只接受这些部分,如果它们紧跟在记录的末尾或下一部分。我很想知道它是否真的有效,因为总是很难预测语法的行为:-)
规则末尾的 ()
(空非终结符)确保我们可以在应用限制之前跳到下一部分的开头。仅当您在语法中某处已有最长的布局匹配规则时才有效。