fix(parser/lexer): 支持括号内行首 or/and、类基类跨行、CRLF 反斜杠续行(追加69/70/71)
This commit is contained in:
1 parent
5e6a80c9f6
commit
a7bbd68507
2 files changed
+29
-5
No files matched your search
+17
-5
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user