"""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 os as _os 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 _ParsePure(source: str, mode: str) -> AST: """纯 Python vast 解析(vast_c 不可用或回退时使用)。""" 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}") # C 加速解析器(vast_c 扩展):可用则优先,输出与 vast.parse 结构完全一致。 # VAST_USE_C=0 禁用 C 路径;=strict 时 C 路径异常直接抛出(fail-fast)。 _VAST_C_PARSE = None try: from lib.vast_c import parse as _VAST_C_PARSE except Exception: _VAST_C_PARSE = None def parse(source: str, filename: str = '', mode: str = 'exec', *, type_comments: bool = False, feature_version: tuple[int, int] | int | None = None) -> AST: """解析源码字符串为 AST(与 ast.parse 同签名、同结构)。 优先使用 C 加速解析器 vast_c(输出结构完全一致),异常时回退纯 Python vast; 环境变量 VAST_USE_C:'0' 禁用 C 路径,'strict' 时 C 路径异常直接抛出。 """ if _VAST_C_PARSE is not None and _os.environ.get('VAST_USE_C', '1') != '0': try: return _VAST_C_PARSE(source, mode) except Exception: if _os.environ.get('VAST_USE_C') == 'strict': raise return _ParsePure(source, mode) __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())