Files
TransPyC/lib/vast/__init__.py
T
TermiNexus 6fc9e19e24 feat(vast): 新增自研 Viper/Python 语法解析器取代标准库 ast
TPC 侧取缔对 Python 标准库 ast 模块的依赖,改用 lib/vast 包:
- Nodes: 与 CPython 3.12 ast 完全同构的 131 个节点类(含抽象基类继承)
- Tokenizer: 词法分析(缩进/字符串/f-string/数字/运算符/软关键字)
- ExprParser: 表达式递归下降解析(优先级/lambda/推导式/f-string/切片)
- Parser: 语句解析(def/class/if/for/try/with/match/import/注解)
- Utils/Unparser: walk/dump/unparse/copy_location/literal_eval 等辅助
- 软关键字 fn/fun/func/function 并入解析器, 废除 ExpandSoftKeywords 预处理
- lib/_bootstrap 将 lib 目录加入 sys.path, import vast as ast 零修改替换
- 52 个文件 import ast 替换为 import vast as ast; 94 文件差分测试 0 失败
2026-08-17 09:36:38 +08:00

70 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""vast - Viper/Python 自研语法解析器(ast 替代品)
vast 提供与 CPython 3.12 标准库 ``ast`` 完全一致的 API:
- 节点类:``AST`` 及全部 131 个节点类(Name/Call/BinOp/FunctionDef/...)
- 解析入口:``parse(source, filename, mode, ...)`` 产出 ``Module``
- 辅助函数:``dump`` / ``walk`` / ``iter_child_nodes`` / ``iter_fields`` /
``unparse`` / ``copy_location`` / ``fix_missing_locations`` /
``get_source_segment`` / ``literal_eval``
- 类型标注占位:``expr`` / ``stmt`` / ``operator`` / ``cmpop`` 等
编译器侧替换方式(零修改其余代码)::
import vast as ast
vast 原生支持 Viper 软关键字 fn/fun/func/function(并入解析器),无需
ExpandSoftKeywords 预处理。
"""
from __future__ import annotations
import sys as _sys
from lib.vast.Nodes import AST
from lib.vast.Nodes import _NODE_DEFS
# 将全部节点类提升到包命名空间
for _name in _NODE_DEFS:
globals()[_name] = getattr(_sys.modules['lib.vast.Nodes'], _name)
from lib.vast.Parser import Parse # noqa: E402
from lib.vast.Utils import ( # noqa: E402
iter_fields, iter_child_nodes, walk, dump, copy_location,
fix_missing_locations, get_source_segment, literal_eval,
)
from lib.vast.Unparser import Unparse as unparse # noqa: E402
from lib.vast.Tokenizer import SOFT_KEYWORDS # noqa: E402
def parse(source: str, filename: str = '<unknown>', mode: str = 'exec', *,
type_comments: bool = False, feature_version: tuple[int, int] | int | None = None) -> AST:
"""解析源码字符串为 AST(与 ast.parse 同签名、同结构)。
Args:
source: 源码文本
filename: 文件名(仅用于错误报告,vast 保留)
mode: 'exec'(模块)/ 'eval'(单表达式)/ 'single'(交互式)
type_comments: 是否解析 # type: 注释(vast 暂返回 None 字段)
feature_version: 目标 Python 版本(vast 忽略,保持兼容)
"""
tree: AST = Parse(source)
if mode == 'exec':
return tree
if mode == 'eval':
if len(tree.body) != 1 or not isinstance(tree.body[0], _sys.modules['lib.vast.Nodes'].Expr):
raise SyntaxError('invalid syntax for eval mode')
expr_node: AST = _sys.modules['lib.vast.Nodes'].Expression(
body=tree.body[0].value)
return expr_node
if mode == 'single':
interactive: AST = _sys.modules['lib.vast.Nodes'].Interactive(body=tree.body)
return interactive
raise ValueError(f"invalid mode {mode!r}")
__all__: list[str] = [
'AST', 'parse', 'dump', 'walk', 'iter_fields', 'iter_child_nodes',
'unparse', 'copy_location', 'fix_missing_locations',
'get_source_segment', 'literal_eval', 'SOFT_KEYWORDS',
] + list(_NODE_DEFS.keys())