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

用Python编写C++词法分析器时的代码拆分问题求助

C++词法分析器Token拆分问题解决方案

问题描述

当前实现的Python版C++词法分析器存在两个核心问题:

  • 用split(" ")按空格拆分代码时,x=2、function()这类无空格分隔的代码无法拆分成独立Token,必须手动添加空格(比如改成x = 2)才能识别
  • 无法识别每行开头的Token,只有手动在Token之间和行首加空格时代码才能正常运行

试过两种方案都没解决:先按行拆分再按空格拆分,操作复杂且没解决无空格Token的识别;想过按运算符拆分,但没法同时把运算符本身作为Token识别,方案不可行。

尝试过的代码

第一种直接按空格拆分:

f=open("code.txt")
input=f.read()
input=input.split(" ")

第二种先按行拆分再按空格拆分:

f=open("code.txt")
input=f.read()
input1=input.split("\n")
for var in input1:
 var=var.split(" ")

解决方案:用正则表达式匹配Token

词法分析不能靠简单的空格拆分,得按Token的语法规则去匹配。用正则表达式可以一次性识别所有符合C++语法的Token,完美解决无空格分隔和行首Token的问题。

步骤1:定义Token的正则规则

先把C++常见的Token类型对应的正则模式写出来,包括标识符、数字、运算符、标点和关键字:

import re

# 定义C++各类Token的正则模式,带注释方便维护
token_pattern = r"""
    (?P<IDENTIFIER>[a-zA-Z_][a-zA-Z0-9_]*)|  # 变量/函数名:开头是字母或下划线,后面跟字母/数字/下划线
    (?P<NUMBER>\d+(\.\d+)?)|                 # 数字:整数或带小数点的浮点数
    (?P<OPERATOR>=|\+|-|\*|/|==|!=|<|>|<=|>=)| # 常用运算符:单字符或双字符的
    (?P<PUNCTUATION>\(|\)|\{|\}|\;|\,)|       # 括号和标点:(){};,
    (?P<KEYWORD>int|void|return|if|else)      # 关键字:可根据需求扩展更多
"""
# 编译正则,忽略注释和空白符,关键字不区分大小写
regex = re.compile(token_pattern, re.VERBOSE | re.IGNORECASE)

步骤2:读取代码并提取所有Token

用re.findall()全局匹配所有符合规则的Token,不管有没有空格分隔:

# 用with语句自动管理文件,比直接open更安全
with open("code.txt", "r") as f:
    code = f.read()

# 提取所有匹配的Token
tokens = regex.findall(code)

# 整理结果:过滤空字符串,只保留有效Token
processed_tokens = []
for token_group in tokens:
    # 找到每组里非空的那个值(每个组对应一种Token类型)
    token = next(item for item in token_group if item)
    processed_tokens.append(token)

# 打印结果
print(processed_tokens)

比如输入代码x=2; function(),会输出['x', '=', '2', ';', 'function', '(', ')'],完全符合预期。

扩展:区分Token类型

如果需要知道每个Token的类型(比如是标识符还是运算符),可以修改处理逻辑,把类型和值一起保存:

processed_tokens_with_type = []
for token_group in tokens:
    # 找到第一个非空的匹配项,同时获取对应的类型名
    token_info = next((name, value) for name, value in zip(regex.groupindex.keys(), token_group) if value)
    processed_tokens_with_type.append(token_info)

print(processed_tokens_with_type)

输出会是[('IDENTIFIER', 'x'), ('OPERATOR', '='), ('NUMBER', '2'), ('PUNCTUATION', ';'), ('IDENTIFIER', 'function'), ('PUNCTUATION', '('), ('PUNCTUATION', ')')],方便后续做语法分析。

为什么这个方案可行?

正则表达式是按语法规则匹配,而不是按空格拆分,所以不管Token之间有没有空格,只要符合C++的语法规则,就能被正确识别。而且全局匹配会忽略行首、行尾的空白,自然解决了行首Token无法识别的问题。

内容的提问来源于stack exchange,提问作者B Khorram

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:20:28