加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

Python lrparsing模块;无法解析简单的递归语法

发布时间:2020-12-20 11:32:36 所属栏目:Python 来源:网络整理
导读:expr = Ref('expr')block = '{' + Repeat(expr) + '}'expr = block | Token(re='[0-9]')START = expr 这是使用Python的lrparsing模块的语法.该模块报告语法中没有冲突. 它无法解析带有错误的字符串{{0}} lrparsing.ParseError:第1行第5列:在尝试匹配状态11
expr = Ref('expr')
block = '{' + Repeat(expr) + '}'
expr = block | Token(re='[0-9]')
START = expr

这是使用Python的lrparsing模块的语法.该模块报告语法中没有冲突.

它无法解析带有错误的字符串{{0}}
lrparsing.ParseError:第1行第5列:在尝试匹配状态11中的块时期望__end_of_input__时得到’}’

堆栈状态一步一步是:

shift  '{'; ItemSet:5='{'
shift  '{'; ItemSet:5='{' ItemSet:5='{'
shift  /[0-9]/; ItemSet:4=/[0-9]/ ItemSet:5='{' ItemSet:5='{'
reduce '}'; ItemSet:4=/[0-9]/ -- ItemSet:7=expr ItemSet:5='{' ItemSet:5='{'
reduce '}'; ItemSet:7=expr -- ItemSet:9=expr ItemSet:5='{' ItemSet:5='{'
shift  '}'; ItemSet:11='}' ItemSet:9=expr ItemSet:5='{' ItemSet:5='{'

哪个afaik意味着它正在移动{{0,然后看到}将0减少到expr,然后再次减少}而没有先移动它,这使bajeezus混淆了我.

这是一个错误,还是我在做一些无限简单和愚蠢的事情?

如果这是我的语法,我将如何重构它以满足我永恒的热情和热情的欲望?如果这是一个错误,有人可以指导我一个python模块,其语法与lrparsing最相似吗?

编辑:
重构为:

blocks = Ref('blocks')
block = Ref('block')
expr = Ref('expr')
blocks = blocks + block | THIS*0 # THIS*0 is the idiomatic way of getting the empty string
block = '{' + expr + '}'
expr = blocks | Token(re='[0-9]')
START = expr

允许正确的解析.我现在的问题是……为什么?我觉得lrparsing会早些时候向我抱怨任何解析问题……重复是不是按照我期望的方式工作?

解决方法

lrparsing有一个bug;它没有正确考虑递归重复.

您的实际问题可以通过简单的递归来解决,就像您在扩展编辑中所做的那样,尽管杂乱少一点.

block = Ref('block')
block = '{' + block + '}' | Token(re='[0-9]')
START = block

另请注意,您的原始语法允许输入{{0 {1}}}. (原因是可重复的部分可以扩展为简单的数字或再次扩展.)考虑到你的第二个语法,你可能不希望这样.

我确实用pyparsing完成了一些工作,但语法却大相径庭.类似的例子:

from pyparsing import Forward,Literal,nums,oneOf,Word

l = lambda c: Literal(c).suppress()
block = Forward()
block << (Word(nums,exact=1) ^ l('{') + block + l('}'))
print(block.parseString("{{0}}"))

输出:

['0']

希望有所帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读