fix(vast): 修复 match 类模式与 or 模式解析与 CPython 不一致
- case ClassName.attr(...) 类模式:扫描属性链末尾判断 '(',
此前只查首 token 后 '(',LLVMType.Ptr(...) 被误解析为
MatchValue(Call) → TPC 对 renum match 走值模式分支,对枚举
构造表达式运行时求值生成 ptrtoint SSA,LLVM switch 报
'case value is not a constant integer'
- case 0 | 1 值模式:字面量/符号不再消费顶层 '|',留给
_ParsePattern 组 MatchOr(此前 ParseExpr 吞掉 '|' 成 BinOp)
This commit is contained in:
1 parent
d7213d2197
commit
aa9042173e
1 file changed
+40
-10
+40
-10
@@ -883,8 +883,12 @@ class Parser(ExprParserMixin):
|
||||
value={'True': True, 'False': False, 'None': None}[tok.Value])
|
||||
self._FixLoc(node, tok)
|
||||
return node
|
||||
# 类模式:Name(...) 或 a.b(...)
|
||||
if self._Peek(1).Type == OP and self._Peek(1).Value == '(':
|
||||
# 类模式:Name(...) 或 a.b.c(...)——扫描属性链末尾判断 '('
|
||||
peek_i: int = 1
|
||||
while (self._Peek(peek_i).Type == OP and self._Peek(peek_i).Value == '.'
|
||||
and self._Peek(peek_i + 1).Type == NAME):
|
||||
peek_i += 2
|
||||
if self._Peek(peek_i).Type == OP and self._Peek(peek_i).Value == '(':
|
||||
return self._ParseMatchClass()
|
||||
# 属性值模式 a.b(无括号)
|
||||
if self._Peek(1).Type == OP and self._Peek(1).Value == '.':
|
||||
@@ -900,14 +904,10 @@ class Parser(ExprParserMixin):
|
||||
# 映射模式 {k: v, **rest}
|
||||
if tok.Type == OP and tok.Value == '{':
|
||||
return self._ParseMatchMapping()
|
||||
# 字面量:数字/字符串/负号
|
||||
if tok.Type == NUMBER or tok.Type == STRING or tok.Type == FSTRING:
|
||||
value: N.expr = self.ParseExpr()
|
||||
node = N.MatchValue(value=value)
|
||||
self._FixLoc(node, start)
|
||||
return node
|
||||
if tok.Type == OP and tok.Value in ('-', '+'):
|
||||
value = self.ParseExpr()
|
||||
# 值模式:数字/字符串/f-string/带符号字面量(不消费顶层 '|',留给 _ParsePattern 组 MatchOr)
|
||||
if tok.Type == NUMBER or tok.Type == STRING or tok.Type == FSTRING or (
|
||||
tok.Type == OP and tok.Value in ('-', '+')):
|
||||
value: N.expr = self._ParsePatternValue()
|
||||
node = N.MatchValue(value=value)
|
||||
self._FixLoc(node, start)
|
||||
return node
|
||||
@@ -921,6 +921,36 @@ class Parser(ExprParserMixin):
|
||||
return node
|
||||
raise SyntaxError(f"unexpected pattern token {tok.Type}({tok.Value!r})")
|
||||
|
||||
def _ParsePatternValue(self) -> N.expr:
|
||||
"""解析值模式表达式:带可选 +/- 前缀的字面量。
|
||||
|
||||
与 CPython 一致:'|' 是模式或分隔符,这里只解析单个字面量
|
||||
(数字/字符串/f-string),不消费顶层 '|'。
|
||||
"""
|
||||
start: Token = self._Peek()
|
||||
tok: Token = self._Peek()
|
||||
if tok.Type == OP and tok.Value in ('-', '+'):
|
||||
op_tok: Token = self._Next()
|
||||
inner: N.expr
|
||||
if self._Peek().Type == NUMBER:
|
||||
inner = self._ParseNumber()
|
||||
elif self._Peek().Type in (STRING, FSTRING):
|
||||
inner = self._ParseStringConcat()
|
||||
else:
|
||||
raise SyntaxError(
|
||||
f"expected literal after '{op_tok.Value}' in pattern at line {op_tok.Line}"
|
||||
)
|
||||
node: N.expr
|
||||
if op_tok.Value == '-':
|
||||
node = N.UnaryOp(op=N.USub(), operand=inner)
|
||||
else:
|
||||
node = N.UnaryOp(op=N.UAdd(), operand=inner)
|
||||
self._FixLoc(node, start)
|
||||
return node
|
||||
if tok.Type == NUMBER:
|
||||
return self._ParseNumber()
|
||||
return self._ParseStringConcat()
|
||||
|
||||
def _ParseMatchValueAttr(self) -> N.pattern:
|
||||
"""解析值模式属性访问:a.b.c(无括号)。"""
|
||||
start: Token = self._Peek()
|
||||
|
||||
Reference in new issue
Block a user