对着规则核一句
(每道题开头都有同一段:T() 是上一站 lexer 的替身——源码里 token 之间用空格分开,它切成 (kind, text, line, col);show() 把树写成一行:二元运算全加括号,语句之间用 |。)
还没写完整 parser,先用最笨的办法核「是不是一条 let 语句」:五个 token 逐个对照产生式。看三句各得什么:
KEYWORDS = ("let", "if", "else", "while")
CMP = (">=", "<=", "==", "!=", "<", ">")
def T(src):
toks = []
for ln, line in enumerate(src.split("\n"), 1):
pos = 0
for w in line.split():
pos = line.index(w, pos)
if w in KEYWORDS:
k = "KEYWORD"
elif w[0] == '"':
k = "STRING"
elif w.isdigit():
k = "NUMBER"
elif w[0].isalpha() or w[0] == "_":
k = "IDENT"
else:
k = "OP"
toks.append((k, w, ln, pos + 1))
pos += len(w)
toks.append(("EOF", "", ln, pos + 1))
return toks
def is_let(toks):
return (len(toks) == 6 and toks[0][1] == "let" and toks[1][0] == "IDENT"
and toks[2][1] == "=" and toks[3][0] in ("NUMBER", "STRING", "IDENT") and toks[4][1] == ";")
for s in ["let rate = 12 ;", "let = rate 12 ;", "let msg = \"hi\" ;"]:
print(is_let(T(s)), end=",")
全部评论