繁体   English   中英

使用python和Ply解析器生成器时出错

[英]Error using python and the Ply parser generator

我正在使用Ply进行教学,我非常喜欢。 我虽然使用装饰器,但未在某些功能中重复某些代码。 因此,我尝试使用以下代码:

import ply.yacc as yacc
from functools import wraps
from CLexer import Lexico


def producciones(function):
    """
    Decorator for each of the functions which represents
    grammatical rules.
    """
    variable = function.__doc__.split(':')[0].strip()
    @wraps(function)
    def wrapper(*args,**kargs):
        result = []
        for e in args[1][1:]:
            tmp = Node()
            if isinstance(e,Node):
                tmp = e 
            else:
                tmp.type = str(e)
            result.append(tmp)
        tmp = Node(result)
        tmp.type = variable
        args[1][0] = tmp
        function(*args, **kargs)
        return wrapper


class Sintaxis:

    tokens = Lexico.tokens
    start = 'programa'
    @producciones
    def p_program(self, p):
        """
        program : ABREPAREN program CIERRAPAREN program
        | 
        """



    def p_error(self, p):
        print("Syntax error at '%s'" % p.value)

    def run(self, s):
        lexico = Lexico()
        lexico.build()
        global tokens
        self.parser = yacc.yacc(debug = True, module= self)
        result =self.parser.parse(s,lexico)
        return  result




if __name__ == '__main__':
    with open("prueba.txt") as f:
        texto=f.read()
    parser = Sintaxis()
    result = parser.run(texto)

我的问题是尝试使用装饰器时,出现以下错误:

ERROR: new.py:15: Rule 'p_program' requires an argument

我没有在文档中找到此错误,方法p_program似乎接受两个参数...有任何线索吗? 谢谢您的帮助。

作为跟踪漏洞来源的教程,可以解决您的问题。 首先,让我们枚举示例代码和PLY文档之间的差异数量:

  1. 您已经在语法规则函数上使用了修饰符
  2. 您已经使用了两个参数来语法规则函数
  3. 您以空行开始了语法规则
  4. 您已使用python的"""字符串表示法-本手册中未使用
  5. 您已按照手册中弃用的方式使用了空生产
  6. 您指定了不存在的programa起始规则

这可以通过编写示例程序来解决,这些程序分别测试每个程序并显示它们是否正常工作,然后通过消除故障我们可以推断出您为什么会出错。

幸运的是,PLY发行版包含几个工作示例,可以作为手册的附件进行查阅,并且PLY主页上有一些链接 这些示例之一显示了使用"""语法指定的规则,并且还为语法规则函数使用了两个参数;这消除了原因2和4:

def p_declaration(self, p):
        """ declaration : decl_body SEMI
        """
        p[0] = p[1]

如果我们检查PLY发行版随附的更多示例,我们可以找到example\\classcalc\\calc.py ,该规则的规则以空行开头,并使用"""语法,并且还具有两个参数,消除了原因2, 3&4:

def p_expression_binop(self, p):
        """
        expression : expression PLUS expression
                  | expression MINUS expression
                  | expression TIMES expression
                  | expression DIVIDE expression
                  | expression EXP expression
        """

我们需要消除空生产符号问题。 在发行版中的所有示例程序上使用grep发现使用盲生产。 这是BASIC解释器。 在这里(在文件examples\\BASIC\\basparse.py ),我们有规则:

def p_optstep(p):
    '''optstep : STEP expr
               | empty'''
    if len(p) == 3:
       p[0] = p[2]
    else:
       p[0] = None

该规则显示了指定盲法生产的推荐方法,但是手册确实指出:

注意:您可以在任何地方编写空规则,只需指定一个空的右侧即可。 但是,我个人发现,编写“空”规则并使用“空”表示空产品更容易阅读,并且可以更清楚地说明您的意图。

如果我们重写此规则以匹配您的样式,我们可以检验假设:

def p_optstep(p):
    '''optstep : STEP expr
               | '''
    if len(p) == 3:
       p[0] = p[2]
    else:
       p[0] = None

实验结果表明,上述代码仍然有效,从而消除了我们现在只剩下原因1 6 6的原因是容易让你在你的代码消除原因5,和我们剩下的原因1.此外, grep在所有可用的工作PLY示例中,装饰器都没有显示。 这意味着,甚至没有专家,也没有人按照您的代码中所示的方式使用装饰器。 我怀疑是有原因的。 他们不工作。 PLY中装饰器的唯一用途是使用具有复杂正则表达式的令牌。

结论

  1. 停止使用装饰器
  2. 修复开始符号programa
  3. 寻求帮助时提供必要的信息


[*]凡lexicoCLexer ,其中prueba.txt 我是否必须定义自己的标记并编写自己的词法分析器,然后猜测要解析的文本? ,您应该帮助我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM