fix(parser/lexer): 支持括号内行首 or/and、类基类跨行、CRLF 反斜杠续行(追加69/70/71)

This commit is contained in:
TermiNexus committed 2026-08-16 11:19:16 +08:00
1 parent 5e6a80c9f6
commit a7bbd68507
2 files changed
+29 -5

No files matched your search

+17 -5
View File
@@ -690,11 +690,23 @@ def tokenize(lx: Lexer | t.CPtr) -> Token | t.CPtr:
continue
# Backslash continuation line
if ch == '\\' and lx.pos + 1 < lx.len and lx.src[lx.pos + 1] == '\n':
lx.pos += 2
lx.lineno += 1
lx.col = 0
continue
# 支持 LF 与 CRLF(Windows 文件行尾):CRLF 下 `\` 后是 '\r'(非 '\n'),
# 只查 '\n' 会失效 → `\` 被当未知字符跳过、'\n' 产生 NEWLINE → 表达式
# 中断(VpiReader.vp L324 `or \` 行尾续行根因,CRLF 文件)。
if ch == '\\' and lx.pos + 1 < lx.len:
if lx.src[lx.pos + 1] == '\n':
lx.pos += 2
lx.lineno += 1
lx.col = 0
continue
if lx.src[lx.pos + 1] == '\r':
# \ + \r\n:跳 \、\r、\n
lx.pos += 2
if lx.pos < lx.len and lx.src[lx.pos] == '\n':
lx.pos += 1
lx.lineno += 1
lx.col = 0
continue
# Whitespace
if _is_space(ch):
+12
View File
@@ -482,6 +482,11 @@ def _parse_or_test(ps: Parser | t.CPtr) -> AST | t.CPtr:
"""or_test: and_test ('or' and_test)*"""
left: AST | t.CPtr = _parse_and_test(ps)
if left is None: return None
# 括号内行首 or((A\n or B)):or 前的 NL 在此跳过,否则 or_test 返回后
# 上层 _expect_op(RPar) 遇到 or 报"意外的 token 'or'"
# (CallGenMixin.vp L7918 跨模块调用检查根因;ClassGenMixin L1988 等
# 括号内换行行首 or 同理,按解析顺序未暴露)。
_skip_nl(ps)
if _cur_kw(ps) == Keyword.Or:
values: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8)
values.append(left)
@@ -501,6 +506,8 @@ def _parse_and_test(ps: Parser | t.CPtr) -> AST | t.CPtr:
"""and_test: not_test ('and' not_test)*"""
left: AST | t.CPtr = _parse_not_test(ps)
if left is None: return None
# 括号内行首 and((A\n and B)):同 or_test 修复(or 前跳 NL)
_skip_nl(ps)
if _cur_kw(ps) == Keyword.And:
values: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8)
values.append(left)
@@ -2277,6 +2284,10 @@ def _parse_classdef(ps: Parser | t.CPtr) -> AST | t.CPtr:
# bases / keywords
if _accept_op(ps, TokOp.LPar):
while not _match_op(ps, TokOp.RPar):
# 基类括号内跨行(class X(A,\n B):):逗号后换行在此跳过,
# 否则 cur=NL 非 Name/Comma → break → _expect_op(RPar) 报
# "意外的 token"(Generator.vp L34 多继承跨行根因)
_skip_nl(ps)
if _cur_type(ps) == TokenType.EndMarker: break
# base 或 keyword=value
if _cur_type(ps) == TokenType.Name:
@@ -2291,6 +2302,7 @@ def _parse_classdef(ps: Parser | t.CPtr) -> AST | t.CPtr:
bases.append(e)
if not _accept_op(ps, TokOp.Comma):
break
_skip_nl(ps) # 末基类后换行收尾(class X(A,\n B):)
_expect_op(ps, TokOp.RPar)
_expect_op(ps, TokOp.Colon)
dec_list: list[AST | t.CPtr] | t.CPtr = ps.pending_decorators