/* vast_c - C 版 Viper/Python 语法解析器(vast 加速层) * * 完整 Python 3.12 + Viper 软关键字(fn/fun/func/function → def)解析器, * 直接构造 lib.vast.Nodes 的节点类实例,输出与 vast.parse 结构完全一致 * (vast.dump 逐字节相同)。 * * 编译(MSYS2 MinGW gcc,Python 3.12,注意 -l 必须在源文件之后): * gcc -shared -O2 -std=c11 -I D:\Python312\include lib\vast_c\vast_c.c \ * -L D:\Python312\libs -lpython312 -o lib\vast_c\_parser.pyd * * 使用: * from lib.vast_c import parse # 由 lib/vast_c/__init__.py 导出 * tree = parse("x = 1") # 与 vast.parse 同结构 */ #define PY_SSIZE_T_CLEAN #include #include #include #include /* ================= 记号(Token) ================= */ typedef enum { TK_ENDMARKER = 0, TK_NAME, TK_NUMBER, TK_STRING, TK_FSTRING, TK_OP, TK_NEWLINE, TK_NL, TK_INDENT, TK_DEDENT, } TokenKind; typedef struct { TokenKind Kind; const char *Start; /* 指向源码(UTF-8 字节) */ const char *End; int Line; /* 1-based 行号 */ int Col; /* 0-based UTF-8 字节列偏移 */ int EndLine; int EndCol; int StartOff; /* 源码字节偏移 */ int EndOff; } Token; /* Token 类型名(与 Python vast.Tokenizer 的常量同名,使两侧报文措辞一致)。 */ static const char *TokKindName(TokenKind K) { switch (K) { case TK_NAME: return "NAME"; case TK_NUMBER: return "NUMBER"; case TK_STRING: return "STRING"; case TK_FSTRING: return "FSTRING"; case TK_OP: return "OP"; case TK_NEWLINE: return "NEWLINE"; case TK_NL: return "NL"; case TK_INDENT: return "INDENT"; case TK_DEDENT: return "DEDENT"; default: return "ENDMARKER"; } } /* ================= 词法分析器(Lexer) ================= */ typedef struct { const char *Src; Py_ssize_t Len; Py_ssize_t Pos; int BracketDepth; int AtLineStart; int ContinuationLine; int BlankLine; int *Indents; int NIndents; int IndentsCap; Token *Tokens; int NTokens; int TokensCap; int *LineStarts; /* 行起始字节偏移表 */ int NLineStarts; int LineStartsCap; int Error; } Lexer; /* ================= 解析器(Parser) ================= */ typedef struct { const char *Src; Py_ssize_t Len; Token *Tokens; int NTokens; int Idx; int *LineStarts; int NLineStarts; int Error; /* 语法错误标志(可回退) */ const char *ErrMsg; int ErrLine; Token *ErrTok; /* 出错处的 token(供报错带上类型与原文) */ int FStringExprEnd; /* f-string 表达式段结束位置(body 内偏移) */ int InTypeAnnotation; /* 类型注解模式:'*'/'**' 允许按 C 风格指针后缀判定 */ int InClassBody; /* 当前套件的直接拥有者是否为 ClassDef(virtual def 判据) */ int InCIfCond; /* 是否正在解析 cif/celif 条件(defined(NAME) 合法位置判据) */ Token *PtrSuffixTail; /* 最近消费的 C 指针后缀尾 token(识别 (T*)x 无括号强转) */ } Parser; /* vast.nodes 模块与节点类缓存(进程级惰性初始化) */ static PyObject *s_Nodes = NULL; static PyObject *s_Classes = NULL; /* dict: 类名 -> 类对象 */ static PyObject *s_SlotsCache = NULL; /* dict: 类对象 -> PyCapsule(SlotsLayout*) */ static PyObject *NodesModule(void) { if (s_Nodes == NULL) { s_Nodes = PyImport_ImportModule("lib.vast.Nodes"); } return s_Nodes; } /* 获取节点类对象(borrowed 引用,内部缓存避免重复属性查找) */ static PyObject *ClassGet(Parser *P, const char *Name) { PyObject *Mod = NodesModule(); if (Mod == NULL) { return NULL; } if (s_Classes == NULL) { s_Classes = PyDict_New(); if (s_Classes == NULL) { return NULL; } } PyObject *Key = PyUnicode_FromString(Name); if (Key == NULL) { return NULL; } PyObject *Cls = PyDict_GetItemWithError(s_Classes, Key); /* borrowed */ if (Cls == NULL && !PyErr_Occurred()) { Cls = PyObject_GetAttrString(Mod, Name); if (Cls == NULL) { Py_DECREF(Key); return NULL; } if (PyDict_SetItem(s_Classes, Key, Cls) < 0) { Py_DECREF(Cls); Py_DECREF(Key); return NULL; } } Py_DECREF(Key); return Cls; /* borrowed */ } /* slots 直写布局:按 _fields 顺序的成员偏移(PyMemberDef.offset,相对实例基址) */ typedef struct { Py_ssize_t *Offsets; Py_ssize_t NFields; } SlotsLayout; static void FreeSlotsLayout(PyObject *Capsule) { void *P = PyCapsule_GetPointer(Capsule, NULL); if (P != NULL) { PyMem_Free(((SlotsLayout *)P)->Offsets); PyMem_Free(P); } } /* 按 _fields 顺序在 tp_members 中查找各字段的 slots offset; * 任一字段缺失返回 NULL(调用方回退 Vectorcall)。 */ static SlotsLayout *BuildSlotsLayout(PyTypeObject *Tp, PyObject *Fields) { Py_ssize_t N = PyTuple_GET_SIZE(Fields); SlotsLayout *Layout = (SlotsLayout *)PyMem_Malloc(sizeof(SlotsLayout)); if (Layout == NULL) { return NULL; } Layout->Offsets = (Py_ssize_t *)PyMem_Malloc((size_t)N * sizeof(Py_ssize_t)); if (Layout->Offsets == NULL) { PyMem_Free(Layout); return NULL; } Layout->NFields = N; PyMemberDef *M = Tp->tp_members; for (Py_ssize_t I = 0; I < N; I++) { PyObject *FName = PyTuple_GET_ITEM(Fields, I); if (!PyUnicode_Check(FName)) { goto fail; } const char *FNameStr = PyUnicode_AsUTF8(FName); if (FNameStr == NULL) { goto fail; } Py_ssize_t Found = -1; for (PyMemberDef *MM = M; MM != NULL && MM->name != NULL; MM++) { if (strcmp(MM->name, FNameStr) == 0) { Found = MM->offset; break; } } if (Found < 0) { goto fail; } Layout->Offsets[I] = Found; } return Layout; fail: PyMem_Free(Layout->Offsets); PyMem_Free(Layout); return NULL; } /* 构造节点:按位置参数数组实例化 vast.nodes 类。 * slots 直写路径:tp_new + 按 _fields 偏移直接写成员(绕过 Python 层 _Init, * _Init 201 万次 26s 是 worker 最大 tottime;slots 直写 ~ns vs _Init 帧 ~10us)。 * 布局构建失败 / 参数越界 / 类型不符 → 回退 PyObject_Vectorcall(行为与 vast 一致)。 */ static PyObject *NewNode(Parser *P, const char *Name, PyObject **Args, Py_ssize_t NArgs) { PyObject *Cls = ClassGet(P, Name); if (Cls == NULL) { return NULL; } if (PyType_Check(Cls) && ((PyTypeObject *)Cls)->tp_new != NULL) { PyTypeObject *Tp = (PyTypeObject *)Cls; if (s_SlotsCache == NULL) { s_SlotsCache = PyDict_New(); if (s_SlotsCache == NULL) { return NULL; } } PyObject *Capsule = PyDict_GetItemWithError(s_SlotsCache, Cls); /* borrowed */ if (Capsule == NULL && !PyErr_Occurred()) { PyObject *Fields = PyObject_GetAttrString(Cls, "_fields"); if (Fields != NULL && PyTuple_Check(Fields)) { SlotsLayout *Layout = BuildSlotsLayout(Tp, Fields); if (Layout != NULL) { Capsule = PyCapsule_New(Layout, NULL, FreeSlotsLayout); if (Capsule == NULL) { /* PyCapsule_New 失败:Layout 未转交,手动释放 */ PyMem_Free(Layout->Offsets); PyMem_Free(Layout); } else if (PyDict_SetItem(s_SlotsCache, Cls, Capsule) < 0) { /* SetItem 失败:DECREF 触发 FreeSlotsLayout 释放 Layout(勿重复释放) */ Py_DECREF(Capsule); Capsule = NULL; } } } Py_XDECREF(Fields); } if (Capsule != NULL) { SlotsLayout *Layout = PyCapsule_GetPointer(Capsule, NULL); if (Layout != NULL && NArgs <= Layout->NFields) { /* tp_new 的 args 不能为 NULL(object_new 内部 PyTuple_GET_SIZE(NULL) 崩溃) */ PyObject *EmptyArgs = PyTuple_New(0); if (EmptyArgs == NULL) { return NULL; } PyObject *Inst = Tp->tp_new(Tp, EmptyArgs, NULL); Py_DECREF(EmptyArgs); if (Inst == NULL) { return NULL; } for (Py_ssize_t I = 0; I < NArgs; I++) { /* slots 由 PyType_GenericAlloc 清零为 NULL,直接赋值 + INCREF */ PyObject **Slot = (PyObject **)((char *)Inst + Layout->Offsets[I]); Py_INCREF(Args[I]); *Slot = Args[I]; } return Inst; } } } return PyObject_Vectorcall(Cls, Args, NArgs, NULL); } /* 设置整数属性;失败(无槽位)时清除异常 */ static void SetAttrLong(PyObject *Node, const char *Name, long V) { PyObject *O = PyLong_FromLong(V); if (O == NULL) { PyErr_Clear(); return; } if (PyObject_SetAttrString(Node, Name, O) < 0) { PyErr_Clear(); } Py_DECREF(O); } /* 设置 4 个位置属性 */ static void NodePos(Parser *P, PyObject *Node, int Line, int Col, int EndLine, int EndCol) { SetAttrLong(Node, "lineno", Line); SetAttrLong(Node, "col_offset", Col); SetAttrLong(Node, "end_lineno", EndLine); SetAttrLong(Node, "end_col_offset", EndCol); } /* 仅设置 lineno/col_offset(f-string 内部字面量常量用) */ static void NodePosNoEnd(Parser *P, PyObject *Node, int Line, int Col) { SetAttrLong(Node, "lineno", Line); SetAttrLong(Node, "col_offset", Col); } /* 前一个 token(借用的 _Prev 语义) */ static Token *PrevTok(Parser *P) { int I = P->Idx > 0 ? P->Idx - 1 : 0; return &P->Tokens[I]; } /* FixLoc:start 用给定 token,end 缺省取前一个 token(vast _FixLoc 语义) */ static void FixLocEnd(Parser *P, PyObject *Node, Token *Start, Token *End) { if (End == NULL) { End = PrevTok(P); } NodePos(P, Node, Start->Line, Start->Col, End->EndLine, End->EndCol); } static void FixLoc(Parser *P, PyObject *Node, Token *Start) { FixLocEnd(P, Node, Start, NULL); } /* 节点类名(动态 type() 创建的类 tp_name 即类名) */ static const char *TypeName(PyObject *Node) { return Py_TYPE(Node)->tp_name; } static int NodeIs(PyObject *Node, const char *Name) { return strcmp(Py_TYPE(Node)->tp_name, Name) == 0; } /* ================= 字符分类 ================= */ static int IsNameStart(int C) { return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z') || C == '_' || C >= 0x80; } static int IsNameChar(int C) { return IsNameStart(C) || (C >= '0' && C <= '9'); } static int IsDigit(int C) { return C >= '0' && C <= '9'; } static int IsAlnum(int C) { return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z') || (C >= '0' && C <= '9'); } static int IsStringPrefixChar(int C) { return C == 'r' || C == 'R' || C == 'b' || C == 'B' || C == 'u' || C == 'U' || C == 'f' || C == 'F'; } /* ================= 行起始表 ================= */ /* bisect_right(LineStarts, Off) - 1 → (行号, 字节列) */ static void PosInfoLS(const int *LineStarts, int N, int Off, int *Line, int *Col) { int Lo = 0, Hi = N - 1, Ans = 0; while (Lo <= Hi) { int Mid = (Lo + Hi) / 2; if (LineStarts[Mid] <= Off) { Ans = Mid; Lo = Mid + 1; } else { Hi = Mid - 1; } } *Line = Ans + 1; *Col = Off - LineStarts[Ans]; } /* ================= Lexer 基础 ================= */ static void RegisterNewline(Lexer *L, int Pos) { if (L->NLineStarts >= L->LineStartsCap) { int NCap = L->LineStartsCap ? L->LineStartsCap * 2 : 32; int *NS = (int *)PyMem_Realloc(L->LineStarts, (size_t)NCap * sizeof(int)); if (NS == NULL) { L->Error = 1; return; } L->LineStarts = NS; L->LineStartsCap = NCap; } L->LineStarts[L->NLineStarts++] = Pos; } static void EmitToken(Lexer *L, TokenKind Kind, int StartOff, int EndOff) { if (L->NTokens >= L->TokensCap) { int NCap = L->TokensCap ? L->TokensCap * 2 : 128; Token *NT = (Token *)PyMem_Realloc(L->Tokens, (size_t)NCap * sizeof(Token)); if (NT == NULL) { L->Error = 1; return; } L->Tokens = NT; L->TokensCap = NCap; } Token *T = &L->Tokens[L->NTokens]; T->Kind = Kind; T->Start = L->Src + StartOff; T->End = L->Src + EndOff; T->StartOff = StartOff; T->EndOff = EndOff; PosInfoLS(L->LineStarts, L->NLineStarts, StartOff, &T->Line, &T->Col); PosInfoLS(L->LineStarts, L->NLineStarts, EndOff, &T->EndLine, &T->EndCol); L->NTokens++; } /* 运算符最长匹配(与 vast Tokenizer._OPERATORS 一致) */ static int MatchOperator(const char *S, Py_ssize_t N) { if (N <= 0) { return 0; } char C = S[0]; switch (C) { case '*': if (N >= 3 && S[1] == '*' && S[2] == '=') return 3; if (N >= 2 && S[1] == '*') return 2; if (N >= 2 && S[1] == '=') return 2; return 1; case '/': if (N >= 3 && S[1] == '/' && S[2] == '=') return 3; if (N >= 2 && S[1] == '/') return 2; if (N >= 2 && S[1] == '=') return 2; return 1; case '<': if (N >= 3 && S[1] == '<' && S[2] == '=') return 3; if (N >= 2 && S[1] == '<') return 2; if (N >= 2 && S[1] == '=') return 2; return 1; case '>': if (N >= 3 && S[1] == '>' && S[2] == '=') return 3; if (N >= 2 && S[1] == '>') return 2; if (N >= 2 && S[1] == '=') return 2; return 1; case '=': return (N >= 2 && S[1] == '=') ? 2 : 1; case '!': return (N >= 2 && S[1] == '=') ? 2 : 1; case ':': return (N >= 2 && S[1] == '=') ? 2 : 1; case '-': if (N >= 2 && S[1] == '>') return 2; if (N >= 2 && S[1] == '=') return 2; return 1; case '+': return (N >= 2 && S[1] == '=') ? 2 : 1; case '%': return (N >= 2 && S[1] == '=') ? 2 : 1; case '@': return (N >= 2 && S[1] == '=') ? 2 : 1; case '&': return (N >= 2 && S[1] == '=') ? 2 : 1; case '|': return (N >= 2 && S[1] == '=') ? 2 : 1; case '^': return (N >= 2 && S[1] == '=') ? 2 : 1; case '.': return (N >= 3 && S[1] == '.' && S[2] == '.') ? 3 : 1; default: if (C == '(' || C == ')' || C == '[' || C == ']' || C == '{' || C == '}' || C == ',' || C == ';' || C == '~') { return 1; } return 0; } } static void EmitOp(Lexer *L) { int Start = (int)L->Pos; int Len = MatchOperator(L->Src + L->Pos, L->Len - L->Pos); if (Len <= 0) { Len = 1; } L->Pos += Len; EmitToken(L, TK_OP, Start, (int)L->Pos); L->AtLineStart = 0; } static void HandleNewline(Lexer *L) { int NlStart = (int)L->Pos - 1; if (NlStart > 0 && L->Src[NlStart] == '\n' && L->Src[NlStart - 1] == '\r') { NlStart--; } if (L->BracketDepth > 0 || L->BlankLine || (L->AtLineStart && !L->ContinuationLine)) { EmitToken(L, TK_NL, NlStart, (int)L->Pos); } else { EmitToken(L, TK_NEWLINE, NlStart, (int)L->Pos); } RegisterNewline(L, (int)L->Pos); L->AtLineStart = 1; L->ContinuationLine = 0; L->BlankLine = 0; } static void HandleIndent(Lexer *L) { int Start = (int)L->Pos; int Col = 0; while (L->Pos < L->Len) { char Ch = L->Src[L->Pos]; if (Ch == ' ') { Col++; L->Pos++; } else if (Ch == '\t') { Col = (Col / 8 + 1) * 8; L->Pos++; } else if (Ch == '\f' || Ch == '\v') { /* \f(换页)与 \v(垂直制表)不计入缩进列;\v 对齐 Viper 词法层 * includes/ast/lexer.vp 的 _is_space(与 Python Tokenizer 同口径)。 */ L->Pos++; } else { break; } } L->AtLineStart = 0; if (L->Pos >= L->Len || L->Src[L->Pos] == '\r' || L->Src[L->Pos] == '\n' || L->Src[L->Pos] == '#') { L->BlankLine = 1; return; } int Cur = L->Indents[L->NIndents - 1]; if (Col > Cur) { if (L->NIndents >= L->IndentsCap) { int NCap = L->IndentsCap ? L->IndentsCap * 2 : 16; int *NI = (int *)PyMem_Realloc(L->Indents, (size_t)NCap * sizeof(int)); if (NI == NULL) { L->Error = 1; return; } L->Indents = NI; L->IndentsCap = NCap; } L->Indents[L->NIndents++] = Col; EmitToken(L, TK_INDENT, Start, (int)L->Pos); } else if (Col < Cur) { while (L->NIndents > 0 && L->Indents[L->NIndents - 1] > Col) { L->NIndents--; EmitToken(L, TK_DEDENT, (int)L->Pos, (int)L->Pos); } } } static void ScanComment(Lexer *L) { while (L->Pos < L->Len && L->Src[L->Pos] != '\r' && L->Src[L->Pos] != '\n') { L->Pos++; } } static void ScanContinuation(Lexer *L) { if (L->Pos + 1 < L->Len && (L->Src[L->Pos + 1] == '\r' || L->Src[L->Pos + 1] == '\n')) { L->Pos += 1; if (L->Pos < L->Len && L->Src[L->Pos] == '\r') { L->Pos += 1; } if (L->Pos < L->Len && L->Src[L->Pos] == '\n') { L->Pos += 1; } RegisterNewline(L, (int)L->Pos); L->AtLineStart = 1; L->ContinuationLine = 1; } else { L->Pos += 1; } } static void ScanName(Lexer *L) { int Start = (int)L->Pos; while (L->Pos < L->Len && IsNameChar((unsigned char)L->Src[L->Pos])) { L->Pos++; } EmitToken(L, TK_NAME, Start, (int)L->Pos); L->AtLineStart = 0; } static void ScanNumber(Lexer *L) { int Start = (int)L->Pos; if (L->Src[L->Pos] == '0' && L->Pos + 1 < L->Len) { char Nxt = L->Src[L->Pos + 1]; if (Nxt == 'x' || Nxt == 'X' || Nxt == 'o' || Nxt == 'O' || Nxt == 'b' || Nxt == 'B') { L->Pos += 2; while (L->Pos < L->Len && (IsAlnum((unsigned char)L->Src[L->Pos]) || L->Src[L->Pos] == '_')) { L->Pos++; } EmitToken(L, TK_NUMBER, Start, (int)L->Pos); L->AtLineStart = 0; return; } } while (L->Pos < L->Len && (IsDigit((unsigned char)L->Src[L->Pos]) || L->Src[L->Pos] == '_')) { L->Pos++; } if (L->Pos < L->Len && L->Src[L->Pos] == '.') { L->Pos++; while (L->Pos < L->Len && (IsDigit((unsigned char)L->Src[L->Pos]) || L->Src[L->Pos] == '_')) { L->Pos++; } } if (L->Pos < L->Len && (L->Src[L->Pos] == 'e' || L->Src[L->Pos] == 'E')) { Py_ssize_t Save = L->Pos; L->Pos++; if (L->Pos < L->Len && (L->Src[L->Pos] == '+' || L->Src[L->Pos] == '-')) { L->Pos++; } if (L->Pos < L->Len && (IsDigit((unsigned char)L->Src[L->Pos]) || L->Src[L->Pos] == '_')) { while (L->Pos < L->Len && (IsDigit((unsigned char)L->Src[L->Pos]) || L->Src[L->Pos] == '_')) { L->Pos++; } } else { L->Pos = Save; } } if (L->Pos < L->Len && (L->Src[L->Pos] == 'j' || L->Src[L->Pos] == 'J')) { L->Pos++; } EmitToken(L, TK_NUMBER, Start, (int)L->Pos); L->AtLineStart = 0; } static void SkipInnerString(Lexer *L); static void ScanFStringExpr(Lexer *L); static void ScanStringBody(Lexer *L, char Quote, int Triple, int IsFString) { while (L->Pos < L->Len) { char Ch = L->Src[L->Pos]; if (Ch == '\\') { if (L->Pos + 1 < L->Len && (L->Src[L->Pos + 1] == '{' || L->Src[L->Pos + 1] == '}')) { L->Pos += 1; } else { L->Pos += 2; } continue; } if (Ch == '\n') { L->Pos++; RegisterNewline(L, (int)L->Pos); continue; } if (IsFString && Ch == '{') { if (L->Pos + 1 < L->Len && L->Src[L->Pos + 1] == '{') { L->Pos += 2; continue; } ScanFStringExpr(L); continue; } if (IsFString && Ch == '}') { if (L->Pos + 1 < L->Len && L->Src[L->Pos + 1] == '}') { L->Pos += 2; continue; } L->Pos += 1; continue; } if (Ch == Quote) { if (Triple) { if (L->Pos + 2 < L->Len && L->Src[L->Pos] == Quote && L->Src[L->Pos + 1] == Quote && L->Src[L->Pos + 2] == Quote) { L->Pos += 3; return; } L->Pos += 1; continue; } else { L->Pos += 1; return; } } L->Pos += 1; } } static void ScanFStringExpr(Lexer *L) { L->Pos += 1; /* 跳过 { */ int Depth = 1; while (L->Pos < L->Len) { char Ch = L->Src[L->Pos]; if (Ch == '\\') { L->Pos += 2; continue; } if (Ch == '\n') { L->Pos++; RegisterNewline(L, (int)L->Pos); continue; } if (Ch == '\'' || Ch == '"') { SkipInnerString(L); continue; } if (Ch == '(' || Ch == '[' || Ch == '{') { Depth++; L->Pos++; continue; } if (Ch == ')' || Ch == ']') { Depth--; L->Pos++; continue; } if (Ch == '}') { if (Depth == 1) { L->Pos++; return; } Depth--; L->Pos++; continue; } L->Pos++; } } static void SkipInnerString(Lexer *L) { Py_ssize_t Save = L->Pos; while (L->Pos < L->Len && IsStringPrefixChar((unsigned char)L->Src[L->Pos])) { L->Pos++; } if (L->Pos >= L->Len || (L->Src[L->Pos] != '\'' && L->Src[L->Pos] != '"')) { L->Pos = Save; L->Pos += 1; return; } char InnerQuote = L->Src[L->Pos]; int Triple = (L->Pos + 2 < L->Len && L->Src[L->Pos] == InnerQuote && L->Src[L->Pos + 1] == InnerQuote && L->Src[L->Pos + 2] == InnerQuote); if (Triple) { L->Pos += 3; } else { L->Pos += 1; } ScanStringBody(L, InnerQuote, Triple, 0); } static int TryScanString(Lexer *L) { Py_ssize_t Start = L->Pos; while (L->Pos < L->Len && IsStringPrefixChar((unsigned char)L->Src[L->Pos])) { L->Pos++; } if (L->Pos >= L->Len || (L->Src[L->Pos] != '\'' && L->Src[L->Pos] != '"')) { L->Pos = Start; return 0; } int IsFString = 0; for (Py_ssize_t K = Start; K < L->Pos; K++) { char C = L->Src[K]; if (C == 'f' || C == 'F') { IsFString = 1; } } char Quote = L->Src[L->Pos]; int Triple = (L->Pos + 2 < L->Len && L->Src[L->Pos] == Quote && L->Src[L->Pos + 1] == Quote && L->Src[L->Pos + 2] == Quote); if (Triple) { L->Pos += 3; } else { L->Pos += 1; } ScanStringBody(L, Quote, Triple, IsFString); EmitToken(L, IsFString ? TK_FSTRING : TK_STRING, (int)Start, (int)L->Pos); L->AtLineStart = 0; return 1; } static void FinishFile(Lexer *L) { if (L->NTokens > 0) { TokenKind K = L->Tokens[L->NTokens - 1].Kind; if (K != TK_NEWLINE && K != TK_DEDENT && K != TK_INDENT) { EmitToken(L, TK_NEWLINE, (int)L->Pos, (int)L->Pos); } } while (L->NIndents > 1) { L->NIndents--; EmitToken(L, TK_DEDENT, (int)L->Pos, (int)L->Pos); } EmitToken(L, TK_ENDMARKER, (int)L->Pos, (int)L->Pos); } /* 词法分析主循环(对齐 vast Tokenizer.Tokenize) */ static void TokenizeMainLoop(Lexer *L) { while (L->Pos < L->Len) { unsigned char Ch = (unsigned char)L->Src[L->Pos]; if (L->AtLineStart && L->BracketDepth == 0 && !L->ContinuationLine && Ch != '\r' && Ch != '\n') { HandleIndent(L); if (L->Pos >= L->Len) { break; } continue; } if (Ch == ' ' || Ch == '\t' || Ch == '\f' || Ch == '\v') { L->Pos++; continue; } if (Ch == '\r') { L->Pos++; if (L->Pos < L->Len && L->Src[L->Pos] == '\n') { L->Pos++; } HandleNewline(L); continue; } if (Ch == '\n') { L->Pos++; HandleNewline(L); continue; } if (Ch == '#') { ScanComment(L); continue; } if (Ch == '\\') { ScanContinuation(L); continue; } if (Ch == '(' || Ch == '[' || Ch == '{') { L->BracketDepth++; EmitOp(L); continue; } if (Ch == ')' || Ch == ']' || Ch == '}') { if (L->BracketDepth > 0) { L->BracketDepth--; } EmitOp(L); continue; } if (Ch == '\'' || Ch == '"' || IsNameStart(Ch)) { if (TryScanString(L)) { continue; } if (IsDigit(Ch)) { ScanNumber(L); continue; } if (IsNameStart(Ch)) { ScanName(L); continue; } } if (IsDigit(Ch) || (Ch == '.' && L->Pos + 1 < L->Len && IsDigit((unsigned char)L->Src[L->Pos + 1]))) { ScanNumber(L); continue; } EmitOp(L); } } /* 对任意文本执行完整 tokenize。 * OutLineStarts/OutNLineStarts 可为 NULL(子表达式不需要)。 * 返回 1 成功,0 失败(内存不足)。 */ static int TokenizeText(const char *Src, Py_ssize_t Len, Token **OutTokens, int *OutN, int **OutLineStarts, int *OutNLineStarts) { Lexer L; memset(&L, 0, sizeof(L)); L.Src = Src; L.Len = Len; L.Pos = 0; L.AtLineStart = 1; L.Indents = (int *)PyMem_Malloc(sizeof(int)); if (L.Indents == NULL) { return 0; } L.Indents[0] = 0; L.NIndents = 1; L.IndentsCap = 1; RegisterNewline(&L, 0); TokenizeMainLoop(&L); if (!L.Error) { FinishFile(&L); } *OutTokens = L.Tokens; *OutN = L.NTokens; if (OutLineStarts) { *OutLineStarts = L.LineStarts; *OutNLineStarts = L.NLineStarts; } PyMem_Free(L.Indents); if (OutLineStarts == NULL) { PyMem_Free(L.LineStarts); } return !L.Error; } /* ================= Parser 游标辅助 ================= */ static Token *PeekTok(Parser *P, int Off) { int I = P->Idx + Off; if (I >= P->NTokens) { I = P->NTokens - 1; } if (I < 0) { I = 0; } return &P->Tokens[I]; } static Token *NextTok(Parser *P) { Token *T = &P->Tokens[P->Idx]; if (P->Idx < P->NTokens - 1) { P->Idx++; } return T; } static int TokIsOp(Token *T, const char *S) { if (T->Kind != TK_OP) { return 0; } Py_ssize_t L = (Py_ssize_t)strlen(S); return (T->End - T->Start == L) && memcmp(T->Start, S, (size_t)L) == 0; } static int TokIsName(Token *T, const char *S) { if (T->Kind != TK_NAME) { return 0; } Py_ssize_t L = (Py_ssize_t)strlen(S); return (T->End - T->Start == L) && memcmp(T->Start, S, (size_t)L) == 0; } static int AtOp(Parser *P, const char *S) { return TokIsOp(PeekTok(P, 0), S); } static int AtName(Parser *P, const char *S) { return TokIsName(PeekTok(P, 0), S); } static void SkipNL(Parser *P) { while (PeekTok(P, 0)->Kind == TK_NL) { NextTok(P); } } static void SkipNEWLINE(Parser *P) { while (PeekTok(P, 0)->Kind == TK_NEWLINE || PeekTok(P, 0)->Kind == TK_NL) { NextTok(P); } } static void SyntaxErrorAt(Parser *P, Token *T, const char *Msg) { P->Error = 1; P->ErrMsg = Msg; P->ErrLine = T ? T->Line : 0; P->ErrTok = T; } static Token *ExpectOp(Parser *P, const char *S) { Token *T = NextTok(P); if (!TokIsOp(T, S)) { SyntaxErrorAt(P, T, "expected operator"); return NULL; } return T; } static Token *ExpectName(Parser *P, const char *Value) { Token *T = NextTok(P); if (T->Kind != TK_NAME || (Value != NULL && !TokIsName(T, Value))) { SyntaxErrorAt(P, T, "expected name"); return NULL; } return T; } static int ExpectNEWLINE(Parser *P) { Token *T = NextTok(P); if (T->Kind != TK_NEWLINE) { SyntaxErrorAt(P, T, "expected newline"); return 0; } return 1; } /* ================= 节点构造辅助 ================= */ static PyObject *MakeCtx(Parser *P, const char *Name) { PyObject *Cls = ClassGet(P, Name); if (Cls == NULL) { return NULL; } return PyObject_Vectorcall(Cls, NULL, 0, NULL); } static PyObject *MakeSingleton(Parser *P, const char *Name) { PyObject *Cls = ClassGet(P, Name); if (Cls == NULL) { return NULL; } return PyObject_Vectorcall(Cls, NULL, 0, NULL); } static PyObject *NewList(void) { return PyList_New(0); } static int ListAppend(PyObject *List, PyObject *Item) { return PyList_Append(List, Item); } /* Name(id, ctx) 并设置位置 */ static PyObject *MakeNameNode(Parser *P, Token *T, const char *CtxName) { PyObject *Id = PyUnicode_FromStringAndSize(T->Start, T->End - T->Start); PyObject *Ctx = MakeCtx(P, CtxName); if (Id == NULL || Ctx == NULL) { Py_XDECREF(Id); Py_XDECREF(Ctx); return NULL; } PyObject *Argv[2] = { Id, Ctx }; PyObject *Node = NewNode(P, "Name", Argv, 2); Py_DECREF(Id); Py_DECREF(Ctx); if (Node != NULL) { FixLocEnd(P, Node, T, NULL); } return Node; } /* Constant(value, kind=None) */ static PyObject *MakeConstant(Parser *P, PyObject *Value) { PyObject *Argv[2] = { Value, Py_None }; return NewNode(P, "Constant", Argv, 2); } static PyObject *MakeConstantPos(Parser *P, PyObject *Value, Token *Start) { PyObject *N = MakeConstant(P, Value); if (N != NULL) { FixLocEnd(P, N, Start, NULL); } return N; } /* keyword(arg, value):arg 为 NULL 表示 **kwargs(arg=None) */ static PyObject *MakeKeyword(Parser *P, PyObject *Arg, PyObject *Value, Token *Start) { PyObject *Argv[2] = { Arg ? Arg : Py_None, Value }; PyObject *N = NewNode(P, "keyword", Argv, 2); if (N != NULL) { FixLoc(P, N, Start); } return N; } static PyObject *MakeStarred(Parser *P, PyObject *Value) { PyObject *Load = MakeCtx(P, "Load"); if (Load == NULL) { return NULL; } PyObject *Argv[2] = { Value, Load }; PyObject *N = NewNode(P, "Starred", Argv, 2); Py_DECREF(Load); return N; } /* Attribute(value, attr, Load) */ static PyObject *MakeAttrNode(Parser *P, PyObject *Value, Token *AttrTok, Token *Start) { PyObject *Attr = PyUnicode_FromStringAndSize(AttrTok->Start, AttrTok->End - AttrTok->Start); PyObject *Load = MakeCtx(P, "Load"); if (Attr == NULL || Load == NULL) { Py_XDECREF(Attr); Py_XDECREF(Load); return NULL; } PyObject *Argv[3] = { Value, Attr, Load }; PyObject *N = NewNode(P, "Attribute", Argv, 3); Py_DECREF(Attr); Py_DECREF(Load); if (N != NULL) { FixLoc(P, N, Start); } return N; } /* 替换节点 ctx 属性为指定上下文单例 */ static void ReplaceCtx(Parser *P, PyObject *Node, const char *CtxName) { PyObject *Ctx = MakeCtx(P, CtxName); if (Ctx == NULL) { return; } if (PyObject_SetAttrString(Node, "ctx", Ctx) < 0) { PyErr_Clear(); } Py_DECREF(Ctx); } static void SetStoreContext(Parser *P, PyObject *Node); static void SetDelContext(Parser *P, PyObject *Node); static void SetStoreContext(Parser *P, PyObject *Node) { const char *N = TypeName(Node); if (strcmp(N, "Attribute") == 0 || strcmp(N, "Subscript") == 0) { ReplaceCtx(P, Node, "Store"); } else if (strcmp(N, "Name") == 0) { ReplaceCtx(P, Node, "Store"); } else if (strcmp(N, "Tuple") == 0 || strcmp(N, "List") == 0) { ReplaceCtx(P, Node, "Store"); PyObject *Elts = PyObject_GetAttrString(Node, "elts"); if (Elts != NULL) { Py_ssize_t NElts = PyList_GET_SIZE(Elts); for (Py_ssize_t I = 0; I < NElts; I++) { SetStoreContext(P, PyList_GET_ITEM(Elts, I)); } Py_DECREF(Elts); } else { PyErr_Clear(); } } else if (strcmp(N, "Starred") == 0) { ReplaceCtx(P, Node, "Store"); PyObject *V = PyObject_GetAttrString(Node, "value"); if (V != NULL) { SetStoreContext(P, V); Py_DECREF(V); } else { PyErr_Clear(); } } } static void SetDelContext(Parser *P, PyObject *Node) { const char *N = TypeName(Node); if (strcmp(N, "Name") == 0 || strcmp(N, "Attribute") == 0 || strcmp(N, "Subscript") == 0) { ReplaceCtx(P, Node, "Del"); } else if (strcmp(N, "Tuple") == 0 || strcmp(N, "List") == 0) { ReplaceCtx(P, Node, "Del"); PyObject *Elts = PyObject_GetAttrString(Node, "elts"); if (Elts != NULL) { Py_ssize_t NElts = PyList_GET_SIZE(Elts); for (Py_ssize_t I = 0; I < NElts; I++) { SetDelContext(P, PyList_GET_ITEM(Elts, I)); } Py_DECREF(Elts); } else { PyErr_Clear(); } } } static int IsNameOrAttrOrSub(PyObject *Node) { const char *N = TypeName(Node); return strcmp(N, "Name") == 0 || strcmp(N, "Attribute") == 0 || strcmp(N, "Subscript") == 0; } static int NodeIsConstant(PyObject *Node) { return NodeIs(Node, "Constant"); } /* ================= 数字 / 字符串字面量 ================= */ /* 解析数字 token 为 Python 数值对象(对齐 vast _ParseNumber) */ static PyObject *ParseNumberValue(Parser *P, Token *T) { Py_ssize_t Len = T->End - T->Start; char *Buf = (char *)PyMem_Malloc((size_t)Len + 1); if (Buf == NULL) { return NULL; } Py_ssize_t N = 0; for (Py_ssize_t I = 0; I < Len; I++) { if (T->Start[I] != '_') { Buf[N++] = T->Start[I]; } } Buf[N] = '\0'; PyObject *Result = NULL; if (N > 0 && (Buf[N - 1] == 'j' || Buf[N - 1] == 'J')) { /* 复数:去掉 j,实部按 float 解析 */ Buf[N - 1] = '\0'; PyObject *RealStr = PyUnicode_FromStringAndSize(Buf, (Py_ssize_t)strlen(Buf)); if (RealStr != NULL) { PyObject *Real = PyFloat_FromString(RealStr); Py_DECREF(RealStr); if (Real != NULL) { Result = PyComplex_FromDoubles(PyFloat_AS_DOUBLE(Real), 0.0); Py_DECREF(Real); } } } else if (N >= 2 && Buf[0] == '0' && (Buf[1] == 'x' || Buf[1] == 'X' || Buf[1] == 'o' || Buf[1] == 'O' || Buf[1] == 'b' || Buf[1] == 'B')) { Result = PyLong_FromString(Buf, NULL, 0); if (Result == NULL) { PyErr_Clear(); } } else { int IsFloat = 0; for (Py_ssize_t I = 0; I < N; I++) { if (Buf[I] == '.' || Buf[I] == 'e' || Buf[I] == 'E') { IsFloat = 1; break; } } if (IsFloat) { PyObject *S = PyUnicode_FromStringAndSize(Buf, N); if (S != NULL) { Result = PyFloat_FromString(S); Py_DECREF(S); } if (Result == NULL) { PyErr_Clear(); } } else { Result = PyLong_FromString(Buf, NULL, 10); if (Result == NULL) { PyErr_Clear(); } } } if (Result == NULL) { /* 无法解析:保留原字符串(对齐 vast 的 except ValueError 分支) */ Result = PyUnicode_FromStringAndSize(T->Start, Len); } PyMem_Free(Buf); return Result; } /* UTF-8 解码一个字符到 UCS4,返回字节数 */ static int UTF8CharDecode(const char *S, Py_ssize_t N, Py_UCS4 *Out) { unsigned char C = (unsigned char)S[0]; if (C < 0x80) { *Out = C; return 1; } if (C < 0xC0 || N < 2) { *Out = C; return 1; } if (C < 0xE0) { *Out = ((C & 0x1F) << 6) | ((unsigned char)S[1] & 0x3F); return 2; } if (C < 0xF0 && N >= 3) { *Out = ((C & 0x0F) << 12) | (((unsigned char)S[1] & 0x3F) << 6) | ((unsigned char)S[2] & 0x3F); return 3; } if (N >= 4) { *Out = ((C & 0x07) << 18) | (((unsigned char)S[1] & 0x3F) << 12) | (((unsigned char)S[2] & 0x3F) << 6) | ((unsigned char)S[3] & 0x3F); return 4; } *Out = C; return 1; } static int HexVal(char C) { if (C >= '0' && C <= '9') return C - '0'; if (C >= 'a' && C <= 'f') return C - 'a' + 10; if (C >= 'A' && C <= 'F') return C - 'A' + 10; return 0; } /* 解码字符串转义序列(对齐 vast _DecodeEscapes) */ static PyObject *DecodeEscapes(Parser *P, const char *Body, Py_ssize_t Len, int IsRaw) { if (IsRaw) { return PyUnicode_DecodeUTF8(Body, Len, NULL); } Py_UCS4 *Buf = (Py_UCS4 *)PyMem_Malloc((size_t)(Len * 4 + 4) * sizeof(Py_UCS4)); if (Buf == NULL) { return NULL; } Py_ssize_t NBuf = 0; Py_ssize_t I = 0; while (I < Len) { unsigned char Ch = (unsigned char)Body[I]; if (Ch != '\\') { Py_UCS4 Cp; int NB = UTF8CharDecode(Body + I, Len - I, &Cp); Buf[NBuf++] = Cp; I += NB; continue; } I++; if (I >= Len) { Buf[NBuf++] = '\\'; break; } char Esc = Body[I]; switch (Esc) { case '\\': Buf[NBuf++] = '\\'; I++; break; case '\'': Buf[NBuf++] = '\''; I++; break; case '"': Buf[NBuf++] = '"'; I++; break; case 'n': Buf[NBuf++] = '\n'; I++; break; case 't': Buf[NBuf++] = '\t'; I++; break; case 'r': Buf[NBuf++] = '\r'; I++; break; case 'b': Buf[NBuf++] = '\b'; I++; break; case 'f': Buf[NBuf++] = '\f'; I++; break; case 'v': Buf[NBuf++] = '\v'; I++; break; case 'a': Buf[NBuf++] = '\a'; I++; break; case 'x': { int V = HexVal(I + 1 < Len ? Body[I + 1] : '0') * 16 + HexVal(I + 2 < Len ? Body[I + 2] : '0'); Buf[NBuf++] = V; I += 3; break; } case 'u': { int V = 0; for (int K = 1; K <= 4; K++) { V = V * 16 + HexVal(I + K < Len ? Body[I + K] : '0'); } Buf[NBuf++] = V; I += 5; break; } case 'U': { int V = 0; for (int K = 1; K <= 8; K++) { V = V * 16 + HexVal(I + K < Len ? Body[I + K] : '0'); } Buf[NBuf++] = V; I += 9; break; } default: if (Esc >= '0' && Esc <= '7') { int J = 0; int V = 0; while (J < 3 && I + J < Len && Body[I + J] >= '0' && Body[I + J] <= '7') { V = V * 8 + (Body[I + J] - '0'); J++; } Buf[NBuf++] = V; I += J; } else { Buf[NBuf++] = '\\'; Buf[NBuf++] = (Py_UCS4)(unsigned char)Esc; I++; } } } PyObject *R = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, Buf, NBuf); PyMem_Free(Buf); return R; } /* 解码 bytes 字面量(对齐 vast _DecodeBytes) */ static PyObject *DecodeBytes(Parser *P, const char *Body, Py_ssize_t Len, int IsRaw) { if (IsRaw) { return PyBytes_FromStringAndSize(Body, Len); } char *Buf = (char *)PyMem_Malloc((size_t)(Len * 4 + 4)); if (Buf == NULL) { return NULL; } Py_ssize_t NBuf = 0; Py_ssize_t I = 0; while (I < Len) { unsigned char Ch = (unsigned char)Body[I]; if (Ch != '\\') { Buf[NBuf++] = Ch; I++; continue; } I++; if (I >= Len) { Buf[NBuf++] = '\\'; break; } char Esc = Body[I]; switch (Esc) { case '\\': Buf[NBuf++] = '\\'; I++; break; case '\'': Buf[NBuf++] = '\''; I++; break; case '"': Buf[NBuf++] = '"'; I++; break; case 'n': Buf[NBuf++] = 10; I++; break; case 't': Buf[NBuf++] = 9; I++; break; case 'r': Buf[NBuf++] = 13; I++; break; case 'b': Buf[NBuf++] = 8; I++; break; case 'f': Buf[NBuf++] = 12; I++; break; case 'v': Buf[NBuf++] = 11; I++; break; case 'a': Buf[NBuf++] = 7; I++; break; case 'x': { int V = HexVal(I + 1 < Len ? Body[I + 1] : '0') * 16 + HexVal(I + 2 < Len ? Body[I + 2] : '0'); Buf[NBuf++] = (char)V; I += 3; break; } case 'u': { int V = 0; for (int K = 1; K <= 4; K++) { V = V * 16 + HexVal(I + K < Len ? Body[I + K] : '0'); } Buf[NBuf++] = (char)V; I += 5; break; } case 'U': { int V = 0; for (int K = 1; K <= 8; K++) { V = V * 16 + HexVal(I + K < Len ? Body[I + K] : '0'); } Buf[NBuf++] = (char)V; I += 9; break; } default: if (Esc >= '0' && Esc <= '7') { int J = 0; int V = 0; while (J < 3 && I + J < Len && Body[I + J] >= '0' && Body[I + J] <= '7') { V = V * 8 + (Body[I + J] - '0'); J++; } Buf[NBuf++] = (char)V; I += J; } else { Buf[NBuf++] = '\\'; Buf[NBuf++] = (unsigned char)Esc; I++; } } } PyObject *R = PyBytes_FromStringAndSize(Buf, NBuf); PyMem_Free(Buf); return R; } /* 解码字符串 token 原始文本为实际值(str 或 bytes) */ static PyObject *DecodeString(Parser *P, Token *T) { const char *Raw = T->Start; Py_ssize_t Len = T->End - T->Start; Py_ssize_t I = 0; while (I < Len && IsStringPrefixChar((unsigned char)Raw[I])) { I++; } char Quote = Raw[I]; int Triple = (I + 2 < Len && Raw[I] == Quote && Raw[I + 1] == Quote && Raw[I + 2] == Quote); Py_ssize_t BodyStart = I + (Triple ? 3 : 1); Py_ssize_t BodyEnd = Len - (Triple ? 3 : 1); int IsRaw = 0; int IsBytes = 0; for (Py_ssize_t K = 0; K < I; K++) { char C = Raw[K]; if (C == 'r' || C == 'R') IsRaw = 1; if (C == 'b' || C == 'B') IsBytes = 1; } if (IsBytes) { return DecodeBytes(P, Raw + BodyStart, BodyEnd - BodyStart, IsRaw); } return DecodeEscapes(P, Raw + BodyStart, BodyEnd - BodyStart, IsRaw); } /* 拼接字符串字面量值(对齐 vast _JoinConstParts) */ static PyObject *JoinConstParts(PyObject *Parts) { Py_ssize_t N = PyList_GET_SIZE(Parts); if (N == 0) { return PyUnicode_FromString(""); } PyObject *First = PyList_GET_ITEM(Parts, 0); if (PyBytes_Check(First)) { PyObject *Acc = PyBytes_FromStringAndSize(NULL, 0); for (Py_ssize_t I = 0; I < N; I++) { PyObject *Part = PyList_GET_ITEM(Parts, I); PyObject *Bytes = PyBytes_Check(Part) ? Part : PyUnicode_AsUTF8String(Part); if (Bytes == NULL) { Py_DECREF(Acc); return NULL; } PyObject *NewAcc = PySequence_Concat(Acc, Bytes); if (Bytes != Part) { Py_DECREF(Bytes); } Py_DECREF(Acc); if (NewAcc == NULL) { return NULL; } Acc = NewAcc; } return Acc; } PyObject *Sep = PyUnicode_FromString(""); if (Sep == NULL) { return NULL; } PyObject *Joined = PyUnicode_Join(Sep, Parts); Py_DECREF(Sep); return Joined; } /* ================= 表达式解析 ================= */ static PyObject *MakeTAttrNode(Parser *P, const char *AttrName); static PyObject *ParseExpr(Parser *P); static PyObject *ParseConditional(Parser *P); static PyObject *ParseDisjunction(Parser *P); static PyObject *ParseConjunction(Parser *P); static PyObject *ParseInversion(Parser *P); static PyObject *ParseComparison(Parser *P); static PyObject *ParseBitOr(Parser *P); static PyObject *ParseBitXor(Parser *P); static PyObject *ParseBitAnd(Parser *P); static PyObject *ParseShift(Parser *P); static PyObject *ParseArith(Parser *P); static PyObject *ParseTerm(Parser *P); static PyObject *ParseFactor(Parser *P); static PyObject *ParsePower(Parser *P); static PyObject *ParseAwaitPrimary(Parser *P); static PyObject *ParsePrimary(Parser *P); static PyObject *ParseAtom(Parser *P); static PyObject *ParseNumber(Parser *P); static PyObject *ParseStringConcat(Parser *P); static PyObject *ParseParen(Parser *P); static PyObject *ParseList(Parser *P); static PyObject *ParseDictSet(Parser *P); static PyObject *ParseYield(Parser *P); static PyObject *ParseLambda(Parser *P); static PyObject *ParseArguments(Parser *P, int SkipOpen, int AllowLambda); static PyObject *ParseArg(Parser *P, int AllowAnnotation); static PyObject *ParseTarget(Parser *P); static PyObject *ParseComprehensionTarget(Parser *P); static PyObject *ParseComprehensionGenerators(Parser *P); /* ============ 字符串拼接与 f-string ============ */ static PyObject *ParseFStringToken(Parser *P, Token *Tok); static PyObject *ParseFStringBodyEx(Parser *P, const char *Raw, int RawLen, Token *OuterTok, int BaseOffset); static PyObject *ParseFStringValue(Parser *P, const char *Raw, int BodyStart, int Start, int BodyEnd, Token *OuterTok, int RelBase); static PyObject *ParseSubExpression(Parser *P, const char *Text, Py_ssize_t TextLen, int AbsBase); static int SkipInnerLiteral(const char *Raw, int BodyStart, int Start, int BodyEnd); /* f-string 相邻字面量合并常量(仅 lineno/col_offset,对齐 vast) */ static PyObject *MakeFStrConstant(Parser *P, PyObject *Value, Token *OuterTok) { PyObject *N = MakeConstant(P, Value); if (N != NULL) { NodePosNoEnd(P, N, OuterTok->Line, OuterTok->Col); } return N; } /* 合并常量:位置取被合并的前一个 Constant 节点(对齐 Python 的 parts[-1].lineno/col_offset)。 */ static PyObject *MakeFStrConstantLike(Parser *P, PyObject *Value, PyObject *SrcNode) { PyObject *N = MakeConstant(P, Value); if (N == NULL) { return NULL; } PyObject *Line = PyObject_GetAttrString(SrcNode, "lineno"); PyObject *Col = PyObject_GetAttrString(SrcNode, "col_offset"); if (Line != NULL) { PyObject_SetAttrString(N, "lineno", Line); } if (Col != NULL) { PyObject_SetAttrString(N, "col_offset", Col); } Py_XDECREF(Line); Py_XDECREF(Col); PyErr_Clear(); return N; } static PyObject *ParseStringConcat(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *Parts = NewList(); /* JoinedStr 的 values */ PyObject *ConstParts = NewList(); /* 普通字符串字面量值 */ int HasFString = 0; if (Parts == NULL || ConstParts == NULL) { Py_XDECREF(Parts); Py_XDECREF(ConstParts); return NULL; } for (;;) { SkipNL(P); Token *Tok = PeekTok(P, 0); if (Tok->Kind == TK_STRING) { NextTok(P); PyObject *Val = DecodeString(P, Tok); if (Val == NULL) { Py_DECREF(Parts); Py_DECREF(ConstParts); return NULL; } PyList_Append(ConstParts, Val); Py_DECREF(Val); } else if (Tok->Kind == TK_FSTRING) { NextTok(P); PyObject *Joined = ParseFStringToken(P, Tok); if (Joined == NULL) { Py_DECREF(Parts); Py_DECREF(ConstParts); return NULL; } HasFString = 1; if (PyList_GET_SIZE(ConstParts) > 0) { PyObject *JoinedStr = JoinConstParts(ConstParts); if (JoinedStr == NULL) { Py_DECREF(Joined); Py_DECREF(Parts); Py_DECREF(ConstParts); return NULL; } PyObject *C = MakeFStrConstant(P, JoinedStr, Start); Py_DECREF(JoinedStr); if (C == NULL) { Py_DECREF(Joined); Py_DECREF(Parts); Py_DECREF(ConstParts); return NULL; } PyList_Append(Parts, C); Py_DECREF(C); PyList_SetSlice(ConstParts, 0, PyList_GET_SIZE(ConstParts), NULL); } PyObject *JVals = PyObject_GetAttrString(Joined, "values"); if (JVals == NULL) { Py_DECREF(Joined); Py_DECREF(Parts); Py_DECREF(ConstParts); return NULL; } /* 相邻 Constant 合并(f-string 字面量 + 后续常量段) */ if (PyList_GET_SIZE(Parts) > 0 && NodeIsConstant(PyList_GET_ITEM(Parts, PyList_GET_SIZE(Parts) - 1)) && PyList_GET_SIZE(JVals) > 0 && NodeIsConstant(PyList_GET_ITEM(JVals, 0))) { PyObject *Last = PyList_GET_ITEM(Parts, PyList_GET_SIZE(Parts) - 1); PyObject *LastVal = PyObject_GetAttrString(Last, "value"); PyObject *FirstVal = PyObject_GetAttrString(PyList_GET_ITEM(JVals, 0), "value"); if (LastVal == NULL || FirstVal == NULL) { Py_XDECREF(LastVal); Py_XDECREF(FirstVal); Py_DECREF(JVals); Py_DECREF(Joined); Py_DECREF(Parts); Py_DECREF(ConstParts); return NULL; } PyObject *S1 = PyObject_Str(LastVal); PyObject *S2 = PyObject_Str(FirstVal); Py_DECREF(LastVal); Py_DECREF(FirstVal); PyObject *Merged = NULL; if (S1 != NULL && S2 != NULL) { Merged = PyUnicode_Concat(S1, S2); } Py_XDECREF(S1); Py_XDECREF(S2); if (Merged == NULL) { Py_DECREF(JVals); Py_DECREF(Joined); Py_DECREF(Parts); Py_DECREF(ConstParts); return NULL; } PyObject *MergedConst = MakeFStrConstantLike(P, Merged, Last); Py_DECREF(Merged); if (MergedConst == NULL) { Py_DECREF(JVals); Py_DECREF(Joined); Py_DECREF(Parts); Py_DECREF(ConstParts); return NULL; } PyList_SetItem(Parts, PyList_GET_SIZE(Parts) - 1, MergedConst); /* 偷取 */ PyObject *Val; for (Py_ssize_t I = 1; I < PyList_GET_SIZE(JVals); I++) { Val = PyList_GET_ITEM(JVals, I); PyList_Append(Parts, Val); } } else { PyObject *Val; for (Py_ssize_t I = 0; I < PyList_GET_SIZE(JVals); I++) { Val = PyList_GET_ITEM(JVals, I); PyList_Append(Parts, Val); } } Py_DECREF(JVals); Py_DECREF(Joined); } else { break; } } if (!HasFString) { PyObject *Val = JoinConstParts(ConstParts); Py_DECREF(ConstParts); if (Val == NULL) { Py_DECREF(Parts); return NULL; } PyObject *Node = MakeConstantPos(P, Val, Start); Py_DECREF(Val); Py_DECREF(Parts); return Node; } if (PyList_GET_SIZE(ConstParts) > 0) { if (PyList_GET_SIZE(Parts) > 0 && NodeIsConstant(PyList_GET_ITEM(Parts, PyList_GET_SIZE(Parts) - 1))) { PyObject *Last = PyList_GET_ITEM(Parts, PyList_GET_SIZE(Parts) - 1); PyObject *LastVal = PyObject_GetAttrString(Last, "value"); PyObject *TailVal = JoinConstParts(ConstParts); if (LastVal == NULL || TailVal == NULL) { Py_XDECREF(LastVal); Py_XDECREF(TailVal); Py_DECREF(Parts); Py_DECREF(ConstParts); return NULL; } PyObject *S1 = PyObject_Str(LastVal); PyObject *S2 = PyObject_Str(TailVal); Py_DECREF(LastVal); Py_DECREF(TailVal); PyObject *Merged = NULL; if (S1 != NULL && S2 != NULL) { Merged = PyUnicode_Concat(S1, S2); } Py_XDECREF(S1); Py_XDECREF(S2); if (Merged == NULL) { Py_DECREF(Parts); Py_DECREF(ConstParts); return NULL; } PyObject *MergedConst = MakeFStrConstantLike(P, Merged, Last); Py_DECREF(Merged); if (MergedConst == NULL) { Py_DECREF(Parts); Py_DECREF(ConstParts); return NULL; } PyList_SetItem(Parts, PyList_GET_SIZE(Parts) - 1, MergedConst); /* 偷取 */ } else { PyObject *TailVal = JoinConstParts(ConstParts); if (TailVal == NULL) { Py_DECREF(Parts); Py_DECREF(ConstParts); return NULL; } PyObject *C = MakeFStrConstant(P, TailVal, Start); Py_DECREF(TailVal); if (C == NULL) { Py_DECREF(Parts); Py_DECREF(ConstParts); return NULL; } PyList_Append(Parts, C); Py_DECREF(C); } } Py_DECREF(ConstParts); PyObject *Argv[1] = { Parts }; PyObject *Node = NewNode(P, "JoinedStr", Argv, 1); Py_DECREF(Parts); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 解析 FSTRING token 为 JoinedStr */ static PyObject *ParseFStringToken(Parser *P, Token *Tok) { PyObject *Values = ParseFStringBodyEx(P, Tok->Start, (int)(Tok->End - Tok->Start), Tok, 0); if (Values == NULL) { return NULL; } PyObject *Argv[1] = { Values }; PyObject *Node = NewNode(P, "JoinedStr", Argv, 1); Py_DECREF(Values); if (Node != NULL) { NodePos(P, Node, Tok->Line, Tok->Col, Tok->EndLine, Tok->EndCol); } return Node; } /* 基于原始文本的 f-string body 解析(完整实现)。 * 返回 values 列表;BaseOffset 用于嵌套(本实现仅顶层使用)。 */ static PyObject *ParseFStringBodyEx(Parser *P, const char *Raw, int RawLen, Token *OuterTok, int BaseOffset); /* 字面文本暂存(字节缓冲) */ typedef struct { char *Buf; Py_ssize_t Len; Py_ssize_t Cap; } LitBuf; static int LitAppend(LitBuf *Lb, const char *S, Py_ssize_t N) { if (Lb->Len + N > Lb->Cap) { Py_ssize_t NCap = Lb->Cap ? Lb->Cap * 2 : 64; while (NCap < Lb->Len + N) { NCap *= 2; } char *NB = (char *)PyMem_Realloc(Lb->Buf, (size_t)NCap); if (NB == NULL) { return 0; } Lb->Buf = NB; Lb->Cap = NCap; } memcpy(Lb->Buf + Lb->Len, S, (size_t)N); Lb->Len += N; return 1; } static PyObject *ParseFStringBodyEx(Parser *P, const char *Raw, int RawLen, Token *OuterTok, int BaseOffset) { (void)BaseOffset; int I = 0; while (I < RawLen && IsStringPrefixChar((unsigned char)Raw[I])) { I++; } char Quote = Raw[I]; int Triple = (I + 2 < RawLen && Raw[I] == Quote && Raw[I + 1] == Quote && Raw[I + 2] == Quote); int IsRaw = 0; for (int K = 0; K < I; K++) { if (Raw[K] == 'r' || Raw[K] == 'R') IsRaw = 1; } int BodyStart = I + (Triple ? 3 : 1); int BodyEnd = RawLen - (Triple ? 3 : 1); PyObject *Values = NewList(); if (Values == NULL) { return NULL; } LitBuf Lb; memset(&Lb, 0, sizeof(Lb)); int J = 0; int RelBase = BodyStart; while (J < BodyEnd - BodyStart) { char Ch = Raw[BodyStart + J]; if (Ch == '{') { if (J + 1 < BodyEnd - BodyStart && Raw[BodyStart + J + 1] == '{') { if (!LitAppend(&Lb, "{", 1)) { Py_DECREF(Values); PyMem_Free(Lb.Buf); return NULL; } J += 2; continue; } if (Lb.Len > 0) { PyObject *Str = DecodeEscapes(P, Lb.Buf, Lb.Len, IsRaw); Lb.Len = 0; if (Str == NULL) { Py_DECREF(Values); PyMem_Free(Lb.Buf); return NULL; } PyObject *C = MakeFStrConstant(P, Str, OuterTok); Py_DECREF(Str); if (C == NULL) { Py_DECREF(Values); PyMem_Free(Lb.Buf); return NULL; } PyList_Append(Values, C); Py_DECREF(C); } PyObject *Fv = ParseFStringValue(P, Raw, BodyStart, J, BodyEnd, OuterTok, RelBase); if (Fv == NULL) { Py_DECREF(Values); PyMem_Free(Lb.Buf); return NULL; } PyList_Append(Values, Fv); Py_DECREF(Fv); J = P->FStringExprEnd; continue; } else if (Ch == '}') { if (J + 1 < BodyEnd - BodyStart && Raw[BodyStart + J + 1] == '}') { if (!LitAppend(&Lb, "}", 1)) { Py_DECREF(Values); PyMem_Free(Lb.Buf); return NULL; } J += 2; continue; } /* 单独的 } 宽松处理为字面量 */ if (!LitAppend(&Lb, "}", 1)) { Py_DECREF(Values); PyMem_Free(Lb.Buf); return NULL; } J += 1; continue; } else { Py_UCS4 Cp; int NB = UTF8CharDecode(Raw + BodyStart + J, BodyEnd - BodyStart - J, &Cp); char Tmp[4]; int TN; if (Cp < 0x80) { Tmp[0] = (char)Cp; TN = 1; } else if (Cp < 0x800) { Tmp[0] = (char)(0xC0 | (Cp >> 6)); Tmp[1] = (char)(0x80 | (Cp & 0x3F)); TN = 2; } else if (Cp < 0x10000) { Tmp[0] = (char)(0xE0 | (Cp >> 12)); Tmp[1] = (char)(0x80 | ((Cp >> 6) & 0x3F)); Tmp[2] = (char)(0x80 | (Cp & 0x3F)); TN = 3; } else { Tmp[0] = (char)(0xF0 | (Cp >> 18)); Tmp[1] = (char)(0x80 | ((Cp >> 12) & 0x3F)); Tmp[2] = (char)(0x80 | ((Cp >> 6) & 0x3F)); Tmp[3] = (char)(0x80 | (Cp & 0x3F)); TN = 4; } if (!LitAppend(&Lb, Tmp, TN)) { Py_DECREF(Values); PyMem_Free(Lb.Buf); return NULL; } J += NB; continue; } } if (Lb.Len > 0) { PyObject *Str = DecodeEscapes(P, Lb.Buf, Lb.Len, IsRaw); if (Str == NULL) { Py_DECREF(Values); PyMem_Free(Lb.Buf); return NULL; } PyObject *C = MakeFStrConstant(P, Str, OuterTok); Py_DECREF(Str); if (C == NULL) { Py_DECREF(Values); PyMem_Free(Lb.Buf); return NULL; } PyList_Append(Values, C); Py_DECREF(C); } PyMem_Free(Lb.Buf); return Values; } /* 解析单个 {expr[!conv][:spec]} 段,返回 FormattedValue;结束位置存入 P->FStringExprEnd */ static PyObject *ParseFStringValue(Parser *P, const char *Raw, int BodyStart, int Start, int BodyEnd, Token *OuterTok, int RelBase) { int J = Start + 1; /* 跳过 { */ int Depth = 1; int ExprStart = J; int ExprEnd = J; char StopChar = '}'; while (J < BodyEnd) { char Ch = Raw[BodyStart + J]; if (Ch == '\\') { J += 2; continue; } if (Ch == '\'' || Ch == '"') { J = SkipInnerLiteral(Raw, BodyStart, J, BodyEnd); continue; } if (Ch == '(' || Ch == '[' || Ch == '{') { Depth++; J++; continue; } if (Ch == ')' || Ch == ']' || Ch == '}') { if (Depth == 1) { ExprEnd = J; J++; break; } Depth--; J++; continue; } if (Depth == 1 && (Ch == '!' || Ch == ':')) { ExprEnd = J; StopChar = Ch; break; } J++; } P->FStringExprEnd = J; int Conversion = -1; PyObject *FormatSpec = NULL; int K = J; if (StopChar == '!') { K++; if (K < BodyEnd && (Raw[BodyStart + K] == 'r' || Raw[BodyStart + K] == 's' || Raw[BodyStart + K] == 'a')) { Conversion = (unsigned char)Raw[BodyStart + K]; K++; } if (K < BodyEnd && Raw[BodyStart + K] == ':') { StopChar = ':'; } else { if (K < BodyEnd && Raw[BodyStart + K] == '}') { K++; } P->FStringExprEnd = K; } } if (StopChar == ':') { K++; int SpecStart = K; int Depth2 = 1; while (K < BodyEnd) { char C2 = Raw[BodyStart + K]; if (C2 == '{') { Depth2++; K++; } else if (C2 == '}') { Depth2--; if (Depth2 == 0) { break; } K++; } else { K++; } } int HasNested = 0; for (int I2 = SpecStart; I2 < K; I2++) { if (Raw[BodyStart + I2] == '{') { HasNested = 1; break; } } if (HasNested) { /* 嵌套表达式:构造内层 f-string 文本并递归解析 */ Py_ssize_t SpecLen = K - SpecStart; char *Inner = (char *)PyMem_Malloc((size_t)(SpecLen * 2 + 4)); if (Inner == NULL) { return NULL; } Py_ssize_t NI = 0; Inner[NI++] = 'f'; Inner[NI++] = '"'; for (int I2 = SpecStart; I2 < K; I2++) { char C2 = Raw[BodyStart + I2]; if (C2 == '"') { Inner[NI++] = '\\'; } Inner[NI++] = C2; } Inner[NI++] = '"'; Token InnerTok; InnerTok.Kind = TK_FSTRING; InnerTok.Start = Inner; InnerTok.End = Inner + NI; InnerTok.Line = OuterTok->Line; InnerTok.Col = OuterTok->Col; InnerTok.EndLine = OuterTok->EndLine; InnerTok.EndCol = OuterTok->EndCol; InnerTok.StartOff = OuterTok->StartOff; InnerTok.EndOff = OuterTok->EndOff; FormatSpec = ParseFStringToken(P, &InnerTok); PyMem_Free(Inner); if (FormatSpec == NULL) { return NULL; } } else { PyObject *SpecStr = PyUnicode_FromStringAndSize(Raw + BodyStart + SpecStart, K - SpecStart); if (SpecStr == NULL) { return NULL; } PyObject *C = MakeFStrConstant(P, SpecStr, OuterTok); Py_DECREF(SpecStr); if (C == NULL) { return NULL; } PyObject *JVals = NewList(); if (JVals == NULL) { Py_DECREF(C); return NULL; } PyList_Append(JVals, C); Py_DECREF(C); PyObject *Argv[1] = { JVals }; FormatSpec = NewNode(P, "JoinedStr", Argv, 1); Py_DECREF(JVals); if (FormatSpec == NULL) { return NULL; } } if (K < BodyEnd && Raw[BodyStart + K] == '}') { K++; } P->FStringExprEnd = K; } /* 解析子表达式并重定位 */ PyObject *ExprNode = ParseSubExpression(P, Raw + BodyStart + ExprStart, ExprEnd - ExprStart, OuterTok->StartOff + RelBase + ExprStart); if (ExprNode == NULL) { Py_XDECREF(FormatSpec); return NULL; } PyObject *Argv[3]; Argv[0] = ExprNode; Argv[1] = PyLong_FromLong(Conversion); Argv[2] = FormatSpec ? FormatSpec : Py_None; PyObject *Fv = NewNode(P, "FormattedValue", Argv, 3); Py_XDECREF(Argv[1]); Py_XDECREF(FormatSpec); Py_DECREF(ExprNode); if (Fv == NULL) { return NULL; } NodePos(P, Fv, OuterTok->Line, OuterTok->Col, OuterTok->EndLine, OuterTok->EndCol); return Fv; } /* 跳过 f-string 表达式内部的字符串字面量 */ static int SkipInnerLiteral(const char *Raw, int BodyStart, int Start, int BodyEnd) { int J = Start; while (J < BodyEnd && IsStringPrefixChar((unsigned char)Raw[BodyStart + J])) { J++; } if (J >= BodyEnd || (Raw[BodyStart + J] != '\'' && Raw[BodyStart + J] != '"')) { return Start + 1; } char Quote = Raw[BodyStart + J]; int Triple = (J + 2 < BodyEnd && Raw[BodyStart + J] == Quote && Raw[BodyStart + J + 1] == Quote && Raw[BodyStart + J + 2] == Quote); J += Triple ? 3 : 1; while (J < BodyEnd) { char Ch = Raw[BodyStart + J]; if (Ch == '\\') { J += 2; continue; } if (Ch == Quote) { if (Triple) { if (J + 2 < BodyEnd && Raw[BodyStart + J] == Quote && Raw[BodyStart + J + 1] == Quote && Raw[BodyStart + J + 2] == Quote) { J += 3; return J; } J += 1; } else { J += 1; return J; } } J++; } return J; } /* 解析 f-string 子表达式文本(重新 tokenize 并重定位到绝对偏移) */ static PyObject *ParseSubExpression(Parser *P, const char *Text, Py_ssize_t TextLen, int AbsBase) { Token *SubToks = NULL; int NSub = 0; if (!TokenizeText(Text, TextLen, &SubToks, &NSub, NULL, NULL)) { return NULL; } for (int I = 0; I < NSub; I++) { Token *T = &SubToks[I]; T->StartOff += AbsBase; T->EndOff += AbsBase; PosInfoLS(P->LineStarts, P->NLineStarts, T->StartOff, &T->Line, &T->Col); PosInfoLS(P->LineStarts, P->NLineStarts, T->EndOff, &T->EndLine, &T->EndCol); } int SavedIdx = P->Idx; Token *SavedTokens = P->Tokens; int SavedNTokens = P->NTokens; P->Tokens = SubToks; P->NTokens = NSub; P->Idx = 0; PyObject *Expr = ParseExpr(P); P->Tokens = SavedTokens; P->NTokens = SavedNTokens; P->Idx = SavedIdx; PyMem_Free(SubToks); return Expr; } /* ================= 表达式(优先级链) ================= */ /* 完整表达式:lambda 或条件表达式 */ static PyObject *ParseExpr(Parser *P) { if (AtName(P, "lambda")) { return ParseLambda(P); } return ParseConditional(P); } /* testlist_star_expr:表达式或逗号分隔元组 */ static PyObject *ParseExprList(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *First = ParseExpr(P); if (First == NULL) { return NULL; } if (!AtOp(P, ",")) { return First; } PyObject *Elts = NewList(); if (Elts == NULL) { Py_DECREF(First); return NULL; } PyList_Append(Elts, First); while (AtOp(P, ",")) { NextTok(P); SkipNL(P); PyObject *E = ParseExpr(P); if (E == NULL) { Py_DECREF(Elts); Py_DECREF(First); return NULL; } PyList_Append(Elts, E); Py_DECREF(E); } Py_DECREF(First); PyObject *Load = MakeCtx(P, "Load"); if (Load == NULL) { Py_DECREF(Elts); return NULL; } PyObject *Argv[2] = { Elts, Load }; PyObject *Node = NewNode(P, "Tuple", Argv, 2); Py_DECREF(Elts); Py_DECREF(Load); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 条件表达式:disjunction ('if' disjunction 'else' expression)? */ static PyObject *ParseConditional(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *Body = ParseDisjunction(P); if (Body == NULL) { return NULL; } if (!AtName(P, "if")) { return Body; } NextTok(P); PyObject *Test = ParseDisjunction(P); if (Test == NULL) { Py_DECREF(Body); return NULL; } if (!AtName(P, "else")) { Py_DECREF(Body); Py_DECREF(Test); SyntaxErrorAt(P, PeekTok(P, 0), "expected 'else'"); return NULL; } NextTok(P); PyObject *Orelse = ParseExpr(P); if (Orelse == NULL) { Py_DECREF(Body); Py_DECREF(Test); return NULL; } PyObject *Argv[3] = { Test, Body, Orelse }; PyObject *Node = NewNode(P, "IfExp", Argv, 3); Py_DECREF(Test); Py_DECREF(Body); Py_DECREF(Orelse); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* disjunction:conjunction ('or' conjunction)* */ static PyObject *ParseDisjunction(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *Values = NewList(); if (Values == NULL) { return NULL; } PyObject *First = ParseConjunction(P); if (First == NULL) { Py_DECREF(Values); return NULL; } PyList_Append(Values, First); Py_DECREF(First); for (;;) { SkipNL(P); if (!AtName(P, "or")) { break; } NextTok(P); PyObject *V = ParseConjunction(P); if (V == NULL) { Py_DECREF(Values); return NULL; } PyList_Append(Values, V); Py_DECREF(V); } if (PyList_GET_SIZE(Values) == 1) { PyObject *Only = PyList_GET_ITEM(Values, 0); Py_INCREF(Only); Py_DECREF(Values); return Only; } PyObject *Op = MakeSingleton(P, "Or"); if (Op == NULL) { Py_DECREF(Values); return NULL; } PyObject *Argv[2] = { Op, Values }; PyObject *Node = NewNode(P, "BoolOp", Argv, 2); Py_DECREF(Op); Py_DECREF(Values); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* conjunction:inversion ('and' inversion)* */ static PyObject *ParseConjunction(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *Values = NewList(); if (Values == NULL) { return NULL; } PyObject *First = ParseInversion(P); if (First == NULL) { Py_DECREF(Values); return NULL; } PyList_Append(Values, First); Py_DECREF(First); for (;;) { SkipNL(P); if (!AtName(P, "and")) { break; } NextTok(P); PyObject *V = ParseInversion(P); if (V == NULL) { Py_DECREF(Values); return NULL; } PyList_Append(Values, V); Py_DECREF(V); } if (PyList_GET_SIZE(Values) == 1) { PyObject *Only = PyList_GET_ITEM(Values, 0); Py_INCREF(Only); Py_DECREF(Values); return Only; } PyObject *Op = MakeSingleton(P, "And"); if (Op == NULL) { Py_DECREF(Values); return NULL; } PyObject *Argv[2] = { Op, Values }; PyObject *Node = NewNode(P, "BoolOp", Argv, 2); Py_DECREF(Op); Py_DECREF(Values); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* inversion:'not' inversion | comparison */ static PyObject *ParseInversion(Parser *P) { SkipNL(P); if (AtName(P, "not")) { Token *Start = NextTok(P); PyObject *Operand = ParseInversion(P); if (Operand == NULL) { return NULL; } PyObject *Op = MakeSingleton(P, "Not"); if (Op == NULL) { Py_DECREF(Operand); return NULL; } PyObject *Argv[2] = { Op, Operand }; PyObject *Node = NewNode(P, "UnaryOp", Argv, 2); Py_DECREF(Op); Py_DECREF(Operand); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } return ParseComparison(P); } /* 比较运算符映射 */ static const char *CompareOpName(const char *S) { if (strcmp(S, "<") == 0) return "Lt"; if (strcmp(S, ">") == 0) return "Gt"; if (strcmp(S, "<=") == 0) return "LtE"; if (strcmp(S, ">=") == 0) return "GtE"; if (strcmp(S, "==") == 0) return "Eq"; if (strcmp(S, "!=") == 0) return "NotEq"; return NULL; } /* comparison:bit_or (cmpop bit_or)* */ static PyObject *ParseComparison(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *Left = ParseBitOr(P); if (Left == NULL) { return NULL; } PyObject *Ops = NewList(); PyObject *Comparators = NewList(); if (Ops == NULL || Comparators == NULL) { Py_XDECREF(Ops); Py_XDECREF(Comparators); Py_DECREF(Left); return NULL; } for (;;) { SkipNL(P); Token *T = PeekTok(P, 0); const char *OpName = NULL; if (T->Kind == TK_OP) { /* 通过 TokIsOp 精确匹配(避免非 NUL 结尾比较),并消费操作符 token */ if (TokIsOp(T, "<")) { OpName = "Lt"; NextTok(P); } else if (TokIsOp(T, ">")) { OpName = "Gt"; NextTok(P); } else if (TokIsOp(T, "<=")) { OpName = "LtE"; NextTok(P); } else if (TokIsOp(T, ">=")) { OpName = "GtE"; NextTok(P); } else if (TokIsOp(T, "==")) { OpName = "Eq"; NextTok(P); } else if (TokIsOp(T, "!=")) { OpName = "NotEq"; NextTok(P); } } if (OpName == NULL && T->Kind == TK_NAME && TokIsName(T, "is")) { NextTok(P); if (PeekTok(P, 0)->Kind == TK_NAME && TokIsName(PeekTok(P, 0), "not")) { NextTok(P); OpName = "IsNot"; } else { OpName = "Is"; } } else if (OpName == NULL && T->Kind == TK_NAME && TokIsName(T, "in")) { NextTok(P); OpName = "In"; } else if (OpName == NULL && T->Kind == TK_NAME && TokIsName(T, "not") && PeekTok(P, 1)->Kind == TK_NAME && TokIsName(PeekTok(P, 1), "in")) { NextTok(P); NextTok(P); OpName = "NotIn"; } if (OpName == NULL) { break; } PyObject *Op = MakeSingleton(P, OpName); if (Op == NULL) { Py_DECREF(Ops); Py_DECREF(Comparators); Py_DECREF(Left); return NULL; } PyList_Append(Ops, Op); Py_DECREF(Op); PyObject *C = ParseBitOr(P); if (C == NULL) { Py_DECREF(Ops); Py_DECREF(Comparators); Py_DECREF(Left); return NULL; } PyList_Append(Comparators, C); Py_DECREF(C); } if (PyList_GET_SIZE(Ops) == 0) { Py_DECREF(Ops); Py_DECREF(Comparators); return Left; } PyObject *Argv[3] = { Left, Ops, Comparators }; PyObject *Node = NewNode(P, "Compare", Argv, 3); Py_DECREF(Left); Py_DECREF(Ops); Py_DECREF(Comparators); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 二元运算通用循环:left = Parse lower; while op: right = Parse lower; BinOp */ typedef PyObject *(*ParseFunc)(Parser *P); static PyObject *ParseBinLoop(Parser *P, ParseFunc Lower, const char *Op1, const char *Op2, const char *Node1, const char *Node2) { Token *Start = PeekTok(P, 0); PyObject *Left = Lower(P); if (Left == NULL) { return NULL; } for (;;) { SkipNL(P); const char *OpName = NULL; if (Op1 != NULL && AtOp(P, Op1)) { OpName = Node1; NextTok(P); } else if (Op2 != NULL && AtOp(P, Op2)) { OpName = Node2; NextTok(P); } else { break; } PyObject *Right = Lower(P); if (Right == NULL) { Py_DECREF(Left); return NULL; } PyObject *Op = MakeSingleton(P, OpName); if (Op == NULL) { Py_DECREF(Left); Py_DECREF(Right); return NULL; } PyObject *Argv[3] = { Left, Op, Right }; PyObject *Node = NewNode(P, "BinOp", Argv, 3); Py_DECREF(Op); Py_DECREF(Right); Py_DECREF(Left); if (Node == NULL) { return NULL; } FixLoc(P, Node, Start); Left = Node; } return Left; } static PyObject *ParseBitOr(Parser *P) { return ParseBinLoop(P, ParseBitXor, "|", NULL, "BitOr", NULL); } static PyObject *ParseBitXor(Parser *P) { return ParseBinLoop(P, ParseBitAnd, "^", NULL, "BitXor", NULL); } static PyObject *ParseBitAnd(Parser *P) { return ParseBinLoop(P, ParseShift, "&", NULL, "BitAnd", NULL); } static PyObject *ParseShift(Parser *P) { return ParseBinLoop(P, ParseArith, "<<", ">>", "LShift", "RShift"); } static PyObject *ParseArith(Parser *P) { return ParseBinLoop(P, ParseTerm, "+", "-", "Add", "Sub"); } /* ============ C 风格指针后缀(* / **,对齐 vast ExprParser) ============ */ /* 构造类型包装 Subscript(Name(WrapperName), Inner):CPtr[T] / CRef[T] / CTempRef[T]。 */ static PyObject *MakeTypeWrapperSubscript(Parser *P, const char *WrapperName, PyObject *Inner, Token *Tok) { PyObject *Wrapper = MakeTAttrNode(P, WrapperName); if (Wrapper == NULL) { return NULL; } PyObject *Load = MakeCtx(P, "Load"); if (Load == NULL) { Py_DECREF(Wrapper); return NULL; } PyObject *Argv[3] = { Wrapper, Inner, Load }; PyObject *Node = NewNode(P, "Subscript", Argv, 3); Py_DECREF(Wrapper); Py_DECREF(Load); if (Node != NULL) { FixLoc(P, Node, Tok); } return Node; } /* 构造一层指针包装 CPtr[T](对齐 Python _MakePtrType)。 */ static PyObject *MakePtrType(Parser *P, PyObject *Base, Token *Tok) { return MakeTypeWrapperSubscript(P, "CPtr", Base, Tok); } /* 判定当前位置的 '*'/'**' 串是否为 C 风格指针后缀(作用于"类型原子"节点)。 * * 判据(两条同时成立,对齐 Python ExprParser._AtPtrSuffix): * 1. 节点是 Name / Attribute / Subscript(ast.AST / t.CArray[X, N] / rawptr[X] …); * 2. '*'/'**' 串(可跨括号内换行 NL)之后紧跟"无右操作数"位置: * ']'/','/')'/':'/'='(任意上下文)—— 乘法/幂在这些位置本就缺右操作数 * (即原语法错误),故不会改变任何合法表达式(x[a * b] / f(x * y) / * x[1 * 2] / a ** b)的语义;注解模式额外允许 NEWLINE/NL/ENDMARKER/';'。 */ static int AtPtrSuffixEnd(Parser *P, PyObject *Base) { static const char *EndOps[] = {"]", ",", ")", ":", "="}; if (!IsNameOrAttrOrSub(Base)) { return 0; } int J = 0; int Stars = 0; for (;;) { Token *T = PeekTok(P, J); if (TokIsOp(T, "*")) { Stars += 1; J++; } else if (TokIsOp(T, "**")) { Stars += 2; J++; } else if (T->Kind == TK_NL) { J++; } else { break; } } if (Stars == 0) { return 0; } Token *Nxt = PeekTok(P, J); for (size_t I = 0; I < sizeof(EndOps) / sizeof(EndOps[0]); I++) { if (TokIsOp(Nxt, EndOps[I])) { return 1; } } if (P->InTypeAnnotation) { if (Nxt->Kind == TK_NEWLINE || Nxt->Kind == TK_NL || Nxt->Kind == TK_ENDMARKER || TokIsOp(Nxt, ";")) { return 1; } } return 0; } /* 消费连续的 '*'/'**' 指针后缀('**' 计 2 层),展开为 base | t.CPtr 链。 */ static PyObject *ConsumePtrSuffix(Parser *P, PyObject *Node) { for (;;) { Token *T = PeekTok(P, 0); int Layers; if (TokIsOp(T, "*")) { Layers = 1; } else if (TokIsOp(T, "**")) { Layers = 2; } else { break; } NextTok(P); P->PtrSuffixTail = T; /* 记录尾 token,供 ParseParen 识别 (T*)x */ for (int I = 0; I < Layers; I++) { PyObject *Wrapped = MakePtrType(P, Node, T); Py_DECREF(Node); if (Wrapped == NULL) { return NULL; } Node = Wrapped; } } return Node; } static PyObject *ParseCallTail(Parser *P, PyObject *Func, Token *Start); static PyObject *DesugarSpecialCall(Parser *P, PyObject *Node, Token *Start); static PyObject *MakeCifMarkerCall(Parser *P, const char *AttrName, PyObject *Expr, Token *Start); /* 判定当前位置的 '*'/'**' 串是否为 `T*(x)` 形式的指针后缀**强转调用** * (对齐 Python ExprParser._AtPtrSuffixCall): * 1. 节点是类型原子 Name/Attribute/Subscript; * 2. 节点与 '*'/'**' 串**紧贴**(源码字节相邻,无空白/换行); * 3. '*'/'**' 串(串内 token 逐个紧贴)之后**紧贴**一个 '('。 * 即整段写作**无空白**的 `T*(x)`(C 风格强转写法)。'(' 不入 EndOps 表 * (`a * (b)` 是合法乘法,'(' 可作乘法右操作数起点);故叠加"前驱是类型原子 + * 两侧紧贴",`a * (b + c)` / `f(x) * (y)` / `n * (m - 1)` 等仍按乘法解析。 */ static int AtPtrSuffixCall(Parser *P, PyObject *Base) { if (!IsNameOrAttrOrSub(Base)) { return 0; } Token *First = PeekTok(P, 0); Token *Prev = PrevTok(P); if (Prev == NULL || Prev->Kind == TK_NL || Prev->Kind == TK_NEWLINE || Prev->End != First->Start) { return 0; /* base 与 '*'/'**' 之间有空白/换行 */ } int J = 0; int Stars = 0; Token *RunPrev = NULL; Token *Last = NULL; for (;;) { Token *T = PeekTok(P, J); if (TokIsOp(T, "*") || TokIsOp(T, "**")) { if (RunPrev != NULL && T->Start != RunPrev->End) { return 0; /* 星串内部出现空白:非紧邻 */ } Stars++; RunPrev = T; Last = T; J++; } else { break; } } if (Stars == 0 || Last == NULL) { return 0; } Token *Nxt = PeekTok(P, J); return TokIsOp(Nxt, "(") && Nxt->Start == Last->End; } /* 消费已认定的 `T*(...)` 强转:func = base 展开的指针类型,随后解析调用实参。 * 接管 Base 引用(与 ConsumePtrSuffix 一致),返回 Call 的新引用。 */ static PyObject *ConsumePtrSuffixCall(Parser *P, PyObject *Base, Token *Start) { PyObject *Func = ConsumePtrSuffix(P, Base); if (Func == NULL) { return NULL; } PyObject *Call = ParseCallTail(P, Func, Start); Py_DECREF(Func); return Call; } /* ============ 类型注解修饰前缀(const/volatile/... / __attribute__ / 字节序) ============ */ static int IsSpaceByte(char C) { return C == ' ' || C == '\t' || C == '\r' || C == '\n'; } /* 追加一个字符串到惰性创建的 Python list;失败返回 0。 */ static int AppendStringItem(PyObject **List, const char *Text, Py_ssize_t Len) { if (*List == NULL) { *List = NewList(); if (*List == NULL) { return 0; } } PyObject *Item = PyUnicode_FromStringAndSize(Text, Len); if (Item == NULL) { return 0; } int Rc = PyList_Append(*List, Item); Py_DECREF(Item); return Rc == 0; } /* 追加单个 __attribute__ 属性(去掉首尾空白)。 */ static int AppendAttributeSlice(PyObject **List, const char *Text, Py_ssize_t Len) { while (Len > 0 && IsSpaceByte(*Text)) { Text++; Len--; } while (Len > 0 && IsSpaceByte(Text[Len - 1])) { Len--; } if (Len == 0) { return 1; } return AppendStringItem(List, Text, Len); } /* 从 `__attribute__((...))` 源码片段提取属性列表,按顶层逗号拆分后写入 List。 * 例:__attribute__((section(".x"), aligned(16))) -> ["section(\".x\")", "aligned(16)"] */ static int AppendAttributesFromText(PyObject **List, const char *Text, Py_ssize_t Len) { Py_ssize_t I = 0; while (I < Len && Text[I] != '(') { I++; } if (I >= Len) { return 1; } I++; /* 跳过 __attribute__ 后的 '(' */ Py_ssize_t J = Len; while (J > I && Text[J - 1] != ')') { J--; } if (J <= I) { return 1; } J--; /* 去掉与之配对的 ')' */ while (I < J && IsSpaceByte(Text[I])) { I++; } while (J > I && IsSpaceByte(Text[J - 1])) { J--; } /* GNU 双括号形式 __attribute__((...)):剥掉内层一对括号 */ if (J - I >= 2 && Text[I] == '(' && Text[J - 1] == ')') { I++; J--; } Py_ssize_t Start = I; int Depth = 0; char Quote = 0; for (Py_ssize_t K = I; K < J; K++) { char C = Text[K]; if (Quote != 0) { if (C == '\\' && K + 1 < J) { K++; } else if (C == Quote) { Quote = 0; } continue; } if (C == '"' || C == '\'') { Quote = C; } else if (C == '(' || C == '[' || C == '{') { Depth++; } else if (C == ')' || C == ']' || C == '}') { if (Depth > 0) { Depth--; } } else if (C == ',' && Depth == 0) { if (!AppendAttributeSlice(List, Text + Start, K - Start)) { return 0; } Start = K + 1; } } return AppendAttributeSlice(List, Text + Start, J - Start); } /* 下一 token 能否作为类型起点(前缀修饰后必须仍跟着实际类型)。 */ static int TokStartsType(Parser *P, int Off) { Token *T = PeekTok(P, Off); if (T->Kind == TK_NAME) { return 1; } return T->Kind == TK_OP && (TokIsOp(T, "&") || TokIsOp(T, "[") || TokIsOp(T, "(")); } /* 消费注解前缀:const/volatile/static/export/extern/inline/state/define/typedef、 * __attribute__((...))、BigEndian/bigend、LittleEndian/littlend。 * 裸标记名(后面没有类型)不消费,按普通类型名解析。 */ static int ParseTypePrefixes(Parser *P, PyObject **Markers, PyObject **Attributes, const char **ByteOrder) { for (;;) { Token *T = PeekTok(P, 0); if (T->Kind != TK_NAME || !TokStartsType(P, 1)) { break; } if (TokIsName(T, "__attribute__")) { if (!TokIsOp(PeekTok(P, 1), "(")) { break; } Token *AttrTok = NextTok(P); const char *End = NULL; int Depth = 0; for (;;) { Token *U = PeekTok(P, 0); if (U->Kind == TK_ENDMARKER) { SyntaxErrorAt(P, U, "`__attribute__(...)` 括号未闭合"); return 0; } NextTok(P); if (TokIsOp(U, "(")) { Depth++; } else if (TokIsOp(U, ")")) { Depth--; if (Depth == 0) { End = U->End; break; } } } if (!AppendAttributesFromText(Attributes, AttrTok->Start, End - AttrTok->Start)) { return 0; } continue; } static const char *MarkerNames[] = { "const", "volatile", "static", "export", "extern", "inline", "state", "define", "typedef" }; const char *Marker = NULL; for (size_t I = 0; I < sizeof(MarkerNames) / sizeof(MarkerNames[0]); I++) { if (TokIsName(T, MarkerNames[I])) { Marker = MarkerNames[I]; break; } } if (Marker != NULL) { if (!AppendStringItem(Markers, Marker, (Py_ssize_t)strlen(Marker))) { return 0; } NextTok(P); continue; } if (TokIsName(T, "BigEndian") || TokIsName(T, "bigend")) { *ByteOrder = "big"; NextTok(P); continue; } if (TokIsName(T, "LittleEndian") || TokIsName(T, "littlend")) { *ByteOrder = "little"; NextTok(P); continue; } break; } return 1; } /* 名称或属性名是否等于 Name(Name.id / Attribute.attr)。 */ static int IsNameOrAttrNamed(PyObject *Node, const char *Name) { const char *Field = NodeIs(Node, "Name") ? "id" : (NodeIs(Node, "Attribute") ? "attr" : NULL); if (Field == NULL) { return 0; } PyObject *V = PyObject_GetAttrString(Node, Field); if (V == NULL) { PyErr_Clear(); return 0; } int Hit = PyUnicode_Check(V) && PyUnicode_CompareWithASCIIString(V, Name) == 0; Py_DECREF(V); return Hit; } /* Constant 节点的整数值;非整数返回 0。 */ static int ConstantIntValue(PyObject *Node, long *Out) { if (Node == NULL || !NodeIs(Node, "Constant")) { return 0; } PyObject *V = PyObject_GetAttrString(Node, "value"); if (V == NULL) { PyErr_Clear(); return 0; } int Ok = 0; if (PyLong_Check(V)) { long L = PyLong_AsLong(V); if (L == -1 && PyErr_Occurred()) { PyErr_Clear(); } else { *Out = L; Ok = 1; } } Py_DECREF(V); return Ok; } /* Bit(N) / Bit[N] 注解:设 BitWidth(无法求值宽度时记 1)。 */ static void ApplyBitWidthAttr(PyObject *Node) { PyObject *Value = NULL; PyObject *WidthNode = NULL; if (NodeIs(Node, "Call")) { Value = PyObject_GetAttrString(Node, "func"); if (Value != NULL && IsNameOrAttrNamed(Value, "Bit")) { PyObject *Args = PyObject_GetAttrString(Node, "args"); if (Args != NULL && PyList_Check(Args) && PyList_GET_SIZE(Args) > 0) { WidthNode = PyList_GET_ITEM(Args, 0); Py_INCREF(WidthNode); } Py_XDECREF(Args); } } else if (NodeIs(Node, "Subscript")) { Value = PyObject_GetAttrString(Node, "value"); if (Value != NULL && IsNameOrAttrNamed(Value, "Bit")) { WidthNode = PyObject_GetAttrString(Node, "slice"); } } if (WidthNode != NULL) { long Width = 0; SetAttrLong(Node, "BitWidth", ConstantIntValue(WidthNode, &Width) ? Width : 1); Py_DECREF(WidthNode); } Py_XDECREF(Value); } /* 把前缀修饰写入注解节点的 Markers / Attributes / ByteOrder。 */ static void ApplyTypeModifiers(PyObject *Node, PyObject *Markers, PyObject *Attributes, const char *ByteOrder) { if (Markers != NULL && PyList_GET_SIZE(Markers) > 0) { if (PyObject_SetAttrString(Node, "Markers", Markers) < 0) { PyErr_Clear(); } } if (Attributes != NULL && PyList_GET_SIZE(Attributes) > 0) { if (PyObject_SetAttrString(Node, "Attributes", Attributes) < 0) { PyErr_Clear(); } } if (ByteOrder != NULL) { PyObject *Order = PyUnicode_FromString(ByteOrder); if (Order != NULL) { if (PyObject_SetAttrString(Node, "ByteOrder", Order) < 0) { PyErr_Clear(); } Py_DECREF(Order); } } } /* 把语句级修饰词追加到注解节点的 Markers(保序去重,对齐 Parser._AddTypeMarkers)。 */ static void AddTypeMarkers(PyObject *Node, const char *Marker) { if (Node == NULL || Node == Py_None) { return; } if (!PyObject_HasAttrString((PyObject *)Py_TYPE(Node), "Markers")) { return; } PyObject *Existing = PyObject_GetAttrString(Node, "Markers"); PyObject *Items = NULL; if (Existing == NULL) { PyErr_Clear(); Items = PyTuple_New(0); } else { Items = PySequence_Tuple(Existing); Py_DECREF(Existing); } if (Items == NULL) { PyErr_Clear(); return; } PyObject *MarkerStr = PyUnicode_FromString(Marker); if (MarkerStr == NULL) { Py_DECREF(Items); PyErr_Clear(); return; } int Hit = PySequence_Contains(Items, MarkerStr); if (Hit != 0) { if (Hit < 0) { PyErr_Clear(); } Py_DECREF(Items); Py_DECREF(MarkerStr); return; } Py_ssize_t N = PyTuple_GET_SIZE(Items); PyObject *Merged = PyTuple_New(N + 1); if (Merged == NULL) { Py_DECREF(Items); Py_DECREF(MarkerStr); PyErr_Clear(); return; } for (Py_ssize_t I = 0; I < N; I++) { PyObject *Item = PyTuple_GET_ITEM(Items, I); Py_INCREF(Item); PyTuple_SET_ITEM(Merged, I, Item); } PyTuple_SET_ITEM(Merged, N, MarkerStr); /* steals MarkerStr */ if (PyObject_SetAttrString(Node, "Markers", Merged) < 0) { PyErr_Clear(); } Py_DECREF(Merged); Py_DECREF(Items); } /* 注解联合中的 None 字面量:Constant(None) 或 Name('None')。 */ static int IsNoneLiteralNode(PyObject *Node) { if (Node == NULL || Node == Py_None) { return 0; } if (NodeIsConstant(Node)) { PyObject *V = PyObject_GetAttrString(Node, "value"); int Hit = (V == Py_None); if (V == NULL) { PyErr_Clear(); } else { Py_DECREF(V); } return Hit; } if (NodeIs(Node, "Name")) { PyObject *Id = PyObject_GetAttrString(Node, "id"); int Hit = 0; if (Id == NULL) { PyErr_Clear(); } else { Hit = PyUnicode_Check(Id) && PyUnicode_CompareWithASCIIString(Id, "None") == 0; Py_DECREF(Id); } return Hit; } return 0; } /* 注解 AST 中**源码书写**的 CPtr(裸名 / 限定名)节点(无则 NULL)。 * 内部指针表示仍是 Subscript(Name('CPtr'), T)(`T*` 脱糖产物),但合成的 * Name 不带位置属性(MakeTypeWrapperSubscript 只给 Subscript 定位);源码 * 中的 CPtr 一定带 lineno。据此只拒绝用户源码写法,不影响内部 AST。 */ static PyObject *FindSourceCPtr(PyObject *Node) { if (Node == NULL || Node == Py_None) { return NULL; } if (NodeIs(Node, "Name") || NodeIs(Node, "Attribute")) { const char *Field = NodeIs(Node, "Name") ? "id" : "attr"; PyObject *Name = PyObject_GetAttrString(Node, Field); int Hit = 0; if (Name == NULL) { PyErr_Clear(); } else { if (PyUnicode_Check(Name) && PyUnicode_CompareWithASCIIString(Name, "CPtr") == 0 && PyObject_HasAttrString(Node, "lineno") == 1) { Hit = 1; } Py_DECREF(Name); } if (Hit) { return Node; } } PyObject *Fields = PyObject_GetAttrString(Node, "_fields"); if (Fields == NULL) { PyErr_Clear(); return NULL; } PyObject *Found = NULL; Py_ssize_t N = PyTuple_Check(Fields) ? PyTuple_GET_SIZE(Fields) : 0; for (Py_ssize_t I = 0; I < N && Found == NULL; I++) { PyObject *FName = PyTuple_GET_ITEM(Fields, I); if (!PyUnicode_Check(FName)) { continue; } const char *FNameStr = PyUnicode_AsUTF8(FName); if (FNameStr == NULL) { PyErr_Clear(); continue; } PyObject *Child = PyObject_GetAttrString(Node, FNameStr); if (Child == NULL) { PyErr_Clear(); continue; } if (PyList_Check(Child) || PyTuple_Check(Child)) { Py_ssize_t M = PySequence_Size(Child); for (Py_ssize_t J = 0; J < M && Found == NULL; J++) { PyObject *Item = PySequence_GetItem(Child, J); if (Item == NULL) { PyErr_Clear(); continue; } Found = FindSourceCPtr(Item); Py_DECREF(Item); } } else if (PyObject_HasAttrString(Child, "_fields") == 1) { Found = FindSourceCPtr(Child); } Py_DECREF(Child); } Py_DECREF(Fields); return Found; } /* 按 AST 节点的 lineno/col_offset 找回对应 token(用于精确报错定位)。 */ static Token *FindTokenAt(Parser *P, PyObject *Node) { PyObject *LineObj = PyObject_GetAttrString(Node, "lineno"); PyObject *ColObj = PyObject_GetAttrString(Node, "col_offset"); if (LineObj == NULL || ColObj == NULL) { PyErr_Clear(); Py_XDECREF(LineObj); Py_XDECREF(ColObj); return NULL; } long Line = PyLong_AsLong(LineObj); long Col = PyLong_AsLong(ColObj); Py_DECREF(LineObj); Py_DECREF(ColObj); if (PyErr_Occurred()) { PyErr_Clear(); return NULL; } for (int I = 0; I < P->NTokens; I++) { if (P->Tokens[I].Line == Line && P->Tokens[I].Col == Col) { return &P->Tokens[I]; } } return NULL; } /* 类型注解入口:置注解模式标志(对齐 Python ExprParser._ParseTypeAnnotation)。 * * 值引用参数注解(仅形参位有效,对齐纯 Python 端): * 前导 '&' + 可选名 'temp',构造 Subscript(Name('CRef'), T) / Subscript(Name('CTempRef'), T)。 * CRef/CTempRef 非真实类,仅作注解 AST 内的名字标记(语义侧按名字识别)。 * '&'/'&temp' 之后缺类型(行尾 / ')' / ',' / ':' / '=' / ']' / '}' / ';')时响亮失败。 */ static PyObject *ParseTypeAnnotation(Parser *P) { PyObject *Markers = NULL; PyObject *Attributes = NULL; const char *ByteOrder = NULL; if (!ParseTypePrefixes(P, &Markers, &Attributes, &ByteOrder)) { Py_XDECREF(Markers); Py_XDECREF(Attributes); return NULL; } int RefTemp = 0; /* 0=非值引用 1=ref 2=temp */ Token *RefTok = PeekTok(P, 0); if (AtOp(P, "&")) { NextTok(P); if (AtName(P, "temp")) { NextTok(P); RefTemp = 2; } else { RefTemp = 1; } Token *End = PeekTok(P, 0); if (End->Kind == TK_NEWLINE || End->Kind == TK_NL || End->Kind == TK_ENDMARKER || TokIsOp(End, ")") || TokIsOp(End, ",") || TokIsOp(End, ":") || TokIsOp(End, "=") || TokIsOp(End, "]") || TokIsOp(End, "}") || TokIsOp(End, ";")) { SyntaxErrorAt(P, End, "值引用参数注解缺少类型:`&` 后必须紧跟类型 T(ref:`&T`;temp:`&temp T`)"); Py_XDECREF(Markers); Py_XDECREF(Attributes); return NULL; } } int Saved = P->InTypeAnnotation; P->InTypeAnnotation = 1; PyObject *Node = ParseExpr(P); P->InTypeAnnotation = Saved; if (Node == NULL) { Py_XDECREF(Markers); Py_XDECREF(Attributes); return NULL; } /* 源码不再接受 CPtr[...] / CPtr 指针写法(内部 `T*` 脱糖产物无 lineno)。 */ PyObject *SourceCPtr = FindSourceCPtr(Node); if (SourceCPtr != NULL) { Token *BadTok = FindTokenAt(P, SourceCPtr); SyntaxErrorAt(P, BadTok != NULL ? BadTok : RefTok, "指针请写 T*(如 int*):源码不再支持 CPtr[...] 指针写法"); Py_DECREF(Node); Py_XDECREF(Markers); Py_XDECREF(Attributes); return NULL; } /* `T | None` / `None | T` 等价于 T;两侧同为 None 或均非 None 仍报错。 * 对齐 Pure Python ExprParser._ParseTypeAnnotation 的联合处理。 */ if (NodeIs(Node, "BinOp")) { PyObject *Op = PyObject_GetAttrString(Node, "op"); int IsBitOr = (Op != NULL && NodeIs(Op, "BitOr")); Py_XDECREF(Op); if (IsBitOr) { PyObject *Left = PyObject_GetAttrString(Node, "left"); PyObject *Right = PyObject_GetAttrString(Node, "right"); if (Left == NULL || Right == NULL) { PyErr_Clear(); Py_XDECREF(Left); Py_XDECREF(Right); } else { int LeftNone = IsNoneLiteralNode(Left); int RightNone = IsNoneLiteralNode(Right); if (LeftNone != RightNone) { PyObject *Keep = LeftNone ? Right : Left; Py_INCREF(Keep); Py_DECREF(Node); Node = Keep; } else { SyntaxErrorAt(P, PeekTok(P, 0), "unsupported type union 'T1 | T2': type annotation must be a single type"); Py_DECREF(Left); Py_DECREF(Right); Py_DECREF(Node); Py_XDECREF(Markers); Py_XDECREF(Attributes); return NULL; } Py_DECREF(Left); Py_DECREF(Right); } } } if (RefTemp != 0) { PyObject *Wrap = MakeTypeWrapperSubscript( P, RefTemp == 2 ? "CTempRef" : "CRef", Node, RefTok); Py_DECREF(Node); if (Wrap == NULL) { Py_XDECREF(Markers); Py_XDECREF(Attributes); return NULL; } Node = Wrap; } ApplyTypeModifiers(Node, Markers, Attributes, ByteOrder); ApplyBitWidthAttr(Node); Py_XDECREF(Markers); Py_XDECREF(Attributes); return Node; } /* term:factor (*|/|//|%|@ factor)* */ static PyObject *ParseTerm(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *Left = ParseFactor(P); if (Left == NULL) { return NULL; } for (;;) { SkipNL(P); Token *T = PeekTok(P, 0); const char *OpName = NULL; if (T->Kind == TK_OP) { if (TokIsOp(T, "*") && AtPtrSuffixEnd(P, Left)) { /* C 风格指针后缀('*' 一层) */ Left = ConsumePtrSuffix(P, Left); if (Left == NULL) { return NULL; } continue; } if (TokIsOp(T, "*")) OpName = "Mult"; else if (TokIsOp(T, "/")) OpName = "Div"; else if (TokIsOp(T, "//")) OpName = "FloorDiv"; else if (TokIsOp(T, "%")) OpName = "Mod"; else if (TokIsOp(T, "@")) OpName = "MatMult"; } if (OpName == NULL) { break; } NextTok(P); PyObject *Right = ParseFactor(P); if (Right == NULL) { Py_DECREF(Left); return NULL; } PyObject *Op = MakeSingleton(P, OpName); if (Op == NULL) { Py_DECREF(Left); Py_DECREF(Right); return NULL; } PyObject *Argv[3] = { Left, Op, Right }; PyObject *Node = NewNode(P, "BinOp", Argv, 3); Py_DECREF(Op); Py_DECREF(Right); Py_DECREF(Left); if (Node == NULL) { return NULL; } FixLoc(P, Node, Start); Left = Node; } return Left; } /* factor:+|-|~|*|& factor | power */ static PyObject *ParseFactor(Parser *P) { Token *T = PeekTok(P, 0); /* 一元前缀与 Python ExprParser._ParseFactor 逐字对齐:'+' USub/'-'/'~' 之外还含 * Viper 新规范的 '*'(Deref) 与 '&'(AddrOf)(`*p = v` / `&x`)。缺这两项时 * C 解析器对含取址/解引用的文件整体失败并回退纯 Python(C 缺口清单根因)。 */ if (T->Kind == TK_OP && (TokIsOp(T, "+") || TokIsOp(T, "-") || TokIsOp(T, "~") || TokIsOp(T, "*") || TokIsOp(T, "&"))) { Token *Start = NextTok(P); PyObject *Operand = ParseFactor(P); if (Operand == NULL) { return NULL; } const char *OpName = TokIsOp(Start, "+") ? "UAdd" : (TokIsOp(Start, "-") ? "USub" : (TokIsOp(Start, "~") ? "Invert" : (TokIsOp(Start, "*") ? "Deref" : "AddrOf"))); PyObject *Op = MakeSingleton(P, OpName); if (Op == NULL) { Py_DECREF(Operand); return NULL; } PyObject *Argv[2] = { Op, Operand }; PyObject *Node = NewNode(P, "UnaryOp", Argv, 2); Py_DECREF(Op); Py_DECREF(Operand); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } return ParsePower(P); } /* power:await_primary ('**' factor)? */ static PyObject *ParsePower(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *Base = ParseAwaitPrimary(P); if (Base == NULL) { return NULL; } if (!AtOp(P, "**")) { return Base; } if (AtPtrSuffixEnd(P, Base)) { /* C 风格指针后缀('**' 计 2 层) */ return ConsumePtrSuffix(P, Base); } NextTok(P); PyObject *Exp = ParseFactor(P); if (Exp == NULL) { Py_DECREF(Base); return NULL; } PyObject *Op = MakeSingleton(P, "Pow"); if (Op == NULL) { Py_DECREF(Base); Py_DECREF(Exp); return NULL; } PyObject *Argv[3] = { Base, Op, Exp }; PyObject *Node = NewNode(P, "BinOp", Argv, 3); Py_DECREF(Op); Py_DECREF(Exp); Py_DECREF(Base); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* await_primary:'await' primary | primary */ static PyObject *ParseAwaitPrimary(Parser *P) { if (AtName(P, "await")) { Token *Start = NextTok(P); PyObject *Value = ParsePrimary(P); if (Value == NULL) { return NULL; } PyObject *Argv[1] = { Value }; PyObject *Node = NewNode(P, "Await", Argv, 1); Py_DECREF(Value); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } return ParsePrimary(P); } /* 调用尾部:'(' [args] ')' */ static PyObject *ParseCallTail(Parser *P, PyObject *Func, Token *Start) { if (!ExpectOp(P, "(")) { return NULL; } PyObject *Args = NewList(); PyObject *Keywords = NewList(); if (Args == NULL || Keywords == NULL) { Py_XDECREF(Args); Py_XDECREF(Keywords); return NULL; } SkipNL(P); if (!AtOp(P, ")")) { for (;;) { SkipNL(P); if (AtOp(P, "**")) { NextTok(P); PyObject *Value = ParseExpr(P); if (Value == NULL) { Py_DECREF(Args); Py_DECREF(Keywords); return NULL; } PyObject *Kw = MakeKeyword(P, NULL, Value, PrevTok(P)); Py_DECREF(Value); if (Kw == NULL) { Py_DECREF(Args); Py_DECREF(Keywords); return NULL; } PyList_Append(Keywords, Kw); Py_DECREF(Kw); } else { if (AtOp(P, "*")) { NextTok(P); PyObject *Value = ParseExpr(P); if (Value == NULL) { Py_DECREF(Args); Py_DECREF(Keywords); return NULL; } PyObject *Starred = MakeStarred(P, Value); Py_DECREF(Value); if (Starred == NULL) { Py_DECREF(Args); Py_DECREF(Keywords); return NULL; } FixLoc(P, Starred, PrevTok(P)); PyList_Append(Args, Starred); Py_DECREF(Starred); } else { Token *T0 = PeekTok(P, 0); Token *T1 = PeekTok(P, 1); if (T0->Kind == TK_NAME && T1->Kind == TK_OP && TokIsOp(T1, "=")) { Token *NameTok = NextTok(P); NextTok(P); /* '=' */ PyObject *Value = ParseExpr(P); if (Value == NULL) { Py_DECREF(Args); Py_DECREF(Keywords); return NULL; } PyObject *Arg = PyUnicode_FromStringAndSize(NameTok->Start, NameTok->End - NameTok->Start); PyObject *Kw = MakeKeyword(P, Arg, Value, NameTok); Py_XDECREF(Arg); Py_DECREF(Value); if (Kw == NULL) { Py_DECREF(Args); Py_DECREF(Keywords); return NULL; } PyList_Append(Keywords, Kw); Py_DECREF(Kw); } else { if (PyList_GET_SIZE(Args) == 0 && PyList_GET_SIZE(Keywords) == 0) { Token *GenStart = PeekTok(P, 0); PyObject *GenElt = ParseExpr(P); if (GenElt == NULL) { Py_DECREF(Args); Py_DECREF(Keywords); return NULL; } if (AtName(P, "for")) { PyObject *GenGens = ParseComprehensionGenerators(P); if (GenGens == NULL) { Py_DECREF(GenElt); Py_DECREF(Args); Py_DECREF(Keywords); return NULL; } PyObject *GArgv[2] = { GenElt, GenGens }; PyObject *Gen = NewNode(P, "GeneratorExp", GArgv, 2); Py_DECREF(GenGens); Py_DECREF(GenElt); if (Gen == NULL) { Py_DECREF(Args); Py_DECREF(Keywords); return NULL; } FixLoc(P, Gen, GenStart); PyList_Append(Args, Gen); Py_DECREF(Gen); } else { PyList_Append(Args, GenElt); Py_DECREF(GenElt); } } else { PyObject *E = ParseExpr(P); if (E == NULL) { Py_DECREF(Args); Py_DECREF(Keywords); return NULL; } PyList_Append(Args, E); Py_DECREF(E); } } } } SkipNL(P); if (AtOp(P, ",")) { NextTok(P); SkipNL(P); if (AtOp(P, ")")) { break; } continue; } break; } } if (!ExpectOp(P, ")")) { Py_DECREF(Args); Py_DECREF(Keywords); return NULL; } PyObject *Argv[3] = { Func, Args, Keywords }; PyObject *Node = NewNode(P, "Call", Argv, 3); Py_DECREF(Args); Py_DECREF(Keywords); if (Node != NULL) { FixLoc(P, Node, Start); Node = DesugarSpecialCall(P, Node, Start); } return Node; } /* 被调用者限定名:Name('X')→'X';Attribute(Name('M'),'X')→'M.X';否则 NULL(无异常)。 */ static PyObject *MakeCifMarkerCall(Parser *P, const char *AttrName, PyObject *Expr, Token *Start); static PyObject *CalleeQualName(PyObject *Func) { if (NodeIs(Func, "Name")) { return PyObject_GetAttrString(Func, "id"); } if (NodeIs(Func, "Attribute")) { PyObject *Value = PyObject_GetAttrString(Func, "value"); PyObject *Attr = PyObject_GetAttrString(Func, "attr"); PyObject *Result = NULL; if (Value != NULL && Attr != NULL && NodeIs(Value, "Name")) { PyObject *Id = PyObject_GetAttrString(Value, "id"); if (Id != NULL) { Result = PyUnicode_FromFormat("%U.%U", Id, Attr); Py_DECREF(Id); } } Py_XDECREF(Value); Py_XDECREF(Attr); return Result; } return NULL; } static int StrIsOneOf(PyObject *S, const char *const *Names) { for (int I = 0; Names[I] != NULL; I++) { if (PyUnicode_CompareWithASCIIString(S, Names[I]) == 0) { return 1; } } return 0; } /* 调用点特殊 desugar / fail-fast:接管 Node 的引用,返回新引用(失败返回 NULL)。 * - defined(NAME):仅 cif/celif 条件内合法(P->InCIfCond)⇒ desugar 为 c.@CIfdef(NAME); * 其余位置 ⇒ FailFast。 * - c.CIf / c.CIfdef / c.CIfndef / c.CElif / c.CElse / c.CEndif(及裸名):已删除 ⇒ FailFast, * 指向原生新语法。 */ static PyObject *DesugarSpecialCall(Parser *P, PyObject *Node, Token *Start) { PyObject *Func = PyObject_GetAttrString(Node, "func"); if (Func == NULL) { PyErr_Clear(); return Node; } /* 廉价预筛:只看标识符短名(Name.id / Attribute.attr),与 cif 无关的调用一律 * 立即返回,避免在解析热路径上为每个调用构造限定名并分配字符串。 */ PyObject *Short = NULL; if (NodeIs(Func, "Name")) { Short = PyObject_GetAttrString(Func, "id"); } else if (NodeIs(Func, "Attribute")) { Short = PyObject_GetAttrString(Func, "attr"); } if (Short == NULL) { PyErr_Clear(); Py_DECREF(Func); return Node; } static const char *Interesting[] = {"CIf", "CIfdef", "CIfndef", "CElif", "CElse", "CEndif", "defined", NULL}; int Hit = StrIsOneOf(Short, Interesting); Py_DECREF(Short); if (!Hit) { Py_DECREF(Func); return Node; } PyObject *Callee = CalleeQualName(Func); Py_DECREF(Func); if (Callee == NULL) { PyErr_Clear(); return Node; } static const char *Removed[] = { "CIf", "CIfdef", "CIfndef", "CElif", "CElse", "CEndif", "c.CIf", "c.CIfdef", "c.CIfndef", "c.CElif", "c.CElse", "c.CEndif", NULL }; if (StrIsOneOf(Callee, Removed)) { PyErr_Format(PyExc_SyntaxError, "'%U(...)' has been removed; use the native 'cif' / 'celif' / 'celse' " "statements together with the 'defined(NAME)' predicate instead, at line %d", Callee, Start->Line); Py_DECREF(Callee); Py_DECREF(Node); return NULL; } if (PyUnicode_CompareWithASCIIString(Callee, "defined") == 0) { Py_DECREF(Callee); if (!P->InCIfCond) { PyErr_Format(PyExc_SyntaxError, "'defined(NAME)' is only allowed inside a 'cif' / 'celif' condition, at line %d", Start->Line); Py_DECREF(Node); return NULL; } PyObject *Args = PyObject_GetAttrString(Node, "args"); PyObject *Kw = PyObject_GetAttrString(Node, "keywords"); PyObject *Arg0 = NULL; if (Args != NULL && Kw != NULL && PyList_Check(Args) && PyList_Check(Kw) && PyList_GET_SIZE(Args) == 1 && PyList_GET_SIZE(Kw) == 0) { Arg0 = PyList_GetItem(Args, 0); /* borrowed */ } if (Arg0 == NULL) { PyErr_Format(PyExc_SyntaxError, "'defined' expects exactly one macro name (e.g. defined(MAX_SIZE)), at line %d", Start->Line); Py_XDECREF(Args); Py_XDECREF(Kw); Py_DECREF(Node); return NULL; } PyObject *Marker = MakeCifMarkerCall(P, "@CIfdef", Arg0, Start); Py_XDECREF(Args); Py_XDECREF(Kw); Py_DECREF(Node); return Marker; } Py_DECREF(Callee); return Node; } static PyObject *ParseSliceList(Parser *P); static PyObject *ParseSliceItem(Parser *P); /* 下标尾部:'[' slice_list ']' */ static PyObject *ParseSubscriptTail(Parser *P, PyObject *Value, Token *Start) { if (!ExpectOp(P, "[")) { return NULL; } SkipNL(P); PyObject *SliceNode = ParseSliceList(P); if (SliceNode == NULL) { return NULL; } SkipNL(P); if (!ExpectOp(P, "]")) { Py_DECREF(SliceNode); return NULL; } PyObject *Load = MakeCtx(P, "Load"); if (Load == NULL) { Py_DECREF(SliceNode); return NULL; } PyObject *Argv[3] = { Value, SliceNode, Load }; PyObject *Node = NewNode(P, "Subscript", Argv, 3); Py_DECREF(SliceNode); Py_DECREF(Load); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } static PyObject *ParseSliceList(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *Elts = NewList(); if (Elts == NULL) { return NULL; } PyObject *First = ParseSliceItem(P); if (First == NULL) { Py_DECREF(Elts); return NULL; } PyList_Append(Elts, First); while (AtOp(P, ",")) { NextTok(P); SkipNL(P); PyObject *E = ParseSliceItem(P); if (E == NULL) { Py_DECREF(Elts); Py_DECREF(First); return NULL; } PyList_Append(Elts, E); Py_DECREF(E); } if (PyList_GET_SIZE(Elts) == 1) { Py_DECREF(Elts); return First; } Py_DECREF(First); PyObject *Load = MakeCtx(P, "Load"); if (Load == NULL) { Py_DECREF(Elts); return NULL; } PyObject *Argv[2] = { Elts, Load }; PyObject *Node = NewNode(P, "Tuple", Argv, 2); Py_DECREF(Elts); Py_DECREF(Load); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } static PyObject *ParseSliceItem(Parser *P) { Token *Start = PeekTok(P, 0); if (AtOp(P, ":")) { NextTok(P); PyObject *Upper = NULL; if (!AtOp(P, ":") && !AtOp(P, ",")) { if (!AtOp(P, "]")) { Upper = ParseExpr(P); if (Upper == NULL) { return NULL; } } } PyObject *Step = NULL; if (AtOp(P, ":")) { NextTok(P); if (!AtOp(P, "]") && !AtOp(P, ",") && !AtOp(P, ":")) { Step = ParseExpr(P); if (Step == NULL) { Py_XDECREF(Upper); return NULL; } } } PyObject *Argv[3] = { Py_None, Upper ? Upper : Py_None, Step ? Step : Py_None }; PyObject *Node = NewNode(P, "Slice", Argv, 3); Py_XDECREF(Upper); Py_XDECREF(Step); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } PyObject *First = ParseExpr(P); if (First == NULL) { return NULL; } if (!AtOp(P, ":")) { return First; } NextTok(P); PyObject *Lower = First; PyObject *Upper = NULL; PyObject *Step = NULL; if (!AtOp(P, ":") && !AtOp(P, "]") && !AtOp(P, ",")) { Upper = ParseExpr(P); if (Upper == NULL) { Py_DECREF(Lower); return NULL; } } if (AtOp(P, ":")) { NextTok(P); if (!AtOp(P, "]") && !AtOp(P, ",")) { Step = ParseExpr(P); if (Step == NULL) { Py_DECREF(Lower); Py_XDECREF(Upper); return NULL; } } } PyObject *Argv[3] = { Lower, Upper ? Upper : Py_None, Step ? Step : Py_None }; PyObject *Node = NewNode(P, "Slice", Argv, 3); Py_DECREF(Lower); Py_XDECREF(Upper); Py_XDECREF(Step); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 主表达式:原子 + trailer(属性/调用/下标) */ static PyObject *ParsePrimary(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *Node = ParseAtom(P); if (Node == NULL) { return NULL; } for (;;) { SkipNL(P); Token *T = PeekTok(P, 0); if (T->Kind == TK_OP && (TokIsOp(T, "*") || TokIsOp(T, "**")) && AtPtrSuffixCall(P, Node)) { /* `T*(x)` / `T**(x)` 指针后缀强转:解析为 cast 调用(与 (T | t.CPtr)(x) * 同形)。在 trailer 循环里消费,故其后的 .attr / [i] / (…) 继续挂接。 */ Node = ConsumePtrSuffixCall(P, Node, Start); if (Node == NULL) { return NULL; } } else if (T->Kind == TK_OP && TokIsOp(T, ".")) { NextTok(P); Token *AttrTok = ExpectName(P, NULL); if (AttrTok == NULL) { Py_DECREF(Node); return NULL; } PyObject *NewNode2 = MakeAttrNode(P, Node, AttrTok, Start); Py_DECREF(Node); if (NewNode2 == NULL) { return NULL; } Node = NewNode2; } else if (T->Kind == TK_OP && TokIsOp(T, "(")) { PyObject *Call = ParseCallTail(P, Node, Start); Py_DECREF(Node); if (Call == NULL) { return NULL; } Node = Call; } else if (T->Kind == TK_OP && TokIsOp(T, "[")) { PyObject *Sub = ParseSubscriptTail(P, Node, Start); Py_DECREF(Node); if (Sub == NULL) { return NULL; } Node = Sub; } else { break; } } return Node; } /* 数字常量 */ static PyObject *ParseNumber(Parser *P) { Token *T = NextTok(P); PyObject *Val = ParseNumberValue(P, T); if (Val == NULL) { return NULL; } PyObject *Node = MakeConstantPos(P, Val, T); Py_DECREF(Val); return Node; } /* 原子表达式 */ static PyObject *ParseAtom(Parser *P) { SkipNL(P); Token *T = PeekTok(P, 0); if (T->Kind == TK_NUMBER) { return ParseNumber(P); } if (T->Kind == TK_STRING || T->Kind == TK_FSTRING) { return ParseStringConcat(P); } if (T->Kind == TK_NAME) { if (TokIsName(T, "True") || TokIsName(T, "False") || TokIsName(T, "None")) { NextTok(P); PyObject *Val = TokIsName(T, "True") ? Py_True : (TokIsName(T, "False") ? Py_False : Py_None); PyObject *Node = MakeConstantPos(P, Val, T); return Node; } NextTok(P); /* 必须消费名字 token,否则上层循环死循环(idx 不前) */ return MakeNameNode(P, T, "Load"); } if (T->Kind == TK_OP) { if (TokIsOp(T, "(")) { return ParseParen(P); } if (TokIsOp(T, "[")) { return ParseList(P); } if (TokIsOp(T, "{")) { return ParseDictSet(P); } if (TokIsOp(T, "...")) { NextTok(P); return MakeConstantPos(P, Py_Ellipsis, T); } } SyntaxErrorAt(P, T, "unexpected token"); return NULL; } /* 无括号强转 `(T*)x` 的操作数起点判据(对齐 Python ExprParser._AtCastOperand): * NAME/NUMBER/STRING,或 OP 中的 '['/'{'/'*'/'&'/'-'/'+'/'~'。'(' 不在内 * (`(T*)(x)` 已由调用 trailer 处理);NL 不跳过(换行后是新语句,不是操作数)。 */ static int AtCastOperand(Parser *P) { Token *T = PeekTok(P, 0); if (T->Kind == TK_NAME || T->Kind == TK_NUMBER || T->Kind == TK_STRING) { return 1; } if (T->Kind != TK_OP) { return 0; } static const char *Ops[] = {"[", "{", "*", "&", "-", "+", "~"}; for (size_t I = 0; I < sizeof(Ops) / sizeof(Ops[0]); I++) { if (TokIsOp(T, Ops[I])) { return 1; } } return 0; } /* 括号:空元组 / yield / walrus / 生成器表达式 / 元组 / 普通表达式 */ static PyObject *ParseParen(Parser *P) { Token *Start = NextTok(P); /* '(' */ SkipNL(P); if (AtOp(P, ")")) { NextTok(P); PyObject *Load = MakeCtx(P, "Load"); if (Load == NULL) { return NULL; } PyObject *Empty = NewList(); if (Empty == NULL) { Py_DECREF(Load); return NULL; } PyObject *Argv[2] = { Empty, Load }; PyObject *Node = NewNode(P, "Tuple", Argv, 2); Py_DECREF(Empty); Py_DECREF(Load); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } if (AtName(P, "yield")) { PyObject *YieldNode = ParseYield(P); if (YieldNode == NULL) { return NULL; } SkipNL(P); if (!ExpectOp(P, ")")) { Py_DECREF(YieldNode); return NULL; } return YieldNode; } Token *T0 = PeekTok(P, 0); Token *T1 = PeekTok(P, 1); if (T0->Kind == TK_NAME && T1->Kind == TK_OP && TokIsOp(T1, ":=")) { Token *NameTok = NextTok(P); NextTok(P); /* ':=' */ PyObject *Value = ParseExpr(P); if (Value == NULL) { return NULL; } PyObject *Target = MakeNameNode(P, NameTok, "Store"); if (Target == NULL) { Py_DECREF(Value); return NULL; } SkipNL(P); if (!ExpectOp(P, ")")) { Py_DECREF(Target); Py_DECREF(Value); return NULL; } PyObject *Argv[2] = { Target, Value }; PyObject *Node = NewNode(P, "NamedExpr", Argv, 2); Py_DECREF(Target); Py_DECREF(Value); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } PyObject *First = ParseExpr(P); if (First == NULL) { return NULL; } /* 无括号强转 `(T*)x`:内层表达式以指针后缀结束(_Prev() 即该后缀尾 token), * ')' 紧随其后 → 与 `(T*)(x)` / `T*(x)` 同形,产物为 Call(func = T | t.CPtr)。 */ int IsPtrCast = (P->PtrSuffixTail != NULL && AtOp(P, ")") && PrevTok(P) == P->PtrSuffixTail); SkipNL(P); if (AtName(P, "for")) { PyObject *Generators = ParseComprehensionGenerators(P); if (Generators == NULL) { Py_DECREF(First); return NULL; } SkipNL(P); if (!ExpectOp(P, ")")) { Py_DECREF(Generators); Py_DECREF(First); return NULL; } PyObject *Argv[2] = { First, Generators }; PyObject *Gen = NewNode(P, "GeneratorExp", Argv, 2); Py_DECREF(Generators); Py_DECREF(First); if (Gen != NULL) { FixLoc(P, Gen, Start); } return Gen; } if (AtOp(P, ",")) { PyObject *Elts = NewList(); if (Elts == NULL) { Py_DECREF(First); return NULL; } PyList_Append(Elts, First); while (AtOp(P, ",")) { NextTok(P); SkipNL(P); if (AtOp(P, ")")) { break; } PyObject *E = ParseExpr(P); if (E == NULL) { Py_DECREF(Elts); Py_DECREF(First); return NULL; } PyList_Append(Elts, E); Py_DECREF(E); SkipNL(P); } if (!ExpectOp(P, ")")) { Py_DECREF(Elts); Py_DECREF(First); return NULL; } Py_DECREF(First); PyObject *Load = MakeCtx(P, "Load"); if (Load == NULL) { Py_DECREF(Elts); return NULL; } PyObject *Argv[2] = { Elts, Load }; PyObject *Node = NewNode(P, "Tuple", Argv, 2); Py_DECREF(Elts); Py_DECREF(Load); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } if (!ExpectOp(P, ")")) { Py_DECREF(First); return NULL; } if (IsPtrCast && AtCastOperand(P)) { PyObject *Operand = ParseFactor(P); if (Operand == NULL) { Py_DECREF(First); return NULL; } PyObject *Args = NewList(); PyObject *Kw = NewList(); if (Args == NULL || Kw == NULL) { Py_XDECREF(Args); Py_XDECREF(Kw); Py_DECREF(Operand); Py_DECREF(First); return NULL; } PyList_Append(Args, Operand); Py_DECREF(Operand); PyObject *Argv[3] = { First, Args, Kw }; PyObject *Call = NewNode(P, "Call", Argv, 3); Py_DECREF(Args); Py_DECREF(Kw); Py_DECREF(First); if (Call != NULL) { FixLoc(P, Call, Start); } return Call; } return First; } /* 列表字面量 / 列表推导式 */ static PyObject *ParseList(Parser *P) { Token *Start = NextTok(P); /* '[' */ SkipNL(P); if (AtOp(P, "]")) { NextTok(P); PyObject *Load = MakeCtx(P, "Load"); if (Load == NULL) { return NULL; } PyObject *Empty = NewList(); if (Empty == NULL) { Py_DECREF(Load); return NULL; } PyObject *Argv[2] = { Empty, Load }; PyObject *Node = NewNode(P, "List", Argv, 2); Py_DECREF(Empty); Py_DECREF(Load); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } PyObject *First = ParseExpr(P); if (First == NULL) { return NULL; } SkipNL(P); if (AtName(P, "for")) { PyObject *Generators = ParseComprehensionGenerators(P); if (Generators == NULL) { Py_DECREF(First); return NULL; } SkipNL(P); if (!ExpectOp(P, "]")) { Py_DECREF(Generators); Py_DECREF(First); return NULL; } PyObject *Argv[2] = { First, Generators }; PyObject *Lc = NewNode(P, "ListComp", Argv, 2); Py_DECREF(Generators); Py_DECREF(First); if (Lc != NULL) { FixLoc(P, Lc, Start); } return Lc; } PyObject *Elts = NewList(); if (Elts == NULL) { Py_DECREF(First); return NULL; } PyList_Append(Elts, First); while (AtOp(P, ",")) { NextTok(P); SkipNL(P); if (AtOp(P, "]")) { break; } PyObject *E = ParseExpr(P); if (E == NULL) { Py_DECREF(Elts); Py_DECREF(First); return NULL; } PyList_Append(Elts, E); Py_DECREF(E); SkipNL(P); } if (!ExpectOp(P, "]")) { Py_DECREF(Elts); Py_DECREF(First); return NULL; } Py_DECREF(First); PyObject *Load = MakeCtx(P, "Load"); if (Load == NULL) { Py_DECREF(Elts); return NULL; } PyObject *Argv[2] = { Elts, Load }; PyObject *Node = NewNode(P, "List", Argv, 2); Py_DECREF(Elts); Py_DECREF(Load); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 字典 / 集合字面量与推导式 */ static PyObject *ParseDictSet(Parser *P) { Token *Start = NextTok(P); /* '{' */ SkipNL(P); if (AtOp(P, "}")) { NextTok(P); PyObject *Keys = NewList(); PyObject *Values = NewList(); if (Keys == NULL || Values == NULL) { Py_XDECREF(Keys); Py_XDECREF(Values); return NULL; } PyObject *Argv[2] = { Keys, Values }; PyObject *Node = NewNode(P, "Dict", Argv, 2); Py_DECREF(Keys); Py_DECREF(Values); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } PyObject *Keys = NewList(); PyObject *Values = NewList(); if (Keys == NULL || Values == NULL) { Py_XDECREF(Keys); Py_XDECREF(Values); return NULL; } for (;;) { SkipNL(P); if (AtOp(P, "**")) { NextTok(P); PyObject *Val = ParseExpr(P); if (Val == NULL) { Py_DECREF(Keys); Py_DECREF(Values); return NULL; } PyList_Append(Keys, Py_None); PyList_Append(Values, Val); Py_DECREF(Val); } else { PyObject *Key = ParseExpr(P); if (Key == NULL) { Py_DECREF(Keys); Py_DECREF(Values); return NULL; } SkipNL(P); if (AtOp(P, ":")) { NextTok(P); SkipNL(P); PyObject *Value = ParseExpr(P); if (Value == NULL) { Py_DECREF(Key); Py_DECREF(Keys); Py_DECREF(Values); return NULL; } PyList_Append(Keys, Key); PyList_Append(Values, Value); Py_DECREF(Value); Py_DECREF(Key); } else { /* 集合元素 */ PyObject *Elts = NewList(); if (Elts == NULL) { Py_DECREF(Key); Py_DECREF(Keys); Py_DECREF(Values); return NULL; } PyList_Append(Elts, Key); Py_DECREF(Key); while (AtOp(P, ",")) { NextTok(P); SkipNL(P); if (AtOp(P, "}")) { break; } PyObject *E = ParseExpr(P); if (E == NULL) { Py_DECREF(Elts); Py_DECREF(Keys); Py_DECREF(Values); return NULL; } PyList_Append(Elts, E); Py_DECREF(E); SkipNL(P); } SkipNL(P); if (AtName(P, "for")) { PyObject *Generators = ParseComprehensionGenerators(P); if (Generators == NULL) { Py_DECREF(Elts); Py_DECREF(Keys); Py_DECREF(Values); return NULL; } SkipNL(P); if (!ExpectOp(P, "}")) { Py_DECREF(Generators); Py_DECREF(Elts); Py_DECREF(Keys); Py_DECREF(Values); return NULL; } PyObject *Elt0 = PyList_GET_ITEM(Elts, 0); Py_INCREF(Elt0); PyObject *Argv[2] = { Elt0, Generators }; PyObject *Sc = NewNode(P, "SetComp", Argv, 2); Py_DECREF(Elt0); Py_DECREF(Generators); Py_DECREF(Elts); Py_DECREF(Keys); Py_DECREF(Values); if (Sc != NULL) { FixLoc(P, Sc, Start); } return Sc; } if (!ExpectOp(P, "}")) { Py_DECREF(Elts); Py_DECREF(Keys); Py_DECREF(Values); return NULL; } PyObject *Argv[1] = { Elts }; PyObject *St = NewNode(P, "Set", Argv, 1); Py_DECREF(Elts); Py_DECREF(Keys); Py_DECREF(Values); if (St != NULL) { FixLoc(P, St, Start); } return St; } } SkipNL(P); if (AtOp(P, ",")) { NextTok(P); SkipNL(P); if (AtOp(P, "}")) { break; } continue; } break; } /* 字典推导式 */ SkipNL(P); if (AtName(P, "for")) { PyObject *Generators = ParseComprehensionGenerators(P); if (Generators == NULL) { Py_DECREF(Keys); Py_DECREF(Values); return NULL; } SkipNL(P); if (!ExpectOp(P, "}")) { Py_DECREF(Generators); Py_DECREF(Keys); Py_DECREF(Values); return NULL; } PyObject *Key0 = PyList_GET_ITEM(Keys, 0); PyObject *Val0 = PyList_GET_ITEM(Values, 0); PyObject *KeyObj; if (Key0 == Py_None) { KeyObj = MakeConstant(P, Py_None); if (KeyObj == NULL) { Py_DECREF(Generators); Py_DECREF(Keys); Py_DECREF(Values); return NULL; } } else { KeyObj = Key0; Py_INCREF(KeyObj); } Py_INCREF(Val0); PyObject *Argv[3] = { KeyObj, Val0, Generators }; PyObject *Dc = NewNode(P, "DictComp", Argv, 3); Py_DECREF(KeyObj); Py_DECREF(Val0); Py_DECREF(Generators); Py_DECREF(Keys); Py_DECREF(Values); if (Dc != NULL) { FixLoc(P, Dc, Start); } return Dc; } if (!ExpectOp(P, "}")) { Py_DECREF(Keys); Py_DECREF(Values); return NULL; } PyObject *Argv[2] = { Keys, Values }; PyObject *Node = NewNode(P, "Dict", Argv, 2); Py_DECREF(Keys); Py_DECREF(Values); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 推导式生成器子句:for target in iter [if cond]* [async for ...] */ static PyObject *ParseComprehensionGenerators(Parser *P) { PyObject *Generators = NewList(); if (Generators == NULL) { return NULL; } for (;;) { int IsAsync = 0; if (AtName(P, "async") && PeekTok(P, 1)->Kind == TK_NAME && TokIsName(PeekTok(P, 1), "for")) { NextTok(P); IsAsync = 1; } if (!AtName(P, "for")) { break; } Token *Start = NextTok(P); PyObject *Target = ParseComprehensionTarget(P); if (Target == NULL) { Py_DECREF(Generators); return NULL; } if (!ExpectName(P, "in")) { Py_DECREF(Target); Py_DECREF(Generators); return NULL; } PyObject *Iterable = ParseDisjunction(P); if (Iterable == NULL) { Py_DECREF(Target); Py_DECREF(Generators); return NULL; } PyObject *Ifs = NewList(); if (Ifs == NULL) { Py_DECREF(Target); Py_DECREF(Iterable); Py_DECREF(Generators); return NULL; } while (AtName(P, "if")) { NextTok(P); PyObject *Cond = ParseDisjunction(P); if (Cond == NULL) { Py_DECREF(Target); Py_DECREF(Iterable); Py_DECREF(Ifs); Py_DECREF(Generators); return NULL; } PyList_Append(Ifs, Cond); Py_DECREF(Cond); } PyObject *IsAsyncObj = PyLong_FromLong(IsAsync); PyObject *Argv[4] = { Target, Iterable, Ifs, IsAsyncObj }; PyObject *Comp = NewNode(P, "comprehension", Argv, 4); Py_DECREF(IsAsyncObj); Py_DECREF(Target); Py_DECREF(Iterable); Py_DECREF(Ifs); if (Comp == NULL) { Py_DECREF(Generators); return NULL; } /* comprehension 无位置属性,不调用 FixLoc */ (void)Start; PyList_Append(Generators, Comp); Py_DECREF(Comp); if (AtName(P, "for") || (AtName(P, "async") && PeekTok(P, 1)->Kind == TK_NAME && TokIsName(PeekTok(P, 1), "for"))) { continue; } break; } return Generators; } /* 推导式 for 目标(支持裸元组解包) */ static PyObject *ParseComprehensionTarget(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *First = ParseTarget(P); if (First == NULL) { return NULL; } if (!AtOp(P, ",")) { return First; } PyObject *Elts = NewList(); if (Elts == NULL) { Py_DECREF(First); return NULL; } PyList_Append(Elts, First); while (AtOp(P, ",")) { NextTok(P); SkipNL(P); PyObject *E = ParseTarget(P); if (E == NULL) { Py_DECREF(Elts); Py_DECREF(First); return NULL; } PyList_Append(Elts, E); Py_DECREF(E); } Py_DECREF(First); PyObject *Store = MakeCtx(P, "Store"); if (Store == NULL) { Py_DECREF(Elts); return NULL; } PyObject *Argv[2] = { Elts, Store }; PyObject *Node = NewNode(P, "Tuple", Argv, 2); Py_DECREF(Elts); Py_DECREF(Store); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 赋值目标(Store 上下文) */ static PyObject *ParseTarget(Parser *P) { Token *Start = PeekTok(P, 0); if (AtOp(P, "(")) { NextTok(P); SkipNL(P); PyObject *Elts = NewList(); if (Elts == NULL) { return NULL; } if (!AtOp(P, ")")) { for (;;) { PyObject *E = ParseTarget(P); if (E == NULL) { Py_DECREF(Elts); return NULL; } PyList_Append(Elts, E); Py_DECREF(E); SkipNL(P); if (AtOp(P, ",")) { NextTok(P); SkipNL(P); if (AtOp(P, ")")) { break; } continue; } break; } } if (!ExpectOp(P, ")")) { Py_DECREF(Elts); return NULL; } PyObject *Store = MakeCtx(P, "Store"); if (Store == NULL) { Py_DECREF(Elts); return NULL; } PyObject *Argv[2] = { Elts, Store }; PyObject *Node = NewNode(P, "Tuple", Argv, 2); Py_DECREF(Elts); Py_DECREF(Store); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } if (AtOp(P, "[")) { NextTok(P); SkipNL(P); PyObject *Elts = NewList(); if (Elts == NULL) { return NULL; } if (!AtOp(P, "]")) { for (;;) { PyObject *E = ParseTarget(P); if (E == NULL) { Py_DECREF(Elts); return NULL; } PyList_Append(Elts, E); Py_DECREF(E); SkipNL(P); if (AtOp(P, ",")) { NextTok(P); SkipNL(P); if (AtOp(P, "]")) { break; } continue; } break; } } if (!ExpectOp(P, "]")) { Py_DECREF(Elts); return NULL; } PyObject *Store = MakeCtx(P, "Store"); if (Store == NULL) { Py_DECREF(Elts); return NULL; } PyObject *Argv[2] = { Elts, Store }; PyObject *Node = NewNode(P, "List", Argv, 2); Py_DECREF(Elts); Py_DECREF(Store); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } if (AtOp(P, "*")) { NextTok(P); PyObject *Value = ParseTarget(P); if (Value == NULL) { return NULL; } PyObject *Store = MakeCtx(P, "Store"); if (Store == NULL) { Py_DECREF(Value); return NULL; } PyObject *Argv[2] = { Value, Store }; PyObject *Node = NewNode(P, "Starred", Argv, 2); Py_DECREF(Value); Py_DECREF(Store); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } Token *T = PeekTok(P, 0); if (T->Kind == TK_NAME) { NextTok(P); /* 必须消费名字 token */ return MakeNameNode(P, T, "Store"); } /* 属性/下标目标:解析 Load 后改 Store */ PyObject *Node = ParsePrimary(P); if (Node == NULL) { return NULL; } SetStoreContext(P, Node); return Node; } /* lambda */ static PyObject *ParseLambda(Parser *P) { Token *Start = NextTok(P); /* 'lambda' */ PyObject *Args; if (AtOp(P, ":")) { PyObject *E1 = NewList(); PyObject *E2 = NewList(); if (E1 == NULL || E2 == NULL) { Py_XDECREF(E1); Py_XDECREF(E2); return NULL; } PyObject *Argv[7]; Argv[0] = E1; /* posonlyargs */ Argv[1] = E2; /* args */ Argv[2] = Py_None; /* vararg */ Argv[3] = NewList(); /* kwonlyargs */ Argv[4] = NewList(); /* kw_defaults */ Argv[5] = Py_None; /* kwarg */ Argv[6] = NewList(); /* defaults */ if (Argv[3] == NULL || Argv[4] == NULL || Argv[6] == NULL) { Py_XDECREF(E1); Py_XDECREF(E2); Py_XDECREF(Argv[3]); Py_XDECREF(Argv[4]); Py_XDECREF(Argv[6]); return NULL; } Args = NewNode(P, "arguments", Argv, 7); Py_DECREF(E1); Py_DECREF(E2); Py_DECREF(Argv[3]); Py_DECREF(Argv[4]); Py_DECREF(Argv[6]); if (Args == NULL) { return NULL; } } else { Args = ParseArguments(P, 1, 1); if (Args == NULL) { return NULL; } } if (!ExpectOp(P, ":")) { Py_DECREF(Args); return NULL; } PyObject *Body = ParseExpr(P); if (Body == NULL) { Py_DECREF(Args); return NULL; } PyObject *Argv[2] = { Args, Body }; PyObject *Node = NewNode(P, "Lambda", Argv, 2); Py_DECREF(Args); Py_DECREF(Body); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* yield 表达式 */ static PyObject *ParseYield(Parser *P) { Token *Start = NextTok(P); /* 'yield' */ if (AtName(P, "from")) { NextTok(P); PyObject *Value = ParseExpr(P); if (Value == NULL) { return NULL; } PyObject *Argv[1] = { Value }; PyObject *Node = NewNode(P, "YieldFrom", Argv, 1); Py_DECREF(Value); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } if (AtOp(P, ")")) { PyObject *Node = NewNode(P, "Yield", (PyObject *[]){ Py_None }, 1); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } PyObject *Value = ParseExprList(P); if (Value == NULL) { return NULL; } PyObject *Argv[1] = { Value }; PyObject *Node = NewNode(P, "Yield", Argv, 1); Py_DECREF(Value); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 参数列表(lambda 与函数定义共用) */ static PyObject *ParseArguments(Parser *P, int SkipOpen, int AllowLambda) { if (!SkipOpen) { if (!ExpectOp(P, "(")) { return NULL; } } SkipNL(P); PyObject *PosonlyArgs = NewList(); PyObject *Args = NewList(); PyObject *KwonlyArgs = NewList(); PyObject *KwDefaults = NewList(); PyObject *OrderedArgs = NewList(); PyObject *OrderedDefaults = NewList(); PyObject *Vararg = NULL; PyObject *Kwarg = NULL; if (PosonlyArgs == NULL || Args == NULL || KwonlyArgs == NULL || KwDefaults == NULL || OrderedArgs == NULL || OrderedDefaults == NULL) { Py_XDECREF(PosonlyArgs); Py_XDECREF(Args); Py_XDECREF(KwonlyArgs); Py_XDECREF(KwDefaults); Py_XDECREF(OrderedArgs); Py_XDECREF(OrderedDefaults); return NULL; } int SeenStar = 0; if (!AtOp(P, ")")) { for (;;) { SkipNL(P); Token *T = PeekTok(P, 0); if (TokIsOp(T, ")")) { break; } if (TokIsOp(T, "*")) { NextTok(P); if (AtOp(P, ",")) { SeenStar = 1; NextTok(P); if (AtOp(P, ")") || AtOp(P, ":")) { break; } continue; } Vararg = ParseArg(P, !AllowLambda); if (Vararg == NULL) { Py_DECREF(PosonlyArgs); Py_DECREF(Args); Py_DECREF(KwonlyArgs); Py_DECREF(KwDefaults); Py_DECREF(OrderedArgs); Py_DECREF(OrderedDefaults); return NULL; } SeenStar = 1; } else if (TokIsOp(T, "**")) { NextTok(P); Kwarg = ParseArg(P, !AllowLambda); if (Kwarg == NULL) { Py_DECREF(PosonlyArgs); Py_DECREF(Args); Py_DECREF(KwonlyArgs); Py_DECREF(KwDefaults); Py_DECREF(OrderedArgs); Py_DECREF(OrderedDefaults); return NULL; } } else { PyObject *A = ParseArg(P, !AllowLambda); if (A == NULL) { Py_DECREF(PosonlyArgs); Py_DECREF(Args); Py_DECREF(KwonlyArgs); Py_DECREF(KwDefaults); Py_DECREF(OrderedArgs); Py_DECREF(OrderedDefaults); return NULL; } PyObject *Def = Py_None; if (AtOp(P, "=")) { NextTok(P); Def = ParseExpr(P); if (Def == NULL) { Py_DECREF(A); Py_DECREF(PosonlyArgs); Py_DECREF(Args); Py_DECREF(KwonlyArgs); Py_DECREF(KwDefaults); Py_DECREF(OrderedArgs); Py_DECREF(OrderedDefaults); return NULL; } } if (SeenStar) { PyList_Append(KwonlyArgs, A); PyList_Append(KwDefaults, Def); } else { PyList_Append(OrderedArgs, A); PyList_Append(OrderedDefaults, Def); } Py_DECREF(A); Py_XDECREF(Def != Py_None ? Def : NULL); } SkipNL(P); if (AtOp(P, ",")) { NextTok(P); if (AtOp(P, ")")) { break; } continue; } break; } } Py_ssize_t NOrdered = PyList_GET_SIZE(OrderedArgs); int LastNone = -1; for (Py_ssize_t I = 0; I < NOrdered; I++) { if (PyList_GET_ITEM(OrderedDefaults, I) == Py_None) { LastNone = (int)I; } } for (Py_ssize_t I = 0; I < NOrdered; I++) { PyList_Append(Args, PyList_GET_ITEM(OrderedArgs, I)); } PyObject *Defaults = NewList(); if (Defaults == NULL) { Py_DECREF(PosonlyArgs); Py_DECREF(Args); Py_DECREF(KwonlyArgs); Py_DECREF(KwDefaults); Py_DECREF(OrderedArgs); Py_DECREF(OrderedDefaults); Py_XDECREF(Vararg); Py_XDECREF(Kwarg); return NULL; } for (int I = LastNone + 1; I < (int)NOrdered; I++) { PyObject *D = PyList_GET_ITEM(OrderedDefaults, I); if (D != Py_None) { PyList_Append(Defaults, D); } } SkipNL(P); if (!SkipOpen) { if (!ExpectOp(P, ")")) { Py_DECREF(PosonlyArgs); Py_DECREF(Args); Py_DECREF(KwonlyArgs); Py_DECREF(KwDefaults); Py_DECREF(OrderedArgs); Py_DECREF(OrderedDefaults); Py_DECREF(Defaults); Py_XDECREF(Vararg); Py_XDECREF(Kwarg); return NULL; } } PyObject *Argv[7]; Argv[0] = PosonlyArgs; Argv[1] = Args; Argv[2] = Vararg ? Vararg : Py_None; Argv[3] = KwonlyArgs; Argv[4] = KwDefaults; Argv[5] = Kwarg ? Kwarg : Py_None; Argv[6] = Defaults; PyObject *Node = NewNode(P, "arguments", Argv, 7); Py_DECREF(PosonlyArgs); Py_DECREF(Args); Py_DECREF(KwonlyArgs); Py_DECREF(KwDefaults); Py_DECREF(OrderedArgs); Py_DECREF(OrderedDefaults); Py_DECREF(Defaults); Py_XDECREF(Vararg); Py_XDECREF(Kwarg); return Node; } /* 单个参数:name [':' annotation] */ static PyObject *ParseArg(Parser *P, int AllowAnnotation) { Token *Start = ExpectName(P, NULL); if (Start == NULL) { return NULL; } PyObject *Annotation = NULL; if (AllowAnnotation && AtOp(P, ":")) { NextTok(P); Annotation = ParseTypeAnnotation(P); if (Annotation == NULL) { return NULL; } } PyObject *Arg = PyUnicode_FromStringAndSize(Start->Start, Start->End - Start->Start); if (Arg == NULL) { Py_XDECREF(Annotation); return NULL; } PyObject *Argv[3] = { Arg, Annotation ? Annotation : Py_None, Py_None }; PyObject *Node = NewNode(P, "arg", Argv, 3); Py_DECREF(Arg); Py_XDECREF(Annotation); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* ================= 语句解析 ================= */ static PyObject *ParseStatement(Parser *P); static PyObject *ParseSimpleStmt(Parser *P); static PyObject *ParseSuite(Parser *P); static PyObject *ParseSuiteOwned(Parser *P, int OwnerIsClass); static PyObject *ParseIf(Parser *P); static PyObject *ParseCIf(Parser *P); static PyObject *ParseCelif(Parser *P); static PyObject *ParseCIfChainTail(Parser *P); static PyObject *MakeCifMarkerCall(Parser *P, const char *AttrName, PyObject *Expr, Token *Start); static int IsCIfStatementStart(Parser *P); static PyObject *DesugarSpecialCall(Parser *P, PyObject *Node, Token *Start); static PyObject *ParseWhile(Parser *P); static PyObject *ParseFor(Parser *P, int IsAsync); static PyObject *ParseTry(Parser *P); static PyObject *ParseWith(Parser *P, int IsAsync); static PyObject *ParseMatch(Parser *P); static PyObject *ParseSwitch(Parser *P); static PyObject *ParseFallThrough(Parser *P); static int SwitchPatAllowed(PyObject *Pat); static PyObject *ParseFunctionDef(Parser *P, int IsAsync, PyObject *Decorators); static PyObject *ParseClassDef(Parser *P, PyObject *Decorators); static PyObject *ParseExprList(Parser *P); static PyObject *ParseExternDef(Parser *P, int IsExport, PyObject *Decorators); static int IsStorageVarStart(Parser *P); static PyObject *ParseStorageVar(Parser *P, const char *Marker); static PyObject *ParseDefineVar(Parser *P); static PyObject *ParseTypedefVar(Parser *P); static PyObject *TryParseAnnAssign(Parser *P); static PyObject *ParseExprStmt(Parser *P); static PyObject *ParseImport(Parser *P); static PyObject *ParseImportFrom(Parser *P); static PyObject *ParseImportAlias(Parser *P); static PyObject *ParseGlobal(Parser *P, const char *NodeName); static PyObject *ParseDelete(Parser *P); static PyObject *ParseAssert(Parser *P); static PyObject *ParseDecorated(Parser *P); static PyObject *ParseVirtualModified(Parser *P, PyObject *Decorators); static PyObject *ParseStructDef(Parser *P, PyObject *Decorators); static PyObject *ParseTypeParams(Parser *P); static PyObject *ParseExceptHandler(Parser *P); static PyObject *ParseTargetList(Parser *P); static PyObject *MakeTAttrNode(Parser *P, const char *AttrName); /* 模块:语句序列 */ static PyObject *ParseModule(Parser *P) { PyObject *Body = NewList(); if (Body == NULL) { return NULL; } SkipNEWLINE(P); while (PeekTok(P, 0)->Kind != TK_ENDMARKER) { PyObject *Stmt = ParseStatement(P); if (Stmt == NULL) { Py_DECREF(Body); return NULL; } PyList_Append(Body, Stmt); Py_DECREF(Stmt); while (AtOp(P, ";")) { NextTok(P); if (PeekTok(P, 0)->Kind == TK_NEWLINE) { break; } PyObject *Extra = ParseStatement(P); if (Extra == NULL) { Py_DECREF(Body); return NULL; } PyList_Append(Body, Extra); Py_DECREF(Extra); } SkipNEWLINE(P); } PyObject *Ti = NewList(); if (Ti == NULL) { Py_DECREF(Body); return NULL; } PyObject *Argv[2] = { Body, Ti }; PyObject *Mod = NewNode(P, "Module", Argv, 2); Py_DECREF(Body); Py_DECREF(Ti); return Mod; } /* 语句分派(对齐 vast Parser.ParseStatement) */ static PyObject *ParseStatement(Parser *P) { Token *T = PeekTok(P, 0); if (T->Kind == TK_NAME) { if (TokIsName(T, "extern")) { if (IsStorageVarStart(P)) { return ParseStorageVar(P, "extern"); } return ParseExternDef(P, 0, NULL); } if (TokIsName(T, "export")) { if (IsStorageVarStart(P)) { return ParseStorageVar(P, "export"); } return ParseExternDef(P, 1, NULL); } if (TokIsName(T, "static") && IsStorageVarStart(P)) { return ParseStorageVar(P, "static"); } if (TokIsName(T, "inline") && IsStorageVarStart(P)) { return ParseStorageVar(P, "inline"); } if (TokIsName(T, "define") && PeekTok(P, 1)->Kind == TK_NAME) { if (IsStorageVarStart(P)) { return ParseDefineVar(P); } return ParseFunctionDef(P, 0, NULL); } if (TokIsName(T, "typedef") && PeekTok(P, 1)->Kind == TK_NAME) { return ParseTypedefVar(P); } if (TokIsName(T, "virtual") || TokIsName(T, "novirtual")) { return ParseVirtualModified(P, NULL); } if ((TokIsName(T, "fn") || TokIsName(T, "fun") || TokIsName(T, "func") || TokIsName(T, "function")) && PeekTok(P, 1)->Kind == TK_NAME) { return ParseFunctionDef(P, 0, NULL); } if (TokIsName(T, "async")) { Token *N = PeekTok(P, 1); if (N->Kind == TK_NAME && TokIsName(N, "def")) { return ParseFunctionDef(P, 1, NULL); } if (N->Kind == TK_NAME && TokIsName(N, "for")) { return ParseFor(P, 1); } if (N->Kind == TK_NAME && TokIsName(N, "with")) { return ParseWith(P, 1); } } if (TokIsName(T, "def")) { return ParseFunctionDef(P, 0, NULL); } if (TokIsName(T, "class")) { return ParseClassDef(P, NULL); } /* struct 纯数据类型定义(硬关键字:语句起始一律按 struct 定义解析) */ if (TokIsName(T, "struct")) { return ParseStructDef(P, NULL); } /* cif 编译期条件编译(软关键字):语句起始 + 非赋值/注解形态 */ if (TokIsName(T, "cif") && IsCIfStatementStart(P)) { return ParseCIf(P); } /* celif / celse 必须属于某条 cif 链(由 ParseCIf 直接消费); * 语句起始独立出现 ⇒ FailFast */ if (TokIsName(T, "celif")) { SyntaxErrorAt(P, T, "'celif' must belong to a 'cif' chain (no matching 'cif')"); return NULL; } if (TokIsName(T, "celse")) { SyntaxErrorAt(P, T, "'celse' must belong to a 'cif' chain (no matching 'cif')"); return NULL; } if (TokIsName(T, "if")) { return ParseIf(P); } if (TokIsName(T, "while")) { return ParseWhile(P); } if (TokIsName(T, "for")) { return ParseFor(P, 0); } if (TokIsName(T, "try")) { return ParseTry(P); } if (TokIsName(T, "with")) { return ParseWith(P, 0); } /* match 多模式匹配(硬关键字:语句起始一律按 match 语句解析) */ if (TokIsName(T, "match")) { return ParseMatch(P); } /* switch 多分支(硬关键字,C switch 语义):desugar 为 is_switch=True 的 Match */ if (TokIsName(T, "switch")) { return ParseSwitch(P); } /* fallthrough 关键字(硬):仅在 switch 的 case 体内合法,脱糖为 * `c.NoBreak()` 标记调用,由 switch 生成侧消费 */ if (TokIsName(T, "fallthrough")) { return ParseFallThrough(P); } if (TokIsName(T, "return")) { Token *Start = NextTok(P); PyObject *Value = NULL; if (PeekTok(P, 0)->Kind != TK_NEWLINE && !AtOp(P, ";")) { Value = ParseExprList(P); if (Value == NULL) { return NULL; } } PyObject *Argv[1] = { Value ? Value : Py_None }; PyObject *Node = NewNode(P, "Return", Argv, 1); Py_XDECREF(Value); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } if (TokIsName(T, "raise")) { Token *Start = NextTok(P); PyObject *Exc = NULL; PyObject *Cause = NULL; if (PeekTok(P, 0)->Kind != TK_NEWLINE && !AtOp(P, ";")) { Exc = ParseExpr(P); if (Exc == NULL) { return NULL; } if (AtName(P, "from")) { NextTok(P); Cause = ParseExpr(P); if (Cause == NULL) { Py_DECREF(Exc); return NULL; } } } PyObject *Argv[2] = { Exc ? Exc : Py_None, Cause ? Cause : Py_None }; PyObject *Node = NewNode(P, "Raise", Argv, 2); Py_XDECREF(Exc); Py_XDECREF(Cause); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } if (TokIsName(T, "import")) { return ParseImport(P); } if (TokIsName(T, "from")) { return ParseImportFrom(P); } if (TokIsName(T, "global")) { return ParseGlobal(P, "Global"); } if (TokIsName(T, "nonlocal")) { return ParseGlobal(P, "Nonlocal"); } if (TokIsName(T, "del")) { return ParseDelete(P); } if (TokIsName(T, "assert")) { return ParseAssert(P); } if (TokIsName(T, "pass")) { Token *Start = NextTok(P); PyObject *Node = NewNode(P, "Pass", NULL, 0); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } if (TokIsName(T, "break")) { Token *Start = NextTok(P); PyObject *Node = NewNode(P, "Break", NULL, 0); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } if (TokIsName(T, "continue")) { Token *Start = NextTok(P); PyObject *Node = NewNode(P, "Continue", NULL, 0); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } if (TokIsName(T, "yield")) { return ParseExprStmt(P); } } if (T->Kind == TK_OP && TokIsOp(T, "@")) { return ParseDecorated(P); } return ParseSimpleStmt(P); } /* 简单语句:AnnAssign / Assign / AugAssign / Expr */ static PyObject *ParseSimpleStmt(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *Ann = TryParseAnnAssign(P); if (Ann != NULL) { return Ann; } if (P->Error || PyErr_Occurred()) { return NULL; } PyObject *Expr = ParseExprList(P); if (Expr == NULL) { return NULL; } /* 赋值链 */ if (AtOp(P, "=")) { PyObject *Targets = NewList(); if (Targets == NULL) { Py_DECREF(Expr); return NULL; } SetStoreContext(P, Expr); PyList_Append(Targets, Expr); for (;;) { NextTok(P); /* '=' */ PyObject *Value = ParseExprList(P); if (Value == NULL) { Py_DECREF(Targets); Py_DECREF(Expr); return NULL; } if (AtOp(P, "=")) { SetStoreContext(P, Value); PyList_Append(Targets, Value); Py_DECREF(Value); continue; } Py_DECREF(Expr); PyObject *Argv[3] = { Targets, Value, Py_None }; PyObject *Node = NewNode(P, "Assign", Argv, 3); Py_DECREF(Targets); Py_DECREF(Value); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } } /* 增强赋值 */ static const struct { const char *Op; const char *NodeName; } AugOps[] = { {"+=", "Add"}, {"-=", "Sub"}, {"*=", "Mult"}, {"/=", "Div"}, {"//=", "FloorDiv"}, {"%=", "Mod"}, {"**=", "Pow"}, {"<<=", "LShift"}, {">>=", "RShift"}, {"&=", "BitAnd"}, {"|=", "BitOr"}, {"^=", "BitXor"}, {"@=", "MatMult"}, }; for (Py_ssize_t I = 0; I < (Py_ssize_t)(sizeof(AugOps) / sizeof(AugOps[0])); I++) { if (AtOp(P, AugOps[I].Op)) { NextTok(P); PyObject *Value = ParseExpr(P); if (Value == NULL) { Py_DECREF(Expr); return NULL; } SetStoreContext(P, Expr); PyObject *Op = MakeSingleton(P, AugOps[I].NodeName); if (Op == NULL) { Py_DECREF(Expr); Py_DECREF(Value); return NULL; } PyObject *Argv[3] = { Expr, Op, Value }; PyObject *Node = NewNode(P, "AugAssign", Argv, 3); Py_DECREF(Op); Py_DECREF(Value); Py_DECREF(Expr); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } } PyObject *Argv[1] = { Expr }; PyObject *Node = NewNode(P, "Expr", Argv, 1); Py_DECREF(Expr); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 注解是否为 typedef 标记(裸 CTypedef / t.CTypedef / 含它的 `|` 联合)。 * 用于把 typedef 的右值按类型位置解析(`X: t.CTypedef = const uint16*` 的 `*` 后缀 * 由 ParseTypeAnnotation 消费),与 Python vast Parser._IsCTypedefAnnotation 同口径。 */ static int IsCTypedefAnnotation(PyObject *Ann) { if (Ann == NULL || Ann == Py_None) { return 0; } if (NodeIs(Ann, "Name") || NodeIs(Ann, "Attribute")) { const char *Field = NodeIs(Ann, "Name") ? "id" : "attr"; PyObject *V = PyObject_GetAttrString(Ann, Field); int Hit = 0; if (V != NULL) { if (PyUnicode_Check(V) && PyUnicode_CompareWithASCIIString(V, "CTypedef") == 0) { Hit = 1; } Py_DECREF(V); } else { PyErr_Clear(); } return Hit; } if (NodeIs(Ann, "BinOp")) { int Hit = 0; PyObject *L = PyObject_GetAttrString(Ann, "left"); if (L != NULL) { Hit = IsCTypedefAnnotation(L); Py_DECREF(L); } else { PyErr_Clear(); } if (!Hit) { PyObject *R = PyObject_GetAttrString(Ann, "right"); if (R != NULL) { Hit = IsCTypedefAnnotation(R); Py_DECREF(R); } else { PyErr_Clear(); } } return Hit; } return 0; } /* 语句级变量声明判据:`修饰词 名字 :` 或 `修饰词 名字 =` * (对齐 vast Parser._IsStorageVarStart)。 */ static int IsStorageVarStart(Parser *P) { if (PeekTok(P, 1)->Kind != TK_NAME) { return 0; } Token *Next = PeekTok(P, 2); return Next->Kind == TK_OP && (TokIsOp(Next, ":") || TokIsOp(Next, "=")); } /* 构造 AnnAssign(target, annotation, value, simple=1) 并设置位置。 */ static PyObject *MakeAnnAssignSimple(Parser *P, Token *Start, Token *NameTok, PyObject *Annotation, PyObject *Value) { PyObject *Target = MakeNameNode(P, NameTok, "Store"); if (Target == NULL) { return NULL; } PyObject *Simple = PyLong_FromLong(1); if (Simple == NULL) { Py_DECREF(Target); return NULL; } PyObject *Argv[4] = { Target, Annotation, Value ? Value : Py_None, Simple }; PyObject *Node = NewNode(P, "AnnAssign", Argv, 4); Py_DECREF(Simple); Py_DECREF(Target); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* `static|export|extern|inline 名字: 类型 [= 初值]` → AnnAssign(extern 禁止初值)。 * 对齐 vast Parser._ParseStorageVar。 */ static PyObject *ParseStorageVar(Parser *P, const char *Marker) { Token *Start = NextTok(P); /* 修饰词 */ Token *NameTok = ExpectName(P, NULL); if (NameTok == NULL) { return NULL; } if (!AtOp(P, ":")) { SyntaxErrorAt(P, PeekTok(P, 0), "storage variable declaration requires a type annotation"); return NULL; } NextTok(P); /* ':' */ PyObject *Annotation = ParseTypeAnnotation(P); if (Annotation == NULL) { return NULL; } PyObject *Value = NULL; if (AtOp(P, "=")) { if (strcmp(Marker, "extern") == 0) { SyntaxErrorAt(P, PeekTok(P, 0), "extern variable declaration cannot have an initializer"); Py_DECREF(Annotation); return NULL; } NextTok(P); /* '=' */ Value = ParseExpr(P); if (Value == NULL) { Py_DECREF(Annotation); return NULL; } } AddTypeMarkers(Annotation, Marker); PyObject *Node = MakeAnnAssignSimple(P, Start, NameTok, Annotation, Value); Py_DECREF(Annotation); Py_XDECREF(Value); return Node; } /* `define 名字[: 类型] = 值` → AnnAssign;未标注类型时注解占位 Name('CDefine')。 * 对齐 vast Parser._ParseDefineVar。 */ static PyObject *ParseDefineVar(Parser *P) { Token *Start = NextTok(P); /* 'define' */ Token *NameTok = ExpectName(P, NULL); if (NameTok == NULL) { return NULL; } PyObject *Annotation = NULL; if (AtOp(P, ":")) { NextTok(P); Annotation = ParseTypeAnnotation(P); if (Annotation == NULL) { return NULL; } } if (!AtOp(P, "=")) { SyntaxErrorAt(P, PeekTok(P, 0), "define constant declaration requires an initializer"); Py_XDECREF(Annotation); return NULL; } NextTok(P); /* '=' */ PyObject *Value = ParseExpr(P); if (Value == NULL) { Py_XDECREF(Annotation); return NULL; } if (Annotation == NULL) { Annotation = MakeTAttrNode(P, "CDefine"); if (Annotation == NULL) { Py_DECREF(Value); return NULL; } FixLoc(P, Annotation, Start); } AddTypeMarkers(Annotation, "define"); PyObject *Node = MakeAnnAssignSimple(P, Start, NameTok, Annotation, Value); Py_DECREF(Annotation); Py_DECREF(Value); return Node; } /* `typedef 名字 = 类型` → AnnAssign(annotation 与 value 同一节点)。 * 对齐 vast Parser._ParseTypedefVar。 */ static PyObject *ParseTypedefVar(Parser *P) { Token *Start = NextTok(P); /* 'typedef' */ Token *NameTok = ExpectName(P, NULL); if (NameTok == NULL) { return NULL; } if (!AtOp(P, "=")) { SyntaxErrorAt(P, PeekTok(P, 0), "typedef syntax error: expected `typedef NAME = type`"); return NULL; } NextTok(P); /* '=' */ PyObject *TypeNode = ParseTypeAnnotation(P); if (TypeNode == NULL) { return NULL; } AddTypeMarkers(TypeNode, "typedef"); PyObject *Node = MakeAnnAssignSimple(P, Start, NameTok, TypeNode, TypeNode); Py_DECREF(TypeNode); return Node; } /* 尝试解析带注解赋值(对齐 vast _TryParseAnnAssign) */ static PyObject *TryParseAnnAssign(Parser *P) { Token *Start = PeekTok(P, 0); Token *T0 = PeekTok(P, 0); Token *T1 = PeekTok(P, 1); if (T0->Kind == TK_NAME && T1->Kind == TK_OP && TokIsOp(T1, ":")) { Token *NameTok = NextTok(P); NextTok(P); /* ':' */ PyObject *Annotation = ParseTypeAnnotation(P); if (Annotation == NULL) { return NULL; } PyObject *Value = NULL; if (AtOp(P, "=")) { NextTok(P); /* A typedef's RHS is a type (`const str` / `uint16*`), not a general expression. */ Value = IsCTypedefAnnotation(Annotation) ? ParseTypeAnnotation(P) : ParseExpr(P); if (Value == NULL) { Py_DECREF(Annotation); return NULL; } } PyObject *Target = MakeNameNode(P, NameTok, "Store"); if (Target == NULL) { Py_DECREF(Annotation); Py_XDECREF(Value); return NULL; } PyObject *Argv[4] = { Target, Annotation, Value ? Value : Py_None, PyLong_FromLong(1) }; PyObject *Node = NewNode(P, "AnnAssign", Argv, 4); Py_DECREF(Argv[3]); Py_DECREF(Target); Py_DECREF(Annotation); Py_XDECREF(Value); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } if (T0->Kind == TK_NAME || (T0->Kind == TK_OP && (TokIsOp(T0, "(") || TokIsOp(T0, "[")))) { int SaveIdx = P->Idx; int SaveError = P->Error; PyObject *Expr = ParseExpr(P); if (Expr == NULL) { if (PyErr_Occurred()) { return NULL; } P->Idx = SaveIdx; P->Error = SaveError; return NULL; } if (AtOp(P, ":") && IsNameOrAttrOrSub(Expr)) { NextTok(P); PyObject *Annotation = ParseTypeAnnotation(P); if (Annotation == NULL) { Py_DECREF(Expr); return NULL; } PyObject *Value = NULL; if (AtOp(P, "=")) { NextTok(P); /* A typedef's RHS is a type (`const str` / `uint16*`). */ Value = IsCTypedefAnnotation(Annotation) ? ParseTypeAnnotation(P) : ParseExpr(P); if (Value == NULL) { Py_DECREF(Annotation); Py_DECREF(Expr); return NULL; } } SetStoreContext(P, Expr); int Simple = NodeIs(Expr, "Name") ? 1 : 0; PyObject *Argv[4] = { Expr, Annotation, Value ? Value : Py_None, PyLong_FromLong(Simple) }; PyObject *Node = NewNode(P, "AnnAssign", Argv, 4); Py_DECREF(Argv[3]); Py_DECREF(Annotation); Py_XDECREF(Value); Py_DECREF(Expr); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } P->Idx = SaveIdx; P->Error = SaveError; Py_DECREF(Expr); } return NULL; } /* 表达式语句(含 yield) */ static PyObject *ParseExprStmt(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *Expr; if (AtName(P, "yield")) { Expr = ParseYield(P); } else { Expr = ParseExprList(P); } if (Expr == NULL) { return NULL; } PyObject *Argv[1] = { Expr }; PyObject *Node = NewNode(P, "Expr", Argv, 1); Py_DECREF(Expr); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* import a.b.c [as x], ... */ static PyObject *ParseImport(Parser *P) { Token *Start = NextTok(P); /* 'import' */ PyObject *Names = NewList(); if (Names == NULL) { return NULL; } for (;;) { Token *NameTok = ExpectName(P, NULL); if (NameTok == NULL) { Py_DECREF(Names); return NULL; } Token *EndTok = NameTok; PyObject *Parts = PyList_New(0); if (Parts == NULL) { Py_DECREF(Names); return NULL; } PyObject *FirstPart = PyUnicode_FromStringAndSize(NameTok->Start, NameTok->End - NameTok->Start); if (FirstPart == NULL) { Py_DECREF(Parts); Py_DECREF(Names); return NULL; } PyList_Append(Parts, FirstPart); Py_DECREF(FirstPart); while (AtOp(P, ".")) { NextTok(P); Token *PartTok = ExpectName(P, NULL); if (PartTok == NULL) { Py_DECREF(Parts); Py_DECREF(Names); return NULL; } EndTok = PartTok; PyObject *Part = PyUnicode_FromStringAndSize(PartTok->Start, PartTok->End - PartTok->Start); if (Part == NULL) { Py_DECREF(Parts); Py_DECREF(Names); return NULL; } PyList_Append(Parts, Part); Py_DECREF(Part); } PyObject *Sep = PyUnicode_FromString("."); PyObject *Full = PyUnicode_Join(Sep, Parts); Py_DECREF(Sep); Py_DECREF(Parts); if (Full == NULL) { Py_DECREF(Names); return NULL; } PyObject *Asname = NULL; if (AtName(P, "as")) { NextTok(P); Token *AsTok = ExpectName(P, NULL); if (AsTok == NULL) { Py_DECREF(Full); Py_DECREF(Names); return NULL; } EndTok = AsTok; Asname = PyUnicode_FromStringAndSize(AsTok->Start, AsTok->End - AsTok->Start); if (Asname == NULL) { Py_DECREF(Full); Py_DECREF(Names); return NULL; } } PyObject *Argv[2] = { Full, Asname ? Asname : Py_None }; PyObject *Alias = NewNode(P, "alias", Argv, 2); Py_DECREF(Full); Py_XDECREF(Asname); if (Alias == NULL) { Py_DECREF(Names); return NULL; } /* alias 需与 vast 一致携带位置属性(编译器符号注册按节点位置关联) */ FixLoc(P, Alias, NameTok); PyList_Append(Names, Alias); Py_DECREF(Alias); if (AtOp(P, ",")) { NextTok(P); continue; } break; } PyObject *Argv[1] = { Names }; PyObject *Node = NewNode(P, "Import", Argv, 1); Py_DECREF(Names); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* from [.]*module import ... */ static PyObject *ParseImportFrom(Parser *P) { Token *Start = NextTok(P); /* 'from' */ int Level = 0; while (AtOp(P, ".")) { NextTok(P); Level++; } PyObject *Module = NULL; if (!AtName(P, "import")) { Token *NameTok = ExpectName(P, NULL); if (NameTok == NULL) { return NULL; } PyObject *Parts = PyList_New(0); if (Parts == NULL) { return NULL; } PyObject *FirstPart = PyUnicode_FromStringAndSize(NameTok->Start, NameTok->End - NameTok->Start); if (FirstPart == NULL) { Py_DECREF(Parts); return NULL; } PyList_Append(Parts, FirstPart); Py_DECREF(FirstPart); while (AtOp(P, ".")) { NextTok(P); Token *PartTok = ExpectName(P, NULL); if (PartTok == NULL) { Py_DECREF(Parts); return NULL; } PyObject *Part = PyUnicode_FromStringAndSize(PartTok->Start, PartTok->End - PartTok->Start); if (Part == NULL) { Py_DECREF(Parts); return NULL; } PyList_Append(Parts, Part); Py_DECREF(Part); } PyObject *Sep = PyUnicode_FromString("."); Module = PyUnicode_Join(Sep, Parts); Py_DECREF(Sep); Py_DECREF(Parts); if (Module == NULL) { return NULL; } } if (!ExpectName(P, "import")) { Py_XDECREF(Module); return NULL; } PyObject *Names = NewList(); if (Names == NULL) { Py_XDECREF(Module); return NULL; } if (AtOp(P, "(")) { NextTok(P); SkipNL(P); if (!AtOp(P, ")")) { for (;;) { PyObject *Alias = ParseImportAlias(P); if (Alias == NULL) { Py_DECREF(Names); Py_XDECREF(Module); return NULL; } PyList_Append(Names, Alias); Py_DECREF(Alias); SkipNL(P); if (AtOp(P, ",")) { NextTok(P); SkipNL(P); if (AtOp(P, ")")) { break; } continue; } break; } } if (!ExpectOp(P, ")")) { Py_DECREF(Names); Py_XDECREF(Module); return NULL; } } else { if (AtOp(P, "*")) { Token *StarTok = NextTok(P); PyObject *Argv[2] = { PyUnicode_FromString("*"), Py_None }; if (Argv[0] == NULL) { Py_DECREF(Names); Py_XDECREF(Module); return NULL; } PyObject *Alias = NewNode(P, "alias", Argv, 2); Py_DECREF(Argv[0]); if (Alias == NULL) { Py_DECREF(Names); Py_XDECREF(Module); return NULL; } FixLoc(P, Alias, StarTok); PyList_Append(Names, Alias); Py_DECREF(Alias); } else { for (;;) { PyObject *Alias = ParseImportAlias(P); if (Alias == NULL) { Py_DECREF(Names); Py_XDECREF(Module); return NULL; } PyList_Append(Names, Alias); Py_DECREF(Alias); if (AtOp(P, ",")) { NextTok(P); continue; } break; } } } PyObject *LevelObj = PyLong_FromLong(Level); PyObject *Argv[3] = { Module ? Module : Py_None, Names, LevelObj }; PyObject *Node = NewNode(P, "ImportFrom", Argv, 3); Py_DECREF(LevelObj); Py_XDECREF(Module); Py_DECREF(Names); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 单个 import 别名:name [as alias] */ static PyObject *ParseImportAlias(Parser *P) { Token *NameTok = ExpectName(P, NULL); if (NameTok == NULL) { return NULL; } PyObject *Asname = NULL; if (AtName(P, "as")) { NextTok(P); Token *AsTok = ExpectName(P, NULL); if (AsTok == NULL) { return NULL; } Asname = PyUnicode_FromStringAndSize(AsTok->Start, AsTok->End - AsTok->Start); if (Asname == NULL) { return NULL; } } PyObject *Name = PyUnicode_FromStringAndSize(NameTok->Start, NameTok->End - NameTok->Start); if (Name == NULL) { Py_XDECREF(Asname); return NULL; } PyObject *Argv[2] = { Name, Asname ? Asname : Py_None }; PyObject *Alias = NewNode(P, "alias", Argv, 2); Py_DECREF(Name); Py_XDECREF(Asname); if (Alias != NULL) { FixLoc(P, Alias, NameTok); } return Alias; } /* global / nonlocal */ static PyObject *ParseGlobal(Parser *P, const char *NodeName) { Token *Start = NextTok(P); PyObject *Names = NewList(); if (Names == NULL) { return NULL; } for (;;) { Token *N = ExpectName(P, NULL); if (N == NULL) { Py_DECREF(Names); return NULL; } PyObject *Name = PyUnicode_FromStringAndSize(N->Start, N->End - N->Start); if (Name == NULL) { Py_DECREF(Names); return NULL; } PyList_Append(Names, Name); Py_DECREF(Name); if (AtOp(P, ",")) { NextTok(P); continue; } break; } PyObject *Argv[1] = { Names }; PyObject *Node = NewNode(P, NodeName, Argv, 1); Py_DECREF(Names); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* del target, ... */ static PyObject *ParseDelete(Parser *P) { Token *Start = NextTok(P); /* 'del' */ PyObject *Targets = NewList(); if (Targets == NULL) { return NULL; } for (;;) { PyObject *Expr = ParseExpr(P); if (Expr == NULL) { Py_DECREF(Targets); return NULL; } SetDelContext(P, Expr); PyList_Append(Targets, Expr); Py_DECREF(Expr); if (AtOp(P, ",")) { NextTok(P); continue; } break; } PyObject *Argv[1] = { Targets }; PyObject *Node = NewNode(P, "Delete", Argv, 1); Py_DECREF(Targets); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* assert test [, msg] */ static PyObject *ParseAssert(Parser *P) { Token *Start = NextTok(P); /* 'assert' */ PyObject *Test = ParseExpr(P); if (Test == NULL) { return NULL; } PyObject *Msg = NULL; if (AtOp(P, ",")) { NextTok(P); Msg = ParseExpr(P); if (Msg == NULL) { Py_DECREF(Test); return NULL; } } PyObject *Argv[2] = { Test, Msg ? Msg : Py_None }; PyObject *Node = NewNode(P, "Assert", Argv, 2); Py_DECREF(Test); Py_XDECREF(Msg); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 装饰器 + def/class */ static PyObject *ParseDecorated(Parser *P) { PyObject *DecoratorList = NewList(); if (DecoratorList == NULL) { return NULL; } while (AtOp(P, "@")) { Token *DecoStart = NextTok(P); PyObject *Deco = ParseExpr(P); if (Deco == NULL) { Py_DECREF(DecoratorList); return NULL; } FixLocEnd(P, Deco, DecoStart, NULL); PyList_Append(DecoratorList, Deco); Py_DECREF(Deco); if (!ExpectNEWLINE(P)) { Py_DECREF(DecoratorList); return NULL; } SkipNEWLINE(P); } Token *T = PeekTok(P, 0); /* extern / export 必须走 ParseExternDef(与 Python _ParseDecorated 的 * _ParseExternDef/_ParseExportDef 分派一致)。此前误走 ParseFunctionDef: * 它无条件把当前 token 当 `def` 吃掉、再 ExpectName 拿到 `def`, * 于是 `@deco` + `export def f(...)` 在 `(` 处报 expected operator NAME('f')。 */ if (T->Kind == TK_NAME && TokIsName(T, "extern")) { return ParseExternDef(P, 0, DecoratorList); } if (T->Kind == TK_NAME && TokIsName(T, "export")) { return ParseExternDef(P, 1, DecoratorList); } if (T->Kind == TK_NAME && TokIsName(T, "define")) { return ParseFunctionDef(P, 0, DecoratorList); } if (T->Kind == TK_NAME && TokIsName(T, "def")) { return ParseFunctionDef(P, 0, DecoratorList); } if (T->Kind == TK_NAME && TokIsName(T, "async") && PeekTok(P, 1)->Kind == TK_NAME && TokIsName(PeekTok(P, 1), "def")) { return ParseFunctionDef(P, 1, DecoratorList); } if (T->Kind == TK_NAME && TokIsName(T, "class")) { return ParseClassDef(P, DecoratorList); } if (T->Kind == TK_NAME && TokIsName(T, "struct") && PeekTok(P, 1)->Kind == TK_NAME) { return ParseStructDef(P, DecoratorList); } if (T->Kind == TK_NAME && (TokIsName(T, "virtual") || TokIsName(T, "novirtual"))) { return ParseVirtualModified(P, DecoratorList); } SyntaxErrorAt(P, T, "decorator must be followed by def/class"); Py_DECREF(DecoratorList); return NULL; } /* virtual / novirtual 修饰符(对齐 vast Parser._ParseVirtualModified): * 语句起始的 `virtual`/`novirtual` 后随 class/def(def 别名 fn/fun/func/function 同样接受) * 时,合成装饰器 t.CVTable / t.NoVTable 追加到既有装饰器之后,再交由 * ParseClassDef / ParseFunctionDef 解析。非法形态(后随非 class/def;virtual def * 不在类体内)一律报错,绝不静默丢弃修饰符。 */ static PyObject *ParseVirtualModified(Parser *P, PyObject *Decorators) { Token *Mod = PeekTok(P, 0); Token *Nxt = PeekTok(P, 1); const char *Marker = TokIsName(Mod, "virtual") ? "CVTable" : "NoVTable"; int IsClass = 0; int IsDef = 0; if (Nxt->Kind == TK_NAME) { if (TokIsName(Nxt, "class")) { IsClass = 1; } else if (TokIsName(Nxt, "def") || TokIsName(Nxt, "fn") || TokIsName(Nxt, "fun") || TokIsName(Nxt, "func") || TokIsName(Nxt, "function")) { IsDef = 1; } } if (Nxt->Kind == TK_NAME && TokIsName(Nxt, "struct")) { /* struct 是纯数据类型:禁止 virtual / novirtual 修饰(用户 2026-10-01 定)。 * struct 解析期已合成 @t.NoVTable,无需也无法再显式声明虚/非虚。 */ SyntaxErrorAt(P, Mod, "virtual/novirtual is not allowed on struct " "(struct is data-only, use class for vtable)"); return NULL; } if (!IsClass && !IsDef) { SyntaxErrorAt(P, Mod, "virtual/novirtual must precede class/def"); return NULL; } if (IsDef && !P->InClassBody) { SyntaxErrorAt(P, Mod, "virtual def must appear inside a class body"); return NULL; } NextTok(P); /* 消费修饰符 */ PyObject *Deco = MakeTAttrNode(P, Marker); if (Deco == NULL) { return NULL; } FixLoc(P, Deco, Mod); PyObject *DecoList = NewList(); if (DecoList == NULL) { Py_DECREF(Deco); return NULL; } if (Decorators != NULL) { Py_ssize_t N = PyList_GET_SIZE(Decorators); for (Py_ssize_t I = 0; I < N; I++) { PyList_Append(DecoList, PyList_GET_ITEM(Decorators, I)); } } PyList_Append(DecoList, Deco); Py_DECREF(Deco); PyObject *Node = IsClass ? ParseClassDef(P, DecoList) : ParseFunctionDef(P, 0, DecoList); Py_DECREF(DecoList); return Node; } /* def / fn / fun / func / function(含 async def) */ static PyObject *ParseFunctionDef(Parser *P, int IsAsync, PyObject *Decorators) { Token *Start = NextTok(P); if (Start->Kind == TK_NAME && TokIsName(Start, "async")) { Start = NextTok(P); /* def */ } /* define 宏函数关键字(语法与 def 一致,产出 FunctionDef.Define=True) */ int IsDefine = (Start->Kind == TK_NAME && TokIsName(Start, "define")); Token *NameTok = ExpectName(P, NULL); if (NameTok == NULL) { return NULL; } PyObject *TypeParams = NewList(); if (TypeParams == NULL) { return NULL; } if (AtOp(P, "[")) { Py_DECREF(TypeParams); TypeParams = ParseTypeParams(P); if (TypeParams == NULL) { return NULL; } } PyObject *Args = ParseArguments(P, 0, 0); if (Args == NULL) { Py_DECREF(TypeParams); return NULL; } PyObject *Returns = NULL; if (AtOp(P, "->")) { NextTok(P); Returns = ParseTypeAnnotation(P); if (Returns == NULL) { Py_DECREF(Args); Py_DECREF(TypeParams); return NULL; } } if (!ExpectOp(P, ":")) { Py_DECREF(Args); Py_XDECREF(Returns); Py_DECREF(TypeParams); return NULL; } PyObject *Body = ParseSuite(P); if (Body == NULL) { Py_DECREF(Args); Py_XDECREF(Returns); Py_DECREF(TypeParams); return NULL; } PyObject *Name = PyUnicode_FromStringAndSize(NameTok->Start, NameTok->End - NameTok->Start); if (Name == NULL) { Py_DECREF(Args); Py_XDECREF(Returns); Py_DECREF(TypeParams); Py_DECREF(Body); return NULL; } PyObject *Argv[7]; Argv[0] = Name; Argv[1] = Args; Argv[2] = Body; Argv[3] = Decorators ? Decorators : NewList(); Argv[4] = Returns ? Returns : Py_None; Argv[5] = Py_None; /* type_comment */ Argv[6] = TypeParams; if (Argv[3] == NULL) { Py_DECREF(Name); Py_DECREF(Args); Py_DECREF(Body); Py_XDECREF(Returns); Py_DECREF(TypeParams); return NULL; } PyObject *Node = NewNode(P, IsAsync ? "AsyncFunctionDef" : "FunctionDef", Argv, 7); Py_DECREF(Name); Py_DECREF(Args); Py_DECREF(Body); if (Argv[3] != Decorators) { Py_DECREF(Argv[3]); } if (Node != NULL && IsDefine) { /* 标记 define 宏函数(Unparser 据此还原语法);返回注解保持原样 */ PyObject_SetAttrString(Node, "Define", Py_True); } Py_XDECREF(Returns); Py_DECREF(TypeParams); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 构造内建 attr 注解节点:Name(AttrName, Load) */ static PyObject *MakeTAttrNode(Parser *P, const char *AttrName) { PyObject *Load = MakeCtx(P, "Load"); PyObject *AttrStr = AttrName ? PyUnicode_FromString(AttrName) : NULL; if (Load == NULL || AttrStr == NULL) { Py_XDECREF(Load); Py_XDECREF(AttrStr); return NULL; } PyObject *ArgvN[2] = { AttrStr, Load }; PyObject *Node = NewNode(P, "Name", ArgvN, 2); Py_DECREF(AttrStr); Py_DECREF(Load); return Node; } /* extern/export 函数声明(FFI/裸名导出,对齐 vast Parser._ParseExternDef/_ParseExportDef)。 * 允许语法(4 种,配不配 def 都一样,无 `:` 时 body 为空): * extern [def] A(x: int) -> int [': pass'] * 产出标准 FunctionDef:返回注解保持原样,设 Extern=True / Export=True 供 Unparser 还原。 */ static PyObject *ParseExternDef(Parser *P, int IsExport, PyObject *Decorators) { Token *Start = NextTok(P); /* 'extern' / 'export' */ if (AtName(P, "def")) { NextTok(P); } Token *NameTok = ExpectName(P, NULL); if (NameTok == NULL) { return NULL; } PyObject *TypeParams = NewList(); if (TypeParams == NULL) { return NULL; } if (AtOp(P, "[")) { Py_DECREF(TypeParams); TypeParams = ParseTypeParams(P); if (TypeParams == NULL) { return NULL; } } PyObject *Args = ParseArguments(P, 0, 0); if (Args == NULL) { Py_DECREF(TypeParams); return NULL; } PyObject *Returns = NULL; if (AtOp(P, "->")) { NextTok(P); Returns = ParseTypeAnnotation(P); if (Returns == NULL) { Py_DECREF(Args); Py_DECREF(TypeParams); return NULL; } } PyObject *Body = NewList(); if (Body == NULL) { Py_DECREF(Args); Py_XDECREF(Returns); Py_DECREF(TypeParams); return NULL; } if (AtOp(P, ":")) { NextTok(P); Py_DECREF(Body); Body = ParseSuite(P); if (Body == NULL) { Py_DECREF(Args); Py_XDECREF(Returns); Py_DECREF(TypeParams); return NULL; } } PyObject *Name = PyUnicode_FromStringAndSize(NameTok->Start, NameTok->End - NameTok->Start); if (Name == NULL) { Py_DECREF(Args); Py_XDECREF(Returns); Py_DECREF(TypeParams); Py_DECREF(Body); return NULL; } PyObject *Argv[7]; Argv[0] = Name; Argv[1] = Args; Argv[2] = Body; Argv[3] = Decorators ? Decorators : NewList(); Argv[4] = Returns ? Returns : Py_None; Argv[5] = Py_None; /* type_comment */ Argv[6] = TypeParams; if (Argv[3] == NULL) { Py_DECREF(Name); Py_DECREF(Args); Py_DECREF(Body); Py_XDECREF(Returns); Py_DECREF(TypeParams); return NULL; } PyObject *Node = NewNode(P, "FunctionDef", Argv, 7); Py_DECREF(Name); Py_DECREF(Args); Py_DECREF(Body); if (Argv[3] != Decorators) { Py_DECREF(Argv[3]); } Py_DECREF(TypeParams); if (Node == NULL) { Py_XDECREF(Returns); return NULL; } /* 标记 extern/export(Unparser 据此还原语法);返回注解保持原样 */ PyObject_SetAttrString(Node, IsExport ? "Export" : "Extern", Py_True); Py_XDECREF(Returns); FixLoc(P, Node, Start); return Node; } /* PEP 695 类型参数:[T, *Ts, **P, U: Bound] */ static PyObject *ParseTypeParams(Parser *P) { if (!ExpectOp(P, "[")) { return NULL; } SkipNL(P); PyObject *Params = NewList(); if (Params == NULL) { return NULL; } if (!AtOp(P, "]")) { for (;;) { SkipNL(P); int Star = 0; if (AtOp(P, "*")) { NextTok(P); Star = 1; } else if (AtOp(P, "**")) { NextTok(P); Star = 2; } Token *NameTok = ExpectName(P, NULL); if (NameTok == NULL) { Py_DECREF(Params); return NULL; } PyObject *Bound = NULL; if (Star == 0 && AtOp(P, ":")) { NextTok(P); Bound = ParseExpr(P); if (Bound == NULL) { Py_DECREF(Params); return NULL; } } PyObject *Name = PyUnicode_FromStringAndSize(NameTok->Start, NameTok->End - NameTok->Start); if (Name == NULL) { Py_XDECREF(Bound); Py_DECREF(Params); return NULL; } PyObject *Node = NULL; if (Star == 1) { PyObject *Argv[1] = { Name }; Node = NewNode(P, "TypeVarTuple", Argv, 1); } else if (Star == 2) { PyObject *Argv[1] = { Name }; Node = NewNode(P, "ParamSpec", Argv, 1); } else { PyObject *Argv[2] = { Name, Bound ? Bound : Py_None }; Node = NewNode(P, "TypeVar", Argv, 2); } Py_DECREF(Name); Py_XDECREF(Bound); if (Node == NULL) { Py_DECREF(Params); return NULL; } FixLoc(P, Node, NameTok); PyList_Append(Params, Node); Py_DECREF(Node); SkipNL(P); if (AtOp(P, ",")) { NextTok(P); continue; } break; } } if (!ExpectOp(P, "]")) { Py_DECREF(Params); return NULL; } return Params; } /* class 定义 */ static PyObject *ParseClassDef(Parser *P, PyObject *Decorators) { Token *Start = NextTok(P); /* class */ Token *NameTok = ExpectName(P, NULL); if (NameTok == NULL) { return NULL; } PyObject *TypeParams = NewList(); if (TypeParams == NULL) { return NULL; } if (AtOp(P, "[")) { Py_DECREF(TypeParams); TypeParams = ParseTypeParams(P); if (TypeParams == NULL) { return NULL; } } PyObject *Bases = NewList(); PyObject *Keywords = NewList(); if (Bases == NULL || Keywords == NULL) { Py_XDECREF(Bases); Py_XDECREF(Keywords); Py_DECREF(TypeParams); return NULL; } if (AtOp(P, "(")) { NextTok(P); SkipNL(P); if (!AtOp(P, ")")) { for (;;) { SkipNL(P); if (AtOp(P, "**")) { NextTok(P); PyObject *Value = ParseExpr(P); if (Value == NULL) { Py_DECREF(Bases); Py_DECREF(Keywords); Py_DECREF(TypeParams); return NULL; } PyObject *Kw = MakeKeyword(P, NULL, Value, PrevTok(P)); Py_DECREF(Value); if (Kw == NULL) { Py_DECREF(Bases); Py_DECREF(Keywords); Py_DECREF(TypeParams); return NULL; } PyList_Append(Keywords, Kw); Py_DECREF(Kw); } else { Token *A0 = PeekTok(P, 0); Token *A1 = PeekTok(P, 1); if (A0->Kind == TK_NAME && A1->Kind == TK_OP && TokIsOp(A1, "=")) { Token *ArgTok = NextTok(P); NextTok(P); /* '=' */ PyObject *Value = ParseExpr(P); if (Value == NULL) { Py_DECREF(Bases); Py_DECREF(Keywords); Py_DECREF(TypeParams); return NULL; } PyObject *Arg = PyUnicode_FromStringAndSize(ArgTok->Start, ArgTok->End - ArgTok->Start); PyObject *Kw = MakeKeyword(P, Arg, Value, ArgTok); Py_XDECREF(Arg); Py_DECREF(Value); if (Kw == NULL) { Py_DECREF(Bases); Py_DECREF(Keywords); Py_DECREF(TypeParams); return NULL; } PyList_Append(Keywords, Kw); Py_DECREF(Kw); } else { PyObject *Base = ParseExpr(P); if (Base == NULL) { Py_DECREF(Bases); Py_DECREF(Keywords); Py_DECREF(TypeParams); return NULL; } PyList_Append(Bases, Base); Py_DECREF(Base); } } SkipNL(P); if (AtOp(P, ",")) { NextTok(P); SkipNL(P); if (AtOp(P, ")")) { break; } continue; } break; } } if (!ExpectOp(P, ")")) { Py_DECREF(Bases); Py_DECREF(Keywords); Py_DECREF(TypeParams); return NULL; } } if (!ExpectOp(P, ":")) { Py_DECREF(Bases); Py_DECREF(Keywords); Py_DECREF(TypeParams); return NULL; } PyObject *Body = ParseSuiteOwned(P, 1); if (Body == NULL) { Py_DECREF(Bases); Py_DECREF(Keywords); Py_DECREF(TypeParams); return NULL; } PyObject *Name = PyUnicode_FromStringAndSize(NameTok->Start, NameTok->End - NameTok->Start); if (Name == NULL) { Py_DECREF(Bases); Py_DECREF(Keywords); Py_DECREF(TypeParams); Py_DECREF(Body); return NULL; } PyObject *Argv[6]; Argv[0] = Name; Argv[1] = Bases; Argv[2] = Keywords; Argv[3] = Body; Argv[4] = Decorators ? Decorators : NewList(); Argv[5] = TypeParams; if (Argv[4] == NULL) { Py_DECREF(Name); Py_DECREF(Bases); Py_DECREF(Keywords); Py_DECREF(Body); Py_DECREF(TypeParams); return NULL; } PyObject *Node = NewNode(P, "ClassDef", Argv, 6); Py_DECREF(Name); Py_DECREF(Bases); Py_DECREF(Keywords); Py_DECREF(Body); if (Argv[4] != Decorators) { Py_DECREF(Argv[4]); } Py_DECREF(TypeParams); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* struct 纯数据类型定义(对齐 vast Parser._ParseStructDef): * `struct X:` / `struct X(Base):` ≡ `@t.NoVTable class X(t.CStruct):`。 * 复用 ParseClassDef 的完整解析路径(类型参数/基类/关键字实参/类体套件)—— * ParseClassDef 的首个 NextTok 消费的正是 `struct` 关键字本身,故此处不预消费。 * 解析前后各补:合成 @t.NoVTable 装饰器(类级强制无虚表)、追加 t.CStruct * 标记基类(数据类语义,_MARKER_BASES 认它)、校验类体内没有 def。 */ static PyObject *ParseStructDef(Parser *P, PyObject *Decorators) { Token *Start = PeekTok(P, 0); /* struct */ PyObject *Deco = MakeTAttrNode(P, "NoVTable"); if (Deco == NULL) { return NULL; } FixLoc(P, Deco, Start); PyObject *DecoList = NewList(); if (DecoList == NULL) { Py_DECREF(Deco); return NULL; } if (Decorators != NULL) { Py_ssize_t N = PyList_GET_SIZE(Decorators); for (Py_ssize_t I = 0; I < N; I++) { PyList_Append(DecoList, PyList_GET_ITEM(Decorators, I)); } } PyList_Append(DecoList, Deco); Py_DECREF(Deco); PyObject *Node = ParseClassDef(P, DecoList); Py_DECREF(DecoList); if (Node == NULL) { return NULL; } /* 数据类标记基类:追加在用户基类之后(真实父类解析顺序不变) */ PyObject *Bases = PyObject_GetAttrString(Node, "bases"); if (Bases == NULL) { PyErr_Clear(); } else { PyObject *MarkerBase = MakeTAttrNode(P, "CStruct"); if (MarkerBase == NULL) { Py_DECREF(Bases); Py_DECREF(Node); return NULL; } FixLoc(P, MarkerBase, Start); PyList_Append(Bases, MarkerBase); Py_DECREF(MarkerBase); Py_DECREF(Bases); } /* struct 禁止 def:检查类体直接子节点(嵌套 struct 由其自身解析自检) */ PyObject *Body = PyObject_GetAttrString(Node, "body"); if (Body == NULL) { PyErr_Clear(); return Node; } Py_ssize_t BN = PyList_GET_SIZE(Body); for (Py_ssize_t I = 0; I < BN; I++) { PyObject *Item = PyList_GET_ITEM(Body, I); if (Item != NULL && NodeIs(Item, "FunctionDef")) { SyntaxErrorAt(P, Start, "def is not allowed inside struct " "(struct is data-only, use class for methods)"); Py_DECREF(Body); Py_DECREF(Node); return NULL; } } Py_DECREF(Body); return Node; } /* 语句块(套件) */ static PyObject *ParseSuiteImpl(Parser *P) { if (PeekTok(P, 0)->Kind == TK_NEWLINE) { NextTok(P); while (PeekTok(P, 0)->Kind == TK_NL) { NextTok(P); } if (PeekTok(P, 0)->Kind == TK_INDENT) { NextTok(P); PyObject *Body = NewList(); if (Body == NULL) { return NULL; } SkipNEWLINE(P); while (PeekTok(P, 0)->Kind != TK_DEDENT && PeekTok(P, 0)->Kind != TK_ENDMARKER) { PyObject *Stmt = ParseStatement(P); if (Stmt == NULL) { Py_DECREF(Body); return NULL; } PyList_Append(Body, Stmt); Py_DECREF(Stmt); while (AtOp(P, ";")) { NextTok(P); if (PeekTok(P, 0)->Kind == TK_NEWLINE) { break; } PyObject *Extra = ParseStatement(P); if (Extra == NULL) { Py_DECREF(Body); return NULL; } PyList_Append(Body, Extra); Py_DECREF(Extra); } SkipNEWLINE(P); } Token *T = NextTok(P); if (T->Kind != TK_DEDENT) { SyntaxErrorAt(P, T, "expected DEDENT"); Py_DECREF(Body); return NULL; } return Body; } /* 空套件(宽松) */ return NewList(); } /* 单行套件 */ PyObject *Body = NewList(); if (Body == NULL) { return NULL; } PyObject *Stmt = ParseStatement(P); if (Stmt == NULL) { Py_DECREF(Body); return NULL; } PyList_Append(Body, Stmt); Py_DECREF(Stmt); while (AtOp(P, ";")) { NextTok(P); if (PeekTok(P, 0)->Kind == TK_NEWLINE) { break; } PyObject *Extra = ParseStatement(P); if (Extra == NULL) { Py_DECREF(Body); return NULL; } PyList_Append(Body, Extra); Py_DECREF(Extra); } if (!ExpectNEWLINE(P)) { Py_DECREF(Body); return NULL; } /* 吞掉单行套件后的空行/注释行 NL:与纯 Python _ParseSuite 的单行分支一致, * 使外层语句的 end_lineno 落在最后一个被吞掉的 NL 上(而非本行 NEWLINE)。 */ SkipNL(P); return Body; } /* 套件入口:OwnerIsClass 表示该套件的直接拥有者是否 ClassDef(供 virtual def 判据)。 */ static PyObject *ParseSuiteOwned(Parser *P, int OwnerIsClass) { int Prev = P->InClassBody; P->InClassBody = OwnerIsClass; PyObject *Body = ParseSuiteImpl(P); P->InClassBody = Prev; return Body; } static PyObject *ParseSuite(Parser *P) { return ParseSuiteOwned(P, 0); } /* if / elif / else */ static PyObject *ParseIf(Parser *P) { Token *Start = NextTok(P); /* if */ PyObject *Test = ParseExpr(P); if (Test == NULL) { return NULL; } if (!ExpectOp(P, ":")) { Py_DECREF(Test); return NULL; } PyObject *Body = ParseSuite(P); if (Body == NULL) { Py_DECREF(Test); return NULL; } PyObject *Orelse = NewList(); if (Orelse == NULL) { Py_DECREF(Test); Py_DECREF(Body); return NULL; } if (AtName(P, "elif")) { PyObject *Nested = ParseIf(P); if (Nested == NULL) { Py_DECREF(Test); Py_DECREF(Body); Py_DECREF(Orelse); return NULL; } PyList_Append(Orelse, Nested); Py_DECREF(Nested); } else if (AtName(P, "else")) { NextTok(P); if (!ExpectOp(P, ":")) { Py_DECREF(Test); Py_DECREF(Body); Py_DECREF(Orelse); return NULL; } PyObject *ElseBody = ParseSuite(P); if (ElseBody == NULL) { Py_DECREF(Test); Py_DECREF(Body); Py_DECREF(Orelse); return NULL; } Py_DECREF(Orelse); Orelse = ElseBody; } PyObject *Argv[3] = { Test, Body, Orelse }; PyObject *Node = NewNode(P, "If", Argv, 3); Py_DECREF(Test); Py_DECREF(Body); Py_DECREF(Orelse); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* ===================== cif / celif / celse 编译期条件编译 ===================== * 软关键字:语句起始 NAME('cif') 后非赋值/注解形态 ⇒ cif 语句。 * 解析期 desugar 为既有「If + c.@CIf 标记调用」形状(与纯 Python / Viper 侧一致): * cif E: → If(test=c.@CIf(E), body, orelse) * celif E: → 同链下一个 If(test=c.@CIf(E), ...)(挂在上一支 orelse) * celse: → 普通 orelse * 标记 c.@CIf / c.@CIfdef 由本解析器合成(属性名前导 '@' 词法器不可产出), * 用户写 c.CIf 在表达式处 FailFast。 */ /* cif 语句起始判定:第二 token 为 '=' ':' 或增强赋值 ⇒ 非 cif 语句(cif = 5)。 */ static int IsCIfStatementStart(Parser *P) { Token *N = PeekTok(P, 1); if (N->Kind != TK_OP) { return 1; } static const char *Ops[] = { "=", ":", "+=", "-=", "*=", "/=", "//=", "%=", "**=", "<<=", ">>=", "&=", "|=", "^=", "@=", NULL }; for (int I = 0; Ops[I] != NULL; I++) { if (TokIsOp(N, Ops[I])) { return 0; } } return 1; } /* 构造内部标记调用 `(Expr)`。 */ static PyObject *MakeCifMarkerCall(Parser *P, const char *AttrName, PyObject *Expr, Token *Start) { PyObject *Load = MakeCtx(P, "Load"); PyObject *AttrStr = Load ? PyUnicode_FromString(AttrName) : NULL; if (Load == NULL || AttrStr == NULL) { Py_XDECREF(Load); Py_XDECREF(AttrStr); return NULL; } PyObject *NameArgv[2] = { AttrStr, Load }; PyObject *FnNode = NewNode(P, "Name", NameArgv, 2); Py_DECREF(AttrStr); Py_DECREF(Load); if (FnNode == NULL) { return NULL; } FixLoc(P, FnNode, Start); PyObject *Args = NewList(); PyObject *Kw = NewList(); if (Args == NULL || Kw == NULL) { Py_XDECREF(Args); Py_XDECREF(Kw); Py_DECREF(FnNode); return NULL; } PyList_Append(Args, Expr); PyObject *CallArgv[3] = { FnNode, Args, Kw }; PyObject *CallNode = NewNode(P, "Call", CallArgv, 3); Py_DECREF(Args); Py_DECREF(Kw); Py_DECREF(FnNode); if (CallNode == NULL) { return NULL; } FixLoc(P, CallNode, Start); return CallNode; } /* 解析 cif/celif 条件表达式:期间允许 defined(NAME) 谓词。 */ static PyObject *ParseCIfCondition(Parser *P) { int Prev = P->InCIfCond; P->InCIfCond = 1; PyObject *E = ParseExpr(P); P->InCIfCond = Prev; return E; } /* `cif :` + 可选 celif/celse 链 */ static PyObject *ParseCIf(Parser *P) { Token *Start = NextTok(P); /* cif */ PyObject *Test = ParseCIfCondition(P); if (Test == NULL) { return NULL; } if (!ExpectOp(P, ":")) { Py_DECREF(Test); return NULL; } PyObject *Body = ParseSuite(P); if (Body == NULL) { Py_DECREF(Test); return NULL; } PyObject *Marker = MakeCifMarkerCall(P, "@CIf", Test, Start); Py_DECREF(Test); if (Marker == NULL) { Py_DECREF(Body); return NULL; } PyObject *Orelse = ParseCIfChainTail(P); if (Orelse == NULL) { Py_DECREF(Marker); Py_DECREF(Body); return NULL; } PyObject *Argv[3] = { Marker, Body, Orelse }; PyObject *Node = NewNode(P, "If", Argv, 3); Py_DECREF(Marker); Py_DECREF(Body); Py_DECREF(Orelse); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* `celif :`(cif 链的后续分支) */ static PyObject *ParseCelif(Parser *P) { Token *Start = NextTok(P); /* celif */ PyObject *Test = ParseCIfCondition(P); if (Test == NULL) { return NULL; } if (!ExpectOp(P, ":")) { Py_DECREF(Test); return NULL; } PyObject *Body = ParseSuite(P); if (Body == NULL) { Py_DECREF(Test); return NULL; } PyObject *Marker = MakeCifMarkerCall(P, "@CIf", Test, Start); Py_DECREF(Test); if (Marker == NULL) { Py_DECREF(Body); return NULL; } PyObject *Orelse = ParseCIfChainTail(P); if (Orelse == NULL) { Py_DECREF(Marker); Py_DECREF(Body); return NULL; } PyObject *Argv[3] = { Marker, Body, Orelse }; PyObject *Node = NewNode(P, "If", Argv, 3); Py_DECREF(Marker); Py_DECREF(Body); Py_DECREF(Orelse); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* cif 链尾部(celif/celse)→ orelse 列表;错配 ⇒ FailFast(静态报文)。 */ static PyObject *ParseCIfChainTail(Parser *P) { if (AtName(P, "celif")) { PyObject *Nested = ParseCelif(P); if (Nested == NULL) { return NULL; } PyObject *L = NewList(); if (L == NULL) { Py_DECREF(Nested); return NULL; } PyList_Append(L, Nested); Py_DECREF(Nested); return L; } if (AtName(P, "celse")) { NextTok(P); if (!ExpectOp(P, ":")) { return NULL; } PyObject *Body = ParseSuite(P); if (Body == NULL) { return NULL; } if (AtName(P, "celif")) { SyntaxErrorAt(P, PeekTok(P, 0), "'celif' cannot follow 'celse' (the 'celse' branch must be the last of the 'cif' chain)"); Py_DECREF(Body); return NULL; } if (AtName(P, "celse")) { SyntaxErrorAt(P, PeekTok(P, 0), "'celse' cannot follow 'celse' (the 'celse' branch must be the last of the 'cif' chain)"); Py_DECREF(Body); return NULL; } return Body; } if (AtName(P, "elif")) { SyntaxErrorAt(P, PeekTok(P, 0), "a 'cif' chain must be closed with 'celse', not 'elif'"); return NULL; } if (AtName(P, "else")) { SyntaxErrorAt(P, PeekTok(P, 0), "a 'cif' chain must be closed with 'celse', not 'else'"); return NULL; } return NewList(); } /* while / else */ static PyObject *ParseWhile(Parser *P) { Token *Start = NextTok(P); /* while */ PyObject *Test = ParseExpr(P); if (Test == NULL) { return NULL; } if (!ExpectOp(P, ":")) { Py_DECREF(Test); return NULL; } PyObject *Body = ParseSuite(P); if (Body == NULL) { Py_DECREF(Test); return NULL; } PyObject *Orelse = NewList(); if (Orelse == NULL) { Py_DECREF(Test); Py_DECREF(Body); return NULL; } if (AtName(P, "else")) { NextTok(P); if (!ExpectOp(P, ":")) { Py_DECREF(Test); Py_DECREF(Body); Py_DECREF(Orelse); return NULL; } PyObject *ElseBody = ParseSuite(P); if (ElseBody == NULL) { Py_DECREF(Test); Py_DECREF(Body); Py_DECREF(Orelse); return NULL; } Py_DECREF(Orelse); Orelse = ElseBody; } PyObject *Argv[3] = { Test, Body, Orelse }; PyObject *Node = NewNode(P, "While", Argv, 3); Py_DECREF(Test); Py_DECREF(Body); Py_DECREF(Orelse); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* for / async for */ static PyObject *ParseFor(Parser *P, int IsAsync) { Token *Start = NextTok(P); if (Start->Kind == TK_NAME && TokIsName(Start, "async")) { Start = NextTok(P); /* for */ } PyObject *Target = ParseTargetList(P); if (Target == NULL) { return NULL; } if (!ExpectName(P, "in")) { Py_DECREF(Target); return NULL; } PyObject *Iterable = ParseExpr(P); if (Iterable == NULL) { Py_DECREF(Target); return NULL; } if (!ExpectOp(P, ":")) { Py_DECREF(Target); Py_DECREF(Iterable); return NULL; } PyObject *Body = ParseSuite(P); if (Body == NULL) { Py_DECREF(Target); Py_DECREF(Iterable); return NULL; } PyObject *Orelse = NewList(); if (Orelse == NULL) { Py_DECREF(Target); Py_DECREF(Iterable); Py_DECREF(Body); return NULL; } if (AtName(P, "else")) { NextTok(P); if (!ExpectOp(P, ":")) { Py_DECREF(Target); Py_DECREF(Iterable); Py_DECREF(Body); Py_DECREF(Orelse); return NULL; } PyObject *ElseBody = ParseSuite(P); if (ElseBody == NULL) { Py_DECREF(Target); Py_DECREF(Iterable); Py_DECREF(Body); Py_DECREF(Orelse); return NULL; } Py_DECREF(Orelse); Orelse = ElseBody; } PyObject *Argv[5] = { Target, Iterable, Body, Orelse, Py_None }; PyObject *Node = NewNode(P, IsAsync ? "AsyncFor" : "For", Argv, 5); Py_DECREF(Target); Py_DECREF(Iterable); Py_DECREF(Body); Py_DECREF(Orelse); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* for 目标列表(支持裸元组解包) */ static PyObject *ParseTargetList(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *First = ParseTarget(P); if (First == NULL) { return NULL; } if (!AtOp(P, ",")) { return First; } PyObject *Elts = NewList(); if (Elts == NULL) { Py_DECREF(First); return NULL; } PyList_Append(Elts, First); while (AtOp(P, ",")) { NextTok(P); SkipNL(P); PyObject *E = ParseTarget(P); if (E == NULL) { Py_DECREF(Elts); Py_DECREF(First); return NULL; } PyList_Append(Elts, E); Py_DECREF(E); } Py_DECREF(First); PyObject *Store = MakeCtx(P, "Store"); if (Store == NULL) { Py_DECREF(Elts); return NULL; } PyObject *Argv[2] = { Elts, Store }; PyObject *Node = NewNode(P, "Tuple", Argv, 2); Py_DECREF(Elts); Py_DECREF(Store); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* try / except* / else / finally */ static PyObject *ParseTry(Parser *P) { Token *Start = NextTok(P); /* try */ if (!ExpectOp(P, ":")) { return NULL; } PyObject *Body = ParseSuite(P); if (Body == NULL) { return NULL; } PyObject *Handlers = NewList(); PyObject *Orelse = NewList(); PyObject *Finalbody = NewList(); if (Handlers == NULL || Orelse == NULL || Finalbody == NULL) { Py_XDECREF(Handlers); Py_XDECREF(Orelse); Py_XDECREF(Finalbody); Py_DECREF(Body); return NULL; } int IsStar = 0; while (AtName(P, "except")) { NextTok(P); if (AtOp(P, "*")) { IsStar = 1; NextTok(P); } PyObject *Handler = ParseExceptHandler(P); if (Handler == NULL) { Py_DECREF(Body); Py_DECREF(Handlers); Py_DECREF(Orelse); Py_DECREF(Finalbody); return NULL; } PyList_Append(Handlers, Handler); Py_DECREF(Handler); } if (AtName(P, "else")) { NextTok(P); if (!ExpectOp(P, ":")) { Py_DECREF(Body); Py_DECREF(Handlers); Py_DECREF(Orelse); Py_DECREF(Finalbody); return NULL; } PyObject *ElseBody = ParseSuite(P); if (ElseBody == NULL) { Py_DECREF(Body); Py_DECREF(Handlers); Py_DECREF(Orelse); Py_DECREF(Finalbody); return NULL; } Py_DECREF(Orelse); Orelse = ElseBody; } if (AtName(P, "finally")) { NextTok(P); if (!ExpectOp(P, ":")) { Py_DECREF(Body); Py_DECREF(Handlers); Py_DECREF(Orelse); Py_DECREF(Finalbody); return NULL; } PyObject *FinBody = ParseSuite(P); if (FinBody == NULL) { Py_DECREF(Body); Py_DECREF(Handlers); Py_DECREF(Orelse); Py_DECREF(Finalbody); return NULL; } Py_DECREF(Finalbody); Finalbody = FinBody; } PyObject *Argv[4] = { Body, Handlers, Orelse, Finalbody }; PyObject *Node = NewNode(P, IsStar ? "TryStar" : "Try", Argv, 4); Py_DECREF(Body); Py_DECREF(Handlers); Py_DECREF(Orelse); Py_DECREF(Finalbody); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* except [expr [as name]] ':' suite */ static PyObject *ParseExceptHandler(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *ExcType = NULL; PyObject *Name = NULL; if (!AtOp(P, ":")) { ExcType = ParseExpr(P); if (ExcType == NULL) { return NULL; } if (AtName(P, "as")) { NextTok(P); Token *NameTok = ExpectName(P, NULL); if (NameTok == NULL) { Py_DECREF(ExcType); return NULL; } Name = PyUnicode_FromStringAndSize(NameTok->Start, NameTok->End - NameTok->Start); if (Name == NULL) { Py_DECREF(ExcType); return NULL; } } } if (!ExpectOp(P, ":")) { Py_XDECREF(ExcType); Py_XDECREF(Name); return NULL; } PyObject *Body = ParseSuite(P); if (Body == NULL) { Py_XDECREF(ExcType); Py_XDECREF(Name); return NULL; } PyObject *Argv[3] = { ExcType ? ExcType : Py_None, Name ? Name : Py_None, Body }; PyObject *Node = NewNode(P, "ExceptHandler", Argv, 3); Py_XDECREF(ExcType); Py_XDECREF(Name); Py_DECREF(Body); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* with / async with */ static PyObject *ParseWith(Parser *P, int IsAsync) { Token *Start = NextTok(P); if (Start->Kind == TK_NAME && TokIsName(Start, "async")) { Start = NextTok(P); /* with */ } PyObject *Items = NewList(); if (Items == NULL) { return NULL; } for (;;) { PyObject *Ctx = ParseExpr(P); if (Ctx == NULL) { Py_DECREF(Items); return NULL; } PyObject *OptionalVars = NULL; if (AtName(P, "as")) { NextTok(P); OptionalVars = ParseTarget(P); if (OptionalVars == NULL) { Py_DECREF(Ctx); Py_DECREF(Items); return NULL; } } PyObject *Argv[2] = { Ctx, OptionalVars ? OptionalVars : Py_None }; PyObject *Item = NewNode(P, "withitem", Argv, 2); Py_DECREF(Ctx); Py_XDECREF(OptionalVars); if (Item == NULL) { Py_DECREF(Items); return NULL; } /* withitem 无位置属性 */ (void)Start; PyList_Append(Items, Item); Py_DECREF(Item); if (AtOp(P, ",")) { NextTok(P); continue; } break; } if (!ExpectOp(P, ":")) { Py_DECREF(Items); return NULL; } PyObject *Body = ParseSuite(P); if (Body == NULL) { Py_DECREF(Items); return NULL; } PyObject *Argv[3] = { Items, Body, Py_None }; PyObject *Node = NewNode(P, IsAsync ? "AsyncWith" : "With", Argv, 3); Py_DECREF(Items); Py_DECREF(Body); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* ================= match 语句(PEP 634) ================= */ static PyObject *ParsePattern(Parser *P); static PyObject *ParsePatternOr(Parser *P); static PyObject *ParsePatternAtom(Parser *P); static PyObject *ParsePatternValue(Parser *P); static PyObject *ParseMatchValueAttr(Parser *P); static PyObject *ParseMatchClass(Parser *P); static PyObject *ParsePatternClassName(Parser *P); static PyObject *ParseMatchSequence(Parser *P); static PyObject *ParseMatchMapping(Parser *P); static PyObject *ParseMatch(Parser *P) { Token *Start = NextTok(P); /* match */ PyObject *Subject = ParseExpr(P); if (Subject == NULL) { return NULL; } if (!ExpectOp(P, ":")) { Py_DECREF(Subject); return NULL; } if (!ExpectNEWLINE(P)) { Py_DECREF(Subject); return NULL; } Token *IndentTok = NextTok(P); if (IndentTok->Kind != TK_INDENT) { SyntaxErrorAt(P, IndentTok, "expected INDENT"); Py_DECREF(Subject); return NULL; } PyObject *Cases = NewList(); if (Cases == NULL) { Py_DECREF(Subject); return NULL; } SkipNEWLINE(P); while (AtName(P, "case")) { Token *CaseStart = NextTok(P); PyObject *Pattern = ParsePattern(P); if (Pattern == NULL) { Py_DECREF(Cases); Py_DECREF(Subject); return NULL; } PyObject *Guard = NULL; if (AtName(P, "if")) { NextTok(P); Guard = ParseExpr(P); if (Guard == NULL) { Py_DECREF(Pattern); Py_DECREF(Cases); Py_DECREF(Subject); return NULL; } } if (!ExpectOp(P, ":")) { Py_DECREF(Pattern); Py_XDECREF(Guard); Py_DECREF(Cases); Py_DECREF(Subject); return NULL; } PyObject *CaseBody = ParseSuite(P); if (CaseBody == NULL) { Py_DECREF(Pattern); Py_XDECREF(Guard); Py_DECREF(Cases); Py_DECREF(Subject); return NULL; } PyObject *Argv[3] = { Pattern, Guard ? Guard : Py_None, CaseBody }; PyObject *Mc = NewNode(P, "match_case", Argv, 3); Py_DECREF(Pattern); Py_XDECREF(Guard); Py_DECREF(CaseBody); if (Mc == NULL) { Py_DECREF(Cases); Py_DECREF(Subject); return NULL; } /* match_case 无位置属性 */ (void)CaseStart; PyList_Append(Cases, Mc); Py_DECREF(Mc); SkipNEWLINE(P); } Token *DedentTok = NextTok(P); if (DedentTok->Kind != TK_DEDENT) { SyntaxErrorAt(P, DedentTok, "expected DEDENT"); Py_DECREF(Cases); Py_DECREF(Subject); return NULL; } PyObject *Argv[3] = { Subject, Cases, Py_False }; PyObject *Node = NewNode(P, "Match", Argv, 3); Py_DECREF(Subject); Py_DECREF(Cases); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* switch 的 case 标签是否合法:只允许常量 / 枚举变体 / 多值或模式 * (MatchValue / MatchSingleton / MatchClass / MatchOr<上述>) */ static int SwitchPatAllowed(PyObject *Pat) { if (Pat == NULL) { return 0; } const char *N = Py_TYPE(Pat)->tp_name; if (strcmp(N, "MatchValue") == 0 || strcmp(N, "MatchSingleton") == 0 || strcmp(N, "MatchClass") == 0) { return 1; } /* 通配 `case _`(MatchAs 无子模式)等价 default */ if (strcmp(N, "MatchAs") == 0) { PyObject *Inner = PyObject_GetAttrString(Pat, "pattern"); if (Inner == NULL) { PyErr_Clear(); return 0; } int IsWild = (Inner == Py_None); Py_DECREF(Inner); return IsWild; } if (strcmp(N, "MatchOr") == 0) { PyObject *Pats = PyObject_GetAttrString(Pat, "patterns"); if (Pats == NULL) { PyErr_Clear(); return 0; } if (!PyList_Check(Pats)) { Py_DECREF(Pats); return 0; } Py_ssize_t Count = PyList_Size(Pats); int Ok = (Count > 0); for (Py_ssize_t I = 0; I < Count && Ok; I++) { if (!SwitchPatAllowed(PyList_GetItem(Pats, I))) { Ok = 0; } } Py_DECREF(Pats); return Ok; } return 0; } /* switch 的 case 标签修正:裸名按**值引用**处理 * * match 里裸名是捕获模式(MatchAs,pattern=None),switch 里对齐 C 的 `case NAME:` * 语义 —— 归一为 MatchValue(Name(name, Load));`_`(name=None)仍是通配,原样保留。 */ static PyObject *SwitchLabelFromPattern(Parser *P, PyObject *Pat) { if (Pat == NULL || strcmp(Py_TYPE(Pat)->tp_name, "MatchAs") != 0) { return Pat; } PyObject *Inner = PyObject_GetAttrString(Pat, "pattern"); PyObject *NameStr = PyObject_GetAttrString(Pat, "name"); if (Inner == NULL || NameStr == NULL) { PyErr_Clear(); Py_XDECREF(Inner); Py_XDECREF(NameStr); return Pat; } int IsBareName = (Inner == Py_None && NameStr != Py_None); Py_DECREF(Inner); if (!IsBareName) { Py_DECREF(NameStr); return Pat; } PyObject *Load = MakeCtx(P, "Load"); if (Load == NULL) { Py_DECREF(NameStr); return Pat; } PyObject *NameArgv[2] = { NameStr, Load }; PyObject *NameNode = NewNode(P, "Name", NameArgv, 2); Py_DECREF(Load); if (NameNode == NULL) { Py_DECREF(NameStr); return Pat; } /* Name 文本已在 NameNode 内自持,可安全释放 */ Py_DECREF(NameStr); PyObject *MvArgv[1] = { NameNode }; PyObject *Mv = NewNode(P, "MatchValue", MvArgv, 1); Py_DECREF(NameNode); if (Mv == NULL) { return Pat; } Py_DECREF(Pat); return Mv; } /* switch 语句(C switch 语义):脱糖为 is_switch=True 的 Match * * switch : * case <常量 | 枚举变体>: # 可 `case 1 | 2:` 多值 * default: * * case 标签只支持常量 / 枚举变体 / 多值或模式,不支持 if 守卫。 */ static PyObject *ParseSwitch(Parser *P) { Token *Start = NextTok(P); /* switch */ PyObject *Subject = ParseExpr(P); if (Subject == NULL) { return NULL; } if (!ExpectOp(P, ":")) { Py_DECREF(Subject); return NULL; } if (!ExpectNEWLINE(P)) { Py_DECREF(Subject); return NULL; } Token *IndentTok = NextTok(P); if (IndentTok->Kind != TK_INDENT) { SyntaxErrorAt(P, IndentTok, "expected INDENT"); Py_DECREF(Subject); return NULL; } PyObject *Cases = NewList(); if (Cases == NULL) { Py_DECREF(Subject); return NULL; } SkipNEWLINE(P); while (1) { PyObject *Pattern = NULL; Token *CaseStart = NULL; if (AtName(P, "case")) { CaseStart = NextTok(P); /* case */ Pattern = ParsePattern(P); if (Pattern == NULL) { Py_DECREF(Cases); Py_DECREF(Subject); return NULL; } Pattern = SwitchLabelFromPattern(P, Pattern); if (!SwitchPatAllowed(Pattern)) { SyntaxErrorAt(P, CaseStart, "switch case label must be a constant or enum variant"); Py_DECREF(Pattern); Py_DECREF(Cases); Py_DECREF(Subject); return NULL; } if (AtName(P, "if")) { SyntaxErrorAt(P, PeekTok(P, 0), "switch case does not support if guard"); Py_DECREF(Pattern); Py_DECREF(Cases); Py_DECREF(Subject); return NULL; } } else if (AtName(P, "default") && TokIsOp(PeekTok(P, 1), ":")) { CaseStart = NextTok(P); /* default */ PyObject *WildArgv[2] = { Py_None, Py_None }; Pattern = NewNode(P, "MatchAs", WildArgv, 2); if (Pattern == NULL) { Py_DECREF(Cases); Py_DECREF(Subject); return NULL; } FixLoc(P, Pattern, CaseStart); } else { break; } if (!ExpectOp(P, ":")) { Py_DECREF(Pattern); Py_DECREF(Cases); Py_DECREF(Subject); return NULL; } PyObject *CaseBody = ParseSuite(P); if (CaseBody == NULL) { Py_DECREF(Pattern); Py_DECREF(Cases); Py_DECREF(Subject); return NULL; } PyObject *McArgv[3] = { Pattern, Py_None, CaseBody }; PyObject *Mc = NewNode(P, "match_case", McArgv, 3); Py_DECREF(Pattern); Py_DECREF(CaseBody); if (Mc == NULL) { Py_DECREF(Cases); Py_DECREF(Subject); return NULL; } PyList_Append(Cases, Mc); Py_DECREF(Mc); SkipNEWLINE(P); } Token *DedentTok = NextTok(P); if (DedentTok->Kind != TK_DEDENT) { SyntaxErrorAt(P, DedentTok, "expected DEDENT"); Py_DECREF(Cases); Py_DECREF(Subject); return NULL; } PyObject *Argv[3] = { Subject, Cases, Py_True }; PyObject *Node = NewNode(P, "Match", Argv, 3); Py_DECREF(Subject); Py_DECREF(Cases); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* `fallthrough` 脱糖为 `NoBreak()`(switch 生成侧识别的 fallthrough 标记) */ static PyObject *ParseFallThrough(Parser *P) { Token *Start = NextTok(P); /* fallthrough */ PyObject *Load1 = MakeCtx(P, "Load"); PyObject *NameStr = Load1 ? PyUnicode_FromString("NoBreak") : NULL; if (Load1 == NULL || NameStr == NULL) { Py_XDECREF(Load1); Py_XDECREF(NameStr); return NULL; } PyObject *NameArgv[2] = { NameStr, Load1 }; PyObject *FnNode = NewNode(P, "Name", NameArgv, 2); Py_DECREF(NameStr); Py_DECREF(Load1); if (FnNode == NULL) { return NULL; } FixLoc(P, FnNode, Start); PyObject *Args = NewList(); PyObject *Keywords = NewList(); if (Args == NULL || Keywords == NULL) { Py_XDECREF(Args); Py_XDECREF(Keywords); Py_DECREF(FnNode); return NULL; } PyObject *CallArgv[3] = { FnNode, Args, Keywords }; PyObject *CallNode = NewNode(P, "Call", CallArgv, 3); Py_DECREF(Args); Py_DECREF(Keywords); Py_DECREF(FnNode); if (CallNode == NULL) { return NULL; } FixLoc(P, CallNode, Start); PyObject *ExprArgv[1] = { CallNode }; PyObject *ExprNode = NewNode(P, "Expr", ExprArgv, 1); Py_DECREF(CallNode); if (ExprNode != NULL) { FixLoc(P, ExprNode, Start); } return ExprNode; } /* 模式(顶层,处理 | 或模式) */ static PyObject *ParsePattern(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *Patterns = NewList(); if (Patterns == NULL) { return NULL; } PyObject *First = ParsePatternOr(P); if (First == NULL) { Py_DECREF(Patterns); return NULL; } PyList_Append(Patterns, First); while (AtOp(P, "|")) { NextTok(P); PyObject *Pat = ParsePatternOr(P); if (Pat == NULL) { Py_DECREF(Patterns); Py_DECREF(First); return NULL; } PyList_Append(Patterns, Pat); Py_DECREF(Pat); } if (PyList_GET_SIZE(Patterns) == 1) { Py_DECREF(Patterns); return First; } Py_DECREF(First); PyObject *Argv[1] = { Patterns }; PyObject *Node = NewNode(P, "MatchOr", Argv, 1); Py_DECREF(Patterns); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 单模式(含 as 绑定) */ static PyObject *ParsePatternOr(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *Pat = ParsePatternAtom(P); if (Pat == NULL) { return NULL; } if (AtName(P, "as")) { NextTok(P); Token *NameTok = ExpectName(P, NULL); if (NameTok == NULL) { Py_DECREF(Pat); return NULL; } PyObject *Name = PyUnicode_FromStringAndSize(NameTok->Start, NameTok->End - NameTok->Start); if (Name == NULL) { Py_DECREF(Pat); return NULL; } PyObject *Argv[2] = { Pat, Name }; PyObject *Node = NewNode(P, "MatchAs", Argv, 2); Py_DECREF(Pat); Py_DECREF(Name); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } return Pat; } /* 模式原子 */ static PyObject *ParsePatternAtom(Parser *P) { Token *Start = PeekTok(P, 0); Token *T = PeekTok(P, 0); if (T->Kind == TK_NAME) { if (TokIsName(T, "True") || TokIsName(T, "False") || TokIsName(T, "None")) { NextTok(P); PyObject *Val = TokIsName(T, "True") ? Py_True : (TokIsName(T, "False") ? Py_False : Py_None); PyObject *Argv[1] = { Val }; PyObject *Node = NewNode(P, "MatchSingleton", Argv, 1); if (Node != NULL) { FixLoc(P, Node, T); } return Node; } /* 类模式:Name(...) 或 a.b.c(...) —— 扫描属性链末尾判断 '(' */ int PeekI = 1; while (PeekTok(P, PeekI)->Kind == TK_OP && TokIsOp(PeekTok(P, PeekI), ".") && PeekTok(P, PeekI + 1)->Kind == TK_NAME) { PeekI += 2; } if (PeekTok(P, PeekI)->Kind == TK_OP && TokIsOp(PeekTok(P, PeekI), "(")) { return ParseMatchClass(P); } /* 属性值模式 a.b(无括号) */ if (PeekTok(P, 1)->Kind == TK_OP && TokIsOp(PeekTok(P, 1), ".")) { return ParseMatchValueAttr(P); } /* 捕获模式(含 _ 通配符) */ NextTok(P); PyObject *Name = NULL; if (!TokIsName(T, "_")) { Name = PyUnicode_FromStringAndSize(T->Start, T->End - T->Start); if (Name == NULL) { return NULL; } } PyObject *Argv[2] = { Py_None, Name ? Name : Py_None }; PyObject *Node = NewNode(P, "MatchAs", Argv, 2); Py_XDECREF(Name); if (Node != NULL) { FixLoc(P, Node, T); } return Node; } if (T->Kind == TK_OP && (TokIsOp(T, "[") || TokIsOp(T, "("))) { return ParseMatchSequence(P); } if (T->Kind == TK_OP && TokIsOp(T, "{")) { return ParseMatchMapping(P); } if (T->Kind == TK_NUMBER || T->Kind == TK_STRING || T->Kind == TK_FSTRING || (T->Kind == TK_OP && (TokIsOp(T, "-") || TokIsOp(T, "+")))) { PyObject *Value = ParsePatternValue(P); if (Value == NULL) { return NULL; } PyObject *Argv[1] = { Value }; PyObject *Node = NewNode(P, "MatchValue", Argv, 1); Py_DECREF(Value); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } if (T->Kind == TK_OP && TokIsOp(T, "*")) { NextTok(P); PyObject *Name = NULL; if (PeekTok(P, 0)->Kind != TK_NEWLINE && !AtOp(P, ",")) { Token *NameTok = ExpectName(P, NULL); if (NameTok == NULL) { return NULL; } Name = PyUnicode_FromStringAndSize(NameTok->Start, NameTok->End - NameTok->Start); if (Name == NULL) { return NULL; } } PyObject *Argv[1] = { Name ? Name : Py_None }; PyObject *Node = NewNode(P, "MatchStar", Argv, 1); Py_XDECREF(Name); if (Node != NULL) { FixLoc(P, Node, T); } return Node; } SyntaxErrorAt(P, T, "unexpected pattern token"); return NULL; } /* 值模式表达式(带可选 +/- 前缀) */ static PyObject *ParsePatternValue(Parser *P) { Token *Start = PeekTok(P, 0); Token *T = PeekTok(P, 0); if (T->Kind == TK_OP && (TokIsOp(T, "-") || TokIsOp(T, "+"))) { Token *OpTok = NextTok(P); PyObject *Inner; if (PeekTok(P, 0)->Kind == TK_NUMBER) { Inner = ParseNumber(P); } else if (PeekTok(P, 0)->Kind == TK_STRING || PeekTok(P, 0)->Kind == TK_FSTRING) { Inner = ParseStringConcat(P); } else { SyntaxErrorAt(P, PeekTok(P, 0), "expected literal after sign in pattern"); return NULL; } if (Inner == NULL) { return NULL; } const char *OpName = TokIsOp(OpTok, "-") ? "USub" : "UAdd"; PyObject *Op = MakeSingleton(P, OpName); if (Op == NULL) { Py_DECREF(Inner); return NULL; } PyObject *Argv[2] = { Op, Inner }; PyObject *Node = NewNode(P, "UnaryOp", Argv, 2); Py_DECREF(Op); Py_DECREF(Inner); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } if (T->Kind == TK_NUMBER) { return ParseNumber(P); } return ParseStringConcat(P); } /* 值模式属性访问:a.b.c(无括号) */ static PyObject *ParseMatchValueAttr(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *Expr = ParseExpr(P); if (Expr == NULL) { return NULL; } PyObject *Argv[1] = { Expr }; PyObject *Node = NewNode(P, "MatchValue", Argv, 1); Py_DECREF(Expr); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 类模式:Name(pos, kw=v, ...) */ static PyObject *ParseMatchClass(Parser *P) { Token *Start = PeekTok(P, 0); PyObject *ClsName = ParsePatternClassName(P); if (ClsName == NULL) { return NULL; } if (!ExpectOp(P, "(")) { Py_DECREF(ClsName); return NULL; } SkipNL(P); PyObject *Patterns = NewList(); PyObject *KwdAttrs = NewList(); PyObject *KwdPatterns = NewList(); if (Patterns == NULL || KwdAttrs == NULL || KwdPatterns == NULL) { Py_XDECREF(Patterns); Py_XDECREF(KwdAttrs); Py_XDECREF(KwdPatterns); Py_DECREF(ClsName); return NULL; } if (!AtOp(P, ")")) { for (;;) { SkipNL(P); if (AtOp(P, "*")) { NextTok(P); PyObject *Pat = ParsePattern(P); if (Pat == NULL) { Py_DECREF(Patterns); Py_DECREF(KwdAttrs); Py_DECREF(KwdPatterns); Py_DECREF(ClsName); return NULL; } PyList_Append(Patterns, Pat); Py_DECREF(Pat); } else { Token *A0 = PeekTok(P, 0); Token *A1 = PeekTok(P, 1); if (A0->Kind == TK_NAME && A1->Kind == TK_OP && TokIsOp(A1, "=")) { Token *AttrTok = NextTok(P); NextTok(P); /* '=' */ PyObject *Attr = PyUnicode_FromStringAndSize(AttrTok->Start, AttrTok->End - AttrTok->Start); PyObject *Pat = ParsePattern(P); if (Attr == NULL || Pat == NULL) { Py_XDECREF(Attr); Py_XDECREF(Pat); Py_DECREF(Patterns); Py_DECREF(KwdAttrs); Py_DECREF(KwdPatterns); Py_DECREF(ClsName); return NULL; } PyList_Append(KwdAttrs, Attr); PyList_Append(KwdPatterns, Pat); Py_DECREF(Attr); Py_DECREF(Pat); } else { PyObject *Pat = ParsePattern(P); if (Pat == NULL) { Py_DECREF(Patterns); Py_DECREF(KwdAttrs); Py_DECREF(KwdPatterns); Py_DECREF(ClsName); return NULL; } PyList_Append(Patterns, Pat); Py_DECREF(Pat); } } SkipNL(P); if (AtOp(P, ",")) { NextTok(P); if (AtOp(P, ")")) { break; } continue; } break; } } if (!ExpectOp(P, ")")) { Py_DECREF(Patterns); Py_DECREF(KwdAttrs); Py_DECREF(KwdPatterns); Py_DECREF(ClsName); return NULL; } PyObject *Argv[4] = { ClsName, Patterns, KwdAttrs, KwdPatterns }; PyObject *Node = NewNode(P, "MatchClass", Argv, 4); Py_DECREF(ClsName); Py_DECREF(Patterns); Py_DECREF(KwdAttrs); Py_DECREF(KwdPatterns); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 类模式的类名(Name / a.b.c 属性链) */ static PyObject *ParsePatternClassName(Parser *P) { Token *Start = PeekTok(P, 0); Token *NameTok = ExpectName(P, NULL); if (NameTok == NULL) { return NULL; } PyObject *Node = MakeNameNode(P, NameTok, "Load"); if (Node == NULL) { return NULL; } while (AtOp(P, ".")) { NextTok(P); Token *AttrTok = ExpectName(P, NULL); if (AttrTok == NULL) { Py_DECREF(Node); return NULL; } PyObject *AttrNode = MakeAttrNode(P, Node, AttrTok, Start); Py_DECREF(Node); if (AttrNode == NULL) { return NULL; } Node = AttrNode; } return Node; } /* 序列模式 [a, b] / (a, b) */ static PyObject *ParseMatchSequence(Parser *P) { Token *Start = NextTok(P); /* '[' 或 '(' */ const char *Close = TokIsOp(Start, "[") ? "]" : ")"; PyObject *Patterns = NewList(); if (Patterns == NULL) { return NULL; } SkipNL(P); if (!AtOp(P, Close)) { for (;;) { SkipNL(P); PyObject *Pat = ParsePattern(P); if (Pat == NULL) { Py_DECREF(Patterns); return NULL; } PyList_Append(Patterns, Pat); Py_DECREF(Pat); SkipNL(P); if (AtOp(P, ",")) { NextTok(P); if (AtOp(P, Close)) { break; } continue; } break; } } if (!ExpectOp(P, Close)) { Py_DECREF(Patterns); return NULL; } PyObject *Argv[1] = { Patterns }; PyObject *Node = NewNode(P, "MatchSequence", Argv, 1); Py_DECREF(Patterns); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* 映射模式 {k: v, **rest} */ static PyObject *ParseMatchMapping(Parser *P) { Token *Start = NextTok(P); /* '{' */ PyObject *Keys = NewList(); PyObject *Patterns = NewList(); PyObject *Rest = NULL; if (Keys == NULL || Patterns == NULL) { Py_XDECREF(Keys); Py_XDECREF(Patterns); return NULL; } SkipNL(P); if (!AtOp(P, "}")) { for (;;) { SkipNL(P); if (AtOp(P, "**")) { NextTok(P); Token *NameTok = ExpectName(P, NULL); if (NameTok == NULL) { Py_DECREF(Keys); Py_DECREF(Patterns); return NULL; } Rest = PyUnicode_FromStringAndSize(NameTok->Start, NameTok->End - NameTok->Start); if (Rest == NULL) { Py_DECREF(Keys); Py_DECREF(Patterns); return NULL; } } else { PyObject *Key = ParseExpr(P); if (Key == NULL) { Py_DECREF(Keys); Py_DECREF(Patterns); Py_XDECREF(Rest); return NULL; } if (!ExpectOp(P, ":")) { Py_DECREF(Key); Py_DECREF(Keys); Py_DECREF(Patterns); Py_XDECREF(Rest); return NULL; } PyObject *Pat = ParsePattern(P); if (Pat == NULL) { Py_DECREF(Key); Py_DECREF(Keys); Py_DECREF(Patterns); Py_XDECREF(Rest); return NULL; } PyList_Append(Keys, Key); PyList_Append(Patterns, Pat); Py_DECREF(Key); Py_DECREF(Pat); } SkipNL(P); if (AtOp(P, ",")) { NextTok(P); if (AtOp(P, "}")) { break; } continue; } break; } } if (!ExpectOp(P, "}")) { Py_DECREF(Keys); Py_DECREF(Patterns); Py_XDECREF(Rest); return NULL; } PyObject *Argv[3] = { Keys, Patterns, Rest ? Rest : Py_None }; PyObject *Node = NewNode(P, "MatchMapping", Argv, 3); Py_DECREF(Keys); Py_DECREF(Patterns); Py_XDECREF(Rest); if (Node != NULL) { FixLoc(P, Node, Start); } return Node; } /* ================= 模块入口 ================= */ static PyObject *VastC_Parse(PyObject *Self, PyObject *Args, PyObject *Kwargs) { static char *KwList[] = {"source", "mode", NULL}; const char *Src = NULL; Py_ssize_t Len = 0; const char *Mode = "exec"; if (!PyArg_ParseTupleAndKeywords(Args, Kwargs, "s#|s:parse", KwList, &Src, &Len, &Mode)) { return NULL; } Token *Tokens = NULL; int NTokens = 0; int *LineStarts = NULL; int NLineStarts = 0; if (!TokenizeText(Src, Len, &Tokens, &NTokens, &LineStarts, &NLineStarts)) { PyErr_SetString(PyExc_MemoryError, "vast_c: out of memory during tokenize"); return NULL; } Parser P; P.Src = Src; P.Len = Len; P.Tokens = Tokens; P.NTokens = NTokens; P.Idx = 0; P.LineStarts = LineStarts; P.NLineStarts = NLineStarts; P.Error = 0; P.ErrMsg = NULL; P.ErrLine = 0; P.ErrTok = NULL; P.FStringExprEnd = 0; P.InTypeAnnotation = 0; P.InClassBody = 0; P.InCIfCond = 0; P.PtrSuffixTail = NULL; PyObject *Tree = ParseModule(&P); if (Tree == NULL) { if (P.Error) { /* 报错必须自足可定位:带上 类型名 + token 原文 + 行号,措辞与 * Python ExprParser 的 `unexpected token OP('*') at line N` 一致, * 这样 `[vast] C 解析器失败,回退纯 Python:<文件>: …` 一行即可定位。 * 注意:P.ErrTok 指向 Tokens 数组内部,必须在 PyMem_Free 之前读取 * (否则读到 free 链表指针,首个 token 会被写成 ENDMARKER(''))。 */ char TokBuf[64]; const char *TokName = "ENDMARKER"; TokBuf[0] = '\0'; if (P.ErrTok != NULL) { TokName = TokKindName(P.ErrTok->Kind); Py_ssize_t TL = (Py_ssize_t)(P.ErrTok->End - P.ErrTok->Start); if (TL < 0) { TL = 0; } if (TL > (Py_ssize_t)sizeof(TokBuf) - 1) { TL = (Py_ssize_t)sizeof(TokBuf) - 1; } for (Py_ssize_t I = 0; I < TL; I++) { char C = P.ErrTok->Start[I]; TokBuf[I] = (C == '\n' || C == '\r') ? ' ' : C; } TokBuf[TL] = '\0'; } PyErr_Format(PyExc_SyntaxError, "%s %s('%s') at line %d", P.ErrMsg ? P.ErrMsg : "vast_c: syntax error", TokName, TokBuf, P.ErrLine); } PyMem_Free(Tokens); PyMem_Free(LineStarts); return NULL; } PyMem_Free(Tokens); PyMem_Free(LineStarts); if (strcmp(Mode, "exec") == 0) { return Tree; } if (strcmp(Mode, "eval") == 0) { /* 复用 vast.parse 的 eval 语义:暴露 Expr 的 value 为 Expression 节点 */ PyObject *BodyAttr = PyObject_GetAttrString(Tree, "body"); Py_DECREF(Tree); if (BodyAttr == NULL || PyList_GET_SIZE(BodyAttr) != 1) { Py_XDECREF(BodyAttr); PyErr_SetString(PyExc_SyntaxError, "vast_c: eval mode requires single expression"); return NULL; } PyObject *Stmt = PyList_GetItem(BodyAttr, 0); /* borrowed */ PyObject *Value = PyObject_GetAttrString(Stmt, "value"); Py_DECREF(BodyAttr); if (Value == NULL) { return NULL; } PyObject *Argv2[1]; Argv2[0] = Value; PyObject *ExprNode = NewNode(&P, "Expression", Argv2, 1); Py_DECREF(Value); return ExprNode; } if (strcmp(Mode, "single") == 0) { PyObject *BodyAttr = PyObject_GetAttrString(Tree, "body"); Py_DECREF(Tree); if (BodyAttr == NULL) { return NULL; } PyObject *Argv2[1]; Argv2[0] = BodyAttr; PyObject *IntNode = NewNode(&P, "Interactive", Argv2, 1); Py_DECREF(BodyAttr); return IntNode; } Py_DECREF(Tree); PyErr_SetString(PyExc_ValueError, "vast_c: unsupported mode"); return NULL; } static PyMethodDef VastC_Methods[] = { {"parse", (PyCFunction)VastC_Parse, METH_VARARGS | METH_KEYWORDS, "parse(source, mode='exec') -> vast.nodes 树(完整 Python 3.12 + Viper 软关键字)"}, {NULL, NULL, 0, NULL}, }; static struct PyModuleDef VastC_Module = { PyModuleDef_HEAD_INIT, "vast_c", "vast_c - C 版 Viper/Python 解析器(vast 加速层)", -1, VastC_Methods, }; __declspec(dllexport) PyMODINIT_FUNC PyInit__parser(void) { return PyModule_Create(&VastC_Module); }