所以我使用Definite Clause Grammars在SWI-Prolog中为一些编程语言编写简单的解析器。如果输入字符串或文件对相关语言有效,则返回true;如果输入字符串或文件无效,则返回false。
在几乎所有语言中都有一个"标识符"谓语。在大多数语言中,标识符在EBNF中被定义为以下之一:letter { letter | digit }
或( letter | digit ) { letter | digit }
,也就是说在第一种情况下是一个字母后跟零个或多个字母数字字符,或者我
我的输入文件被拆分为单词字符串列表(即someIdentifier1 = 3
成为列表[someIdentifier1,=,3]
)。将字符串拆分为单词列表而不是字母列表的原因是用于识别定义为终端的关键字。
如何实施"标识符"以便识别任何字母数字字符串或由字母后跟字母数字字符组成的字符串。
是否有可能或有必要将该单词进一步拆分为此特定谓词的字母,如果是,我将如何进行此操作?或者是否有其他解决方案,可能使用SWI-Prolog库'内置谓词?
我为这个问题的措辞不佳而道歉;但是,我无法进一步澄清它。
答案 0 :(得分:2)
首先,当您需要推理个别字母时,通常最方便推理字符列表。
在Prolog中,您可以使用atom_chars/2
轻松地将原子转换为字符。
例如:
?- atom_chars(identifier10, Cs). Cs = [i, d, e, n, t, i, f, i, e, r, '1', '0'].
一旦有了这样的字符,就可以使用char_type/2
等谓词来推断每个字符的属性。
例如:
?- char_type(i, T). T = alnum ; T = alpha ; T = csym ; etc.
用DCG表示诸如你的标识符的一般模式可以如下所示:
identifier --> [L], { letter(L) }, identifier_rest. identifier_rest --> []. identifier_rest --> [I], { letter_or_digit(I) }, identifier_rest.
您可以将其用作构建基块,只需定义letter/1
和letter_or_digit/1
即可。使用char_type/2
非常容易。
此外,您当然可以引入一个参数来将这些列表与原子联系起来。