鱼C论坛

 找回密码
 立即注册
查看: 2235|回复: 3

实现一个忽略语法错误的代码解析器

[复制链接]
发表于 2023-5-9 19:45:23 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我正在实现一个ide,想要搭载一个较为智能的代码补全,目前是使用python ast库分析代码生成语法树,再遍历语法树来实现智能补全
但有一个问题,就是在输入的过程中,代码会出现暂时性的“语法错误”,比如:
prin
当我想要输入一个print函数时,我需要智能补全能够给我print函数的选项,但是由于代码中没有“prin”这个变量,ast分析会爆出syntax error,导致分析无法进行
我想要知道,有没有什么方法能够实现我的需求,或者干脆抛弃ast,实现一个能忽略语法错误的代码解析器?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-5-9 19:46:00 | 显示全部楼层
可以使用Python的 code 模块来实现一个忽略语法错误的代码解析器。 code 模块提供了一个 compile_command 函数,可以将输入的代码编译成Python代码对象。如果输入的代码有语法错误, compile_command 函数会返回 None ,否则会返回编译后的代码对象。

下面是一个简单的示例代码,演示了如何使用 code 模块实现一个忽略语法错误的代码解析器:
import code

def parse_code(input_code):
    try:
        compiled_code = code.compile_command(input_code)
        if compiled_code is not None:
            # 如果编译成功,执行编译后的代码
            exec(compiled_code)
    except Exception as e:
        # 处理异常
        print(e)

在上面的代码中, parse_code 函数接受一个字符串类型的输入代码,使用 code.compile_command 函数将其编译成Python代码对象。如果编译成功,则使用 exec 函数执行编译后的代码。如果编译失败,则捕获异常并进行处理。

使用这个代码解析器,即使输入的代码有语法错误,也不会影响智能补全的实现。你可以在输入代码时,每输入一个字符就调用一次 parse_code 函数,获取智能补全的选项。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-9 19:47:03 | 显示全部楼层
可以考虑使用实时解析器(live parser)来解决这个问题。实时解析器的作用是在代码输入的过程中,及时给出语法提示、错误信息等反馈。常见的实时解析器有 Language Server Protocol(LSP)和Jupyter Notebook。

LSP 是一个跨语言的协议,主要用于提供编辑器客户端(如 VSCode、Sublime Text 等)和语言服务器(Language Server)之间的通信协议。语言服务器负责对特定编程语言进行语义分析,提供智能补全、错误提示等功能。

Jupyter Notebook 是一个基于 Web 的交互式计算环境,支持多种编程语言(如 Python、R、Julia 等)。其采用了实时解析器的方式来处理代码输入,在用户输入代码时,会实时分析代码并提供补全、错误提示等功能,同时也能够运行代码并显示结果。

如果你只想处理单一语言,那么可以使用 LSP;如果你需要支持多种语言或者需要更灵活的交互环境,可以考虑使用 Jupyter Notebook。
有用请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-9 20:05:17 | 显示全部楼层
isdkz 发表于 2023-5-9 19:46
可以使用Python的 code 模块来实现一个忽略语法错误的代码解析器。 code 模块提供了一个 compile_command  ...

首先道个歉,我发现我的描述似乎不准确
我的示例是不会有错误报出的,我的示例属于NameError,不属于静态编译的报错范围
我想要实现的,是如下的效果:

                               
登录/注册后可看大图

如图,第一行括号未闭合,是明显的语法错误,但第二行的智能补全能正常运行

code模块并无用:
import code


def parse_code(input_code):
    try:
        compiled_code = code.compile_command(input_code)
        if compiled_code is not None:
            exec(compiled_code)
    except Exception as e:
        # 处理异常
        print(e)


with open('a.py', 'r') as f:
    data = f.read()

parse_code(data)
输出:invalid syntax (<input>, line 2)
a.py内容:
print('hello'
pr
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-23 07:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表