Files
TransPyC/lib/vast_c/vast_c.c
T
TermiNexus f19d25782f refactor(tpc): 退役 t/c 模块并将定宽类型升级为内建
删除 lib/includes/t.py、c.py,类型模型迁入 lib/core/TypeSystem.py;移除 IsTModule/_T_MODULE_NAMES 等名称判据,语法糖与内部标记统一为裸名;builtins 的 sizet/intN/uintN/fast/least/uchar/short/long 等改为编译器内建短名。
2026-10-18 13:00:58 +08:00

7730 lines
236 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* vast_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 <Python.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
/* ================= 记号(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) ============ */
/* 构造一层指针包装 base | t.CPtr(对齐 Python _MakePtrType)。 */
static PyObject *MakePtrType(Parser *P, PyObject *Base, Token *Tok) {
PyObject *CPtr = MakeTAttrNode(P, "CPtr");
if (CPtr == NULL) {
return NULL;
}
PyObject *Op = MakeSingleton(P, "BitOr");
if (Op == NULL) {
Py_DECREF(CPtr);
return NULL;
}
PyObject *Argv[3] = { Base, Op, CPtr };
PyObject *Node = NewNode(P, "BinOp", Argv, 3);
Py_DECREF(Op);
Py_DECREF(CPtr);
if (Node != NULL) {
FixLoc(P, Node, Tok);
}
return Node;
}
/* 判定当前位置的 '*'/'**' 串是否为 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;
}
/* 类型注解入口:置注解模式标志(对齐 Python ExprParser._ParseTypeAnnotation)。
*
* 值引用参数注解(仅形参位有效,对齐纯 Python 端):
* 前导 '&' + 可选名 'temp',合成联合形态 base | t.CRef(ref)/ base | t.CTempRef(temp)。
* CRef/CTempRef 非真实类,仅作注解 AST 内的名字标记(语义侧按名字识别)。
* '&'/'&temp' 之后缺类型(行尾 / ')' / ',' / ':' / '=' / ']' / '}' / ';')时响亮失败。 */
static PyObject *ParseTypeAnnotation(Parser *P) {
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`)");
return NULL;
}
}
int Saved = P->InTypeAnnotation;
P->InTypeAnnotation = 1;
PyObject *Node = ParseExpr(P);
P->InTypeAnnotation = Saved;
if (Node == NULL) {
return NULL;
}
if (RefTemp == 0) {
return Node;
}
PyObject *Marker = MakeTAttrNode(P, RefTemp == 2 ? "CTempRef" : "CRef");
if (Marker == NULL) {
Py_DECREF(Node);
return NULL;
}
PyObject *Op = MakeSingleton(P, "BitOr");
if (Op == NULL) {
Py_DECREF(Node);
Py_DECREF(Marker);
return NULL;
}
PyObject *Argv[3] = { Node, Op, Marker };
PyObject *Wrap = NewNode(P, "BinOp", Argv, 3);
Py_DECREF(Op);
Py_DECREF(Marker);
Py_DECREF(Node);
if (Wrap != NULL) {
FixLoc(P, Wrap, RefTok);
}
return Wrap;
}
/* 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 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")) {
return ParseExternDef(P, 0, NULL);
}
if (TokIsName(T, "export")) {
return ParseExternDef(P, 1, NULL);
}
if (TokIsName(T, "define") && PeekTok(P, 1)->Kind == TK_NAME) {
return ParseFunctionDef(P, 0, NULL);
}
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 (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 _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 一致,返回注解自动追加 t.CDefine) */
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);
/* 返回注解改写:<原类型> | t.CDefine / 单独 t.CDefine(宏函数标记,
NewNode 后 Returns 引用仍有效,此处仅替换 Node.returns) */
PyObject *TAttr = MakeTAttrNode(P, "CDefine");
if (TAttr != NULL) {
if (Returns != NULL) {
PyObject *Op = MakeSingleton(P, "BitOr");
if (Op != NULL) {
PyObject *ArgvB[3];
ArgvB[0] = Returns;
ArgvB[1] = Op;
ArgvB[2] = TAttr;
PyObject *Bin = NewNode(P, "BinOp", ArgvB, 3);
if (Bin != NULL) {
PyObject_SetAttrString(Node, "returns", Bin);
Py_DECREF(Bin);
}
Py_DECREF(Op);
}
} else {
PyObject_SetAttrString(Node, "returns", TAttr);
}
Py_DECREF(TAttr);
}
}
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:返回注解改写为 <原类型> | t.State(extern)/ <原类型> | t.CExport(export),
* 并设 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);
/* 返回注解改写:<原类型> | t.State / <原类型> | t.CExport(NewNode 后 Returns 引用仍有效) */
PyObject *TAttr = MakeTAttrNode(P, IsExport ? "CExport" : "State");
if (TAttr != NULL) {
if (Returns != NULL) {
PyObject *Op = MakeSingleton(P, "BitOr");
if (Op != NULL) {
PyObject *ArgvB[3];
ArgvB[0] = Returns;
ArgvB[1] = Op;
ArgvB[2] = TAttr;
PyObject *Bin = NewNode(P, "BinOp", ArgvB, 3);
if (Bin != NULL) {
PyObject_SetAttrString(Node, "returns", Bin);
Py_DECREF(Bin);
}
Py_DECREF(Op);
}
} else {
PyObject_SetAttrString(Node, "returns", TAttr);
}
Py_DECREF(TAttr);
}
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;
}
/* 构造内部标记调用 `<AttrName>(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 <expr>:` + 可选 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 <expr>:`(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 <expr>:
* 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);
}