【发布时间】:2016-08-09 13:00:52
【问题描述】:
我正在尝试编写 Tiger 解析器。我最初使用的是 PyPEG,但由于一些困难,我选择了 Arpeggio。
我的语法真的很简单。
def number(): return _(r'[0-9]+')
def string(): return _(r"\".*?\"")
def id(): return _(r'[a-zA-Z][a-zA-Z0-9_]*')
def literal(): return [number, string]
def simple_var(): return id
def let_in_exp(): return 'let', 'in', Optional(ZeroOrMore(exp)), 'end'
param = [number, string]
params = Optional(param, ZeroOrMore(',', param))
def function_call(): return id, '(', params, ')'
exp = [let_in_exp, simple_var, literal, function_call]
def code(): return OneOrMore(exp), EOF
困难在于let-in-exp 表达式。
let in let in let in end end end 是有效的 Tiger。
但是 - 目前 - 琶音不能按原样识别 let-in-exp,而是识别为三个 simple-var。实际上,进入 ZeroOrMore(exp) 时,它消耗了 end,因此找不到 let-in-exp。
如何解决这样的问题?
【问题讨论】:
-
我认为问题在于'let'、'in'和'end'也匹配为
id。我不确定 PyPEG 如何让您定义否定的前瞻,但如果您可以扩展id以在匹配正则表达式之前不匹配关键字,那么我认为您的递归将起作用。跨度> -
我在其他项目中搜索lookaheads,终于找到
Not()和And()。那解决了它。所以非常感谢!无论如何,没有更惯用的方式来编写 PEG 语法吗?
标签: python parsing grammar peg