Prolog DCG 中的可选或重复项
Optional or Repeated Items in Prolog DCG
所以我正在使用 Definite Clause Grammars 在 SWI-Prolog 中为 Pascal 编写一个简单的解析器。
我不明白如何实现重复(2 个或更多)或可选地重复(1 个或更多)谓词。
例如,在 EBNF 中,对于 Pascal 的 "program" 是:
"PROGRAM" identifier "(" identifierlist ")" ";" block "."
其中 "identifierlist" 是:
identifier { "," identifier }
和"identifier"是:
letter { letter | digit }
我知道prolog的DCG形式程序是:
program --> ["PROGRAM"], identifier, ["("], identifierlist, [")"], [";"], block, ["."].
如何实现 "identifierlist" 甚至 "identifier",其中包含可选的重复数量的 "identifier" 或 "letter" 或 "digit" 谓词?
在 Prolog 中,只要 EBNF 确实是您想要的,您就可以完全按照 EBNF 来编写它。
identifierlist = identifier { "," identifier }
你也可以这样写:
identifierlist = identifier
identifierlist = identifier , identifierlist
在 Prolog 中,您可以这样写:
identifier_list --> identifier.
identifier_list --> identifier, ",", identifier_list.
如果你想包含一个空的标识符列表,那就更复杂一点:
identifier_list --> [].
identifier_list --> nonempty_identifier_list.
nonempty_identifier_list--> identifier.
nonempty_identifier_list--> identifier, ",", nonempty_identifier_list.
您的原始 EBNF 不包含空标识符列表。如果是这样,上面的代码可能看起来很像 EBNF。
正如@false 在评论中指出的那样,nonempty_identifier_list
的另一种呈现方式是:
nonempty_identifier_list --> identifier, ( [] | ",", nonempty_identifier_list ).
所以我正在使用 Definite Clause Grammars 在 SWI-Prolog 中为 Pascal 编写一个简单的解析器。
我不明白如何实现重复(2 个或更多)或可选地重复(1 个或更多)谓词。
例如,在 EBNF 中,对于 Pascal 的 "program" 是:
"PROGRAM" identifier "(" identifierlist ")" ";" block "."
其中 "identifierlist" 是:
identifier { "," identifier }
和"identifier"是:
letter { letter | digit }
我知道prolog的DCG形式程序是:
program --> ["PROGRAM"], identifier, ["("], identifierlist, [")"], [";"], block, ["."].
如何实现 "identifierlist" 甚至 "identifier",其中包含可选的重复数量的 "identifier" 或 "letter" 或 "digit" 谓词?
在 Prolog 中,只要 EBNF 确实是您想要的,您就可以完全按照 EBNF 来编写它。
identifierlist = identifier { "," identifier }
你也可以这样写:
identifierlist = identifier
identifierlist = identifier , identifierlist
在 Prolog 中,您可以这样写:
identifier_list --> identifier.
identifier_list --> identifier, ",", identifier_list.
如果你想包含一个空的标识符列表,那就更复杂一点:
identifier_list --> [].
identifier_list --> nonempty_identifier_list.
nonempty_identifier_list--> identifier.
nonempty_identifier_list--> identifier, ",", nonempty_identifier_list.
您的原始 EBNF 不包含空标识符列表。如果是这样,上面的代码可能看起来很像 EBNF。
正如@false 在评论中指出的那样,
nonempty_identifier_list
的另一种呈现方式是:
nonempty_identifier_list --> identifier, ( [] | ",", nonempty_identifier_list ).