refactor(tpc): 删除类型联合语法并将修饰迁移为 AST 字段
类型注解不再接受任何 T1 | T2;const/volatile/static/export/extern/inline/define/typedef/__attribute__/BigEndian/LittleEndian/Bit 改为注解节点字段 Markers/Attributes/ByteOrder/BitWidth;指针与引用改为 CPtr[T]/CRef[T]/CTempRef[T]/CArrayPtr[T]/CAutoPtr[T];Python 与 vast_c 两套解析器、类型解析与声明端同步;C 扩展早于 vast_c.c 时自动回退纯 Python 解析器。
This commit is contained in:
1 parent
3269775945
commit
660a15bef8
19 files changed
+1312
-1576
No files matched your search
+132
-52
@@ -166,27 +166,37 @@ class Parser(ExprParserMixin):
|
||||
tok: Token = self._Peek()
|
||||
if tok.Type == NAME:
|
||||
v: str = tok.Value
|
||||
# extern 函数声明(FFI,等价 State)——必须在软关键字 def 分派之前
|
||||
# extern:变量声明 `extern 名字: 类型`(禁止初值)与函数声明
|
||||
# `extern [def] 名字(...)` 共用起始关键字;第二个 token 是 NAME 且
|
||||
# 再后随 ':' / '=' 时按变量声明解析,否则按函数声明解析。
|
||||
if v == 'extern':
|
||||
if self._IsStorageVarStart():
|
||||
return self._ParseStorageVar('extern')
|
||||
return self._ParseExternDef()
|
||||
# export 函数声明(等价 CExport,裸名导出不增加 SHA1 头)——
|
||||
# 必须在软关键字 def 分派之前
|
||||
# export:变量声明 `export 名字: 类型 [= 初值]` 与函数声明
|
||||
# `export [def] 名字(...)` 同理分派。
|
||||
if v == 'export':
|
||||
if self._IsStorageVarStart():
|
||||
return self._ParseStorageVar('export')
|
||||
return self._ParseExportDef()
|
||||
# static 存储类软关键字(已从"注解位置"迁出为**语句起始前置**修饰符):
|
||||
# 仅 `static def 名字` 形态判定为函数定义——判据必须同时要求第二个 token
|
||||
# 是 `def`,故 `static = 5` / `static x = 5` 不会被误吃成函数定义。
|
||||
# 变量形式 `static 名字: 类型 = 值` 不在本层处理,由 SymbolUtils 的前置
|
||||
# 修饰符展开统一脱糖为 `名字: CStatic | 类型 = 值`。
|
||||
if (v == 'static' and self._Peek(1).Type == NAME
|
||||
and self._Peek(1).Value == 'def'):
|
||||
return self._ParseStaticDef()
|
||||
# define 宏函数定义(与 def 语义一致,返回注解自动追加 CDefine
|
||||
# 标记为宏函数;软关键字:仅"define + 标识符"形态才判定为函数定义,
|
||||
# 变量名/调用(define = 5、define(x))不受影响)——必须在软关键字
|
||||
# def 分派之前
|
||||
# static:`static def 名字` 为函数定义;`static 名字: 类型` 为变量声明。
|
||||
# 判据要求第二个 token 是 NAME 且再后随 ':' / '=',故
|
||||
# `static = 5` / `static x` 不会被误吃成修饰声明。
|
||||
if v == 'static':
|
||||
if (self._Peek(1).Type == NAME
|
||||
and self._Peek(1).Value == 'def'):
|
||||
return self._ParseStaticDef()
|
||||
if self._IsStorageVarStart():
|
||||
return self._ParseStorageVar('static')
|
||||
# define:`define 名字 = 值` / `define 名字: 类型 = 值` 为编译期常量
|
||||
# 声明;`define 名字(...)` / `define 名字[T](...)` 为宏函数定义。
|
||||
if v == 'define' and self._Peek(1).Type == NAME:
|
||||
if self._IsStorageVarStart():
|
||||
return self._ParseDefineVar()
|
||||
return self._ParseDefineDef()
|
||||
# typedef 名字 = 类型:类型别名声明(右值按类型注解解析)。
|
||||
if v == 'typedef' and self._Peek(1).Type == NAME:
|
||||
return self._ParseTypedefVar()
|
||||
# virtual / novirtual 修饰符(软关键字):只在"语句起始 + 紧跟 class/def"
|
||||
# 时生效,合成既有装饰器 @CVTable / @NoVTable(见 _ParseVirtualModified)。
|
||||
# 放在 def/class 分派之前:修饰符必须先被消费,class/def 才能照常分派。
|
||||
@@ -285,6 +295,102 @@ class Parser(ExprParserMixin):
|
||||
return self._ParseDecorated()
|
||||
return self._ParseSimpleStmt()
|
||||
|
||||
# ==================================================================
|
||||
# 语句级变量修饰形态(static / export / extern / define / typedef)
|
||||
# ==================================================================
|
||||
def _IsStorageVarStart(self) -> bool:
|
||||
"""当前修饰词之后是否为变量声明形态:`修饰词 名字 :` 或 `修饰词 名字 =`。"""
|
||||
if self._Peek(1).Type != NAME:
|
||||
return False
|
||||
nxt: Token = self._Peek(2)
|
||||
return nxt.Type == OP and nxt.Value in (':', '=')
|
||||
|
||||
@staticmethod
|
||||
def _AddTypeMarkers(node: N.AST, marker: str) -> None:
|
||||
"""把修饰词追加到类型节点的 Markers 字段(保持出现顺序、去重)。"""
|
||||
if not hasattr(type(node), 'Markers'):
|
||||
return
|
||||
existing: tuple[str, ...] = tuple(getattr(node, 'Markers', ()) or ())
|
||||
if marker not in existing:
|
||||
node.Markers = existing + (marker,)
|
||||
|
||||
def _ParseStorageVar(self, marker: str) -> N.AnnAssign:
|
||||
"""解析 `static|export|extern 名字: 类型 [= 初值]` 为 AnnAssign。
|
||||
|
||||
`extern` 变量只声明不定义,禁止初值。
|
||||
"""
|
||||
start: Token = self._Next() # 修饰词
|
||||
name_tok: Token = self._ExpectName()
|
||||
if not self._AtOp(':'):
|
||||
raise SyntaxError(
|
||||
f"[vast] `{marker} 名字` 变量声明必须带类型注解:"
|
||||
f"期望 `{marker} {name_tok.Value}: 类型"
|
||||
f"{' [= 初值]' if marker != 'extern' else ''}`。")
|
||||
self._Next() # ':'
|
||||
annotation: N.expr = self._ParseTypeAnnotation()
|
||||
value: N.expr | None = None
|
||||
if self._AtOp('='):
|
||||
if marker == 'extern':
|
||||
raise SyntaxError(
|
||||
f"[vast] extern 变量声明不能带初始值(符号定义在外部):"
|
||||
f"`extern {name_tok.Value}: 类型`。")
|
||||
self._Next()
|
||||
value = self.ParseExpr()
|
||||
self._AddTypeMarkers(annotation, marker)
|
||||
target: N.Name = N.Name(id=name_tok.Value, ctx=N.Store())
|
||||
self._FixLoc(target, name_tok)
|
||||
node: N.AnnAssign = N.AnnAssign(
|
||||
target=target, annotation=annotation, value=value, simple=1)
|
||||
self._FixLoc(node, start)
|
||||
return node
|
||||
|
||||
def _ParseDefineVar(self) -> N.AnnAssign:
|
||||
"""解析 `define 名字[: 类型] = 值` 为编译期常量声明(Markers += 'define')。"""
|
||||
start: Token = self._Next() # 'define'
|
||||
name_tok: Token = self._ExpectName()
|
||||
annotation: N.expr | None = None
|
||||
if self._AtOp(':'):
|
||||
self._Next()
|
||||
annotation = self._ParseTypeAnnotation()
|
||||
if not self._AtOp('='):
|
||||
raise SyntaxError(
|
||||
f"[vast] define 常量声明缺少初值:"
|
||||
f"期望 `define {name_tok.Value}[: 类型] = 值`。")
|
||||
self._Next() # '='
|
||||
value: N.expr = self.ParseExpr()
|
||||
if annotation is None:
|
||||
# 未标注类型:注解占位为 CDefine(Markers 仍承载 'define')。
|
||||
annotation = N.Name(id='CDefine', ctx=N.Load())
|
||||
self._FixLoc(annotation, start)
|
||||
self._AddTypeMarkers(annotation, 'define')
|
||||
target: N.Name = N.Name(id=name_tok.Value, ctx=N.Store())
|
||||
self._FixLoc(target, name_tok)
|
||||
node: N.AnnAssign = N.AnnAssign(
|
||||
target=target, annotation=annotation, value=value, simple=1)
|
||||
self._FixLoc(node, start)
|
||||
return node
|
||||
|
||||
def _ParseTypedefVar(self) -> N.AnnAssign:
|
||||
"""解析 `typedef 名字 = 类型` 为类型别名声明(Markers += 'typedef')。
|
||||
|
||||
右值按类型注解解析(支持 `T*` 等 C 风格后缀)。
|
||||
"""
|
||||
start: Token = self._Next() # 'typedef'
|
||||
name_tok: Token = self._ExpectName()
|
||||
if not self._AtOp('='):
|
||||
raise SyntaxError(
|
||||
f"[vast] typedef 语法错误:"
|
||||
f"期望 `typedef {name_tok.Value} = 类型`。")
|
||||
self._Next() # '='
|
||||
type_node: N.expr = self._ParseTypeAnnotation()
|
||||
self._AddTypeMarkers(type_node, 'typedef')
|
||||
target: N.Name = N.Name(id=name_tok.Value, ctx=N.Store())
|
||||
self._FixLoc(target, name_tok)
|
||||
node: N.AnnAssign = N.AnnAssign(
|
||||
target=target, annotation=type_node, value=type_node, simple=1)
|
||||
self._FixLoc(node, start)
|
||||
return node
|
||||
|
||||
# ==================================================================
|
||||
# fallthrough 关键字(语句级)
|
||||
# ==================================================================
|
||||
@@ -422,12 +528,11 @@ class Parser(ExprParserMixin):
|
||||
|
||||
@staticmethod
|
||||
def _IsCTypedefAnnotation(annotation: N.expr | None) -> bool:
|
||||
"""注解是否为 typedef 标记(裸 `CTypedef` / `CTypedef` / 含它的 `|` 联合)。
|
||||
"""注解是否为 typedef 标记(裸 `CTypedef` / 含它的 `|` 联合)。
|
||||
|
||||
用于把 typedef 的右值按**类型位置**解析(`X: CTypedef = const uint16*`
|
||||
里的 `*` 后缀由 _ParseTypeAnnotation 消费,与注解位同一规则;描述符
|
||||
`const`/`volatile` 已由 SymbolUtils._ExpandTypeDescriptors 在文本层展开)。
|
||||
仅按标记名判定,不依赖 import 别名表(与 VPC `_IsCTypedefAnnotation` 同口径)。
|
||||
用于把 typedef 的右值按**类型位置**解析(`X: CTypedef = T` 里的 `*`
|
||||
后缀由 _ParseTypeAnnotation 消费,与注解位同一规则)。仅按标记名判定,
|
||||
不依赖 import 别名表(与 VPC `_IsCTypedefAnnotation` 同口径)。
|
||||
"""
|
||||
if annotation is None:
|
||||
return False
|
||||
@@ -921,7 +1026,7 @@ class Parser(ExprParserMixin):
|
||||
return node
|
||||
|
||||
def _ParseExternDef(self, decorators: list[N.expr] | None = None) -> N.FunctionDef:
|
||||
"""解析 extern 函数声明(FFI,与 State 作用相当)。
|
||||
"""解析 extern 函数声明(FFI,仅声明不定义)。
|
||||
|
||||
允许语法(均声明不定义,不生成函数体):
|
||||
extern def A(x: int) -> int: pass
|
||||
@@ -929,9 +1034,8 @@ class Parser(ExprParserMixin):
|
||||
extern def A(x: int) -> int
|
||||
extern A(x: int) -> int
|
||||
|
||||
产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | State``
|
||||
以复用 TPC 的 IsState 路径;并设自定义属性 ``Extern = True``
|
||||
供 Unparser 还原 extern 语法。
|
||||
产出标准 FunctionDef 节点,``Extern = True`` 供 Unparser 还原 extern 语法;
|
||||
返回注解保持源码原样(不追加 `| State`)。
|
||||
"""
|
||||
start: Token = self._Next() # 'extern'
|
||||
if self._AtName('def'):
|
||||
@@ -955,12 +1059,6 @@ class Parser(ExprParserMixin):
|
||||
type_comment=None, type_params=type_params,
|
||||
)
|
||||
node.Extern = True
|
||||
# 返回注解改写为 <原类型> | State,使 TPC 识别为 State 函数(仅声明)
|
||||
state_attr: N.expr = N.Name(id='State', ctx=N.Load())
|
||||
if returns is not None:
|
||||
node.returns = N.BinOp(left=returns, op=N.BitOr(), right=state_attr)
|
||||
else:
|
||||
node.returns = state_attr
|
||||
self._FixLoc(node, start)
|
||||
return node
|
||||
|
||||
@@ -973,9 +1071,8 @@ class Parser(ExprParserMixin):
|
||||
export def A(x: int) -> int
|
||||
export A(x: int) -> int
|
||||
|
||||
产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | CExport``
|
||||
以复用 TPC 的 CExport 路径(符号名不增加 SHA1 前缀);并设自定义
|
||||
属性 ``Export = True`` 供 Unparser 还原 export 语法。
|
||||
产出标准 FunctionDef 节点,``Export = True`` 供 Unparser 还原 export 语法;
|
||||
返回注解保持源码原样(不追加 `| CExport`)。
|
||||
"""
|
||||
start: Token = self._Next() # 'export'
|
||||
if self._AtName('def'):
|
||||
@@ -999,13 +1096,6 @@ class Parser(ExprParserMixin):
|
||||
type_comment=None, type_params=type_params,
|
||||
)
|
||||
node.Export = True
|
||||
# 返回注解改写为 <原类型> | CExport,使 TPC 识别为 CExport 函数
|
||||
# (导出裸名,不增加模块 SHA1 头;有条件情况下导出)
|
||||
export_attr: N.expr = N.Name(id='CExport', ctx=N.Load())
|
||||
if returns is not None:
|
||||
node.returns = N.BinOp(left=returns, op=N.BitOr(), right=export_attr)
|
||||
else:
|
||||
node.returns = export_attr
|
||||
self._FixLoc(node, start)
|
||||
return node
|
||||
|
||||
@@ -1072,11 +1162,8 @@ class Parser(ExprParserMixin):
|
||||
define A(x: int) -> int: ...
|
||||
define A(x: int): ...
|
||||
|
||||
产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | CDefine``
|
||||
(无显式返回注解时单独 ``CDefine``),使 TPC/VPC 复用既有的
|
||||
CDefine 宏函数识别路径(StubGen 原样保留生成 C #define、
|
||||
alwaysinline 内联);并设自定义属性 ``Define = True`` 供
|
||||
Unparser 还原 define 语法。
|
||||
产出标准 FunctionDef 节点,``Define = True`` 供 Unparser 还原 define 语法;
|
||||
返回注解保持源码原样(不追加 `| CDefine`)。
|
||||
"""
|
||||
start: Token = self._Next() # 'define'
|
||||
name_tok: Token = self._ExpectName()
|
||||
@@ -1096,13 +1183,6 @@ class Parser(ExprParserMixin):
|
||||
type_comment=None, type_params=type_params,
|
||||
)
|
||||
node.Define = True
|
||||
# 返回注解改写为 <原类型> | CDefine,使下游识别为宏函数
|
||||
# (StubGen 保留原样输出 C #define;TPC 标记 alwaysinline 内联)
|
||||
define_attr: N.expr = N.Name(id='CDefine', ctx=N.Load())
|
||||
if returns is not None:
|
||||
node.returns = N.BinOp(left=returns, op=N.BitOr(), right=define_attr)
|
||||
else:
|
||||
node.returns = define_attr
|
||||
self._FixLoc(node, start)
|
||||
return node
|
||||
|
||||
|
||||
Reference in new issue
Block a user