You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于SWI-Prolog DCG的编程语言解析器:标识符规则实现咨询

用SWI-Prolog DCG实现多语言简易解析器:标识符处理方案

最近我一直在用SWI-Prolog的确定子句文法(DCG)编写几款编程语言的简易解析器,核心目标很明确——判断输入的字符串或是文件内容是否符合目标语言的语法规范:符合就返回true,不符合就返回false。有意思的是,这些语言几乎都少不了identifier谓词,而且绝大多数语言里标识符的EBNF定义就两种形式,我整理了对应的DCG实现方案,分享给大家:

两种常见的标识符EBNF定义及对应DCG实现

1. 形式一:letter { letter | digit }

这种定义要求标识符必须以字母开头,后续可以跟任意数量(包括0个)的字母或数字。对应的SWI-Prolog DCG实现如下:

% 匹配大小写英文字母
letter --> [C], { code_type(C, alpha) }.

% 匹配0-9数字
digit --> [C], { code_type(C, digit) }.

% 标识符规则:字母开头,后跟任意字母/数字组合
identifier --> letter, identifier_rest.
identifier_rest --> (letter ; digit), identifier_rest.
identifier_rest --> []. % 空分支对应{...}的0次匹配情况

可以用这些测试用例验证:

% 合法标识符测试:以字母开头,后跟字母数字
?- phrase(identifier, "userName123").
true.

% 非法标识符测试:以数字开头
?- phrase(identifier, "123userName").
false.

2. 形式二:( letter | digit ) { letter | digit }

这种定义放宽了开头限制,允许标识符以字母或数字开头,后续同样可以跟任意数量的字母或数字。只需要微调identifier的起始规则即可:

% 标识符规则:字母/数字开头,后跟任意字母/数字组合
identifier --> (letter ; digit), identifier_rest.
identifier_rest --> (letter ; digit), identifier_rest.
identifier_rest --> [].

测试示例:

% 合法标识符测试:以数字开头
?- phrase(identifier, "123userName").
true.

% 非法标识符测试:包含特殊字符
?- phrase(identifier, "user-Name").
false.

扩展小技巧

如果需要支持下划线这类常见的标识符允许字符,只需要扩展字符匹配规则即可,比如新增一个id_char谓词:

% 匹配标识符允许的所有字符:字母、数字、下划线
id_char --> letter ; digit ; "_".

% 对应形式一的标识符(字母开头)
identifier --> letter, identifier_rest.
identifier_rest --> id_char, identifier_rest.
identifier_rest --> [].

这样就能处理像user_name_456这类带下划线的合法标识符了。

内容的提问来源于stack exchange,提问作者Marcus Hallett

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:02:59