首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >克服TextX解析器中的无限左递归

克服TextX解析器中的无限左递归
EN

Stack Overflow用户
提问于 2018-10-15 07:15:03
回答 2查看 309关注 0票数 0

我正在使用TextX Python (基于弓箭手 弓箭手解析器)为现有语言编写一个解析器。

但是,当我试图使用它来解析一个文件时,我得到了异常:

代码语言:javascript
复制
RecursionError: maximum recursion depth exceeded while calling a Python object

下面是一个引发此异常的最小示例:

代码语言:javascript
复制
#!/usr/bin/env python
from textx import metamodel_from_str

meta_model_string = "Expr: ( Expr '+' Expr ) | INT ;"
model_string      = "1 + 1"

mm = metamodel_from_str(meta_model_string, debug=True)
m = mm.model_from_str(model_string, debug=True)

我将其追溯到Arpeggio的左递归问题,其中声明不支持像A := A B这样的规则,应该将其转换为没有递归的规则。

因此,我的问题是:是否可以以不使用左递归的方式重写上面的Expr := Expr '+' Expr 规则?注意,真正的Expr规则要复杂得多。它的一个稍微不那么简单的版本是:

代码语言:javascript
复制
Expr: '(' Expr ')' | Expr '+' Expr | Expr '*' Expr' | '!' Expr | INT | STRING ;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-15 11:26:56

这里是textX作者。除了保罗的出色答案外,还有表达式示例,它应该为您提供一个良好的开端。

自顶向下的解析器通常不会处理左递归规则,而不会像这样的黑客攻击。如果您的语言将是复杂的、面向表达式的,那么最好尝试一些自下而上的解析器,它允许左递归,并提供声明性优先级和相关性规范。如果您喜欢textX,那么我建议您看看白兰地,它具有类似的设计目标,但是使用了自下而上的解析技术(特别是LR和GLR)。快速入门示例是您正在构建的确切语言。

这个职位中,我写了一些关于启动parglare项目的理由以及与textX/Arpeggio的不同之处。

票数 3
EN

Stack Overflow用户

发布于 2018-10-15 10:55:08

这更典型地写成:

代码语言:javascript
复制
multop: '*' | '/'
addop: '+' | '-'
Factor: INT | STRING | '(' Expr ')' ;
Term: Factor [multop Factor]... ;
Expr: Term [addop Term]... ;

现在,Expr在第一次匹配前导“(”)之前不会直接恢复自身。您还将获得与操作优先级相对应的组。(请注意,对ExprTerm的重复将产生像['1', '+', '1', '+', '1']这样的组,而您可能期望使用左递归解析器所提供的[['1', '+', '1'], '+', '1']。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52811498

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档