Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 循环语法中的自动构建AST_Python_Parsing_Python 3.x_Pyparsing - Fatal编程技术网

Python 循环语法中的自动构建AST

Python 循环语法中的自动构建AST,python,parsing,python-3.x,pyparsing,Python,Parsing,Python 3.x,Pyparsing,我正在为过程演算开发一个解析器。我正在使用自动创建带有已解析对象的AST树 我的问题是,由于语法在结果树中的递归性质,我得到了解析文本中不存在的对象(AST节点) i、 e 对于A=A.b我得到 [Procdef:{'rest':([Choice:{'lhs':([Prefix:{'lhs':(['a'],{}),'rhs':([Prefix:{'lhs':(['b'],{}),'rhs':([],{}]),{},{}),'rhs':([],{}),'proc':'a'> 但我希望这是: [Pr

我正在为过程演算开发一个解析器。我正在使用自动创建带有已解析对象的AST树

我的问题是,由于语法在结果树中的递归性质,我得到了解析文本中不存在的对象(AST节点)

i、 e

对于
A=A.b
我得到
[Procdef:{'rest':([Choice:{'lhs':([Prefix:{'lhs':(['a'],{}),'rhs':([Prefix:{'lhs':(['b'],{}),'rhs':([],{}]),{},{}),'rhs':([],{}),'proc':'a'>

但我希望这是:

[Procdef:{'rest':([Prefix:{'lhs':(['a'],{}),'rhs':([Prefix:{'lhs':(['b'],{}),'rhs':([],{}]),{}),'proc':'a'>

这里的区别在于缺少
选择
节点。在我过去的项目中,我使用自己的AST结构和传递给
setParseAction
的函数,然后我只需检查rhs是否为null并传递令牌。当物体经过时,我不知道怎么做

简化代码如下:

#!/usr/bin/env python

from pyparsing import * 

class ASTNode(object):
    def __init__(self, tokens):
        self.tokens = tokens
        self.assignFields()
    def __str__(self):
        return self.__class__.__name__ + ":" + str(self.__dict__)
    __repr__ = __str__

class Procdef(ASTNode):
    def assignFields(self):
        self.proc, self.rest = self.tokens
        del self.tokens

class Choice(ASTNode):
    def assignFields(self):
        self.lhs, self.rhs = self.tokens
        del self.tokens

class Prefix(ASTNode):
    def assignFields(self):
        self.lhs, self.rhs = self.tokens
        del self.tokens

class RasParser(object):

    def grammar(self):
        prefix_op = Literal('.').suppress()
        choice_op = Literal('+').suppress()
        lpar = Literal('(').suppress()
        rpar = Literal(')').suppress()
        define = Literal('=').suppress()
        Ident = Word(alphas.upper(), alphanums + "_")
        ident = Word(alphas.lower(), alphanums + "_")
        choice = Forward()
        prefix = Forward()

        process = ident | lpar + choice + rpar
        prefix << Group(process) + Group(ZeroOrMore(prefix_op + prefix))
        choice << Group(prefix) + Group(ZeroOrMore(choice_op + prefix))
        rmdef = Ident + define + Group(choice)

        rmdef.setParseAction(Procdef)
        prefix.setParseAction(Prefix)
        choice.setParseAction(Choice)
        ras = ZeroOrMore(rmdef)
        return ras

    def parse(self, string):
        oo = self.grammar().parseString(string, parseAll=True).asList()
        print(oo)

if __name__ == "__main__":
    p = RasParser()
    model = "A = a.b" 
    print(model)
    p.parse(model)
#/usr/bin/env python
从pyparsing导入*
类节点(对象):
定义初始化(自我,令牌):
self.tokens=令牌
self.assignFields()
定义(自我):
返回self.\uuuuu类\uuuuu.\uuuuu名称\uuuuuuuu+“:”+str(self.\uuuuu dict)
__repr\uuuuu=\uuuuuu str__
类Procdef(ASTNode):
def分配字段(自):
self.proc,self.rest=self.tokens
del self.tokens
类选择(ASTNode):
def分配字段(自):
self.lhs,self.rhs=self.tokens
del self.tokens
类前缀(ASTNode):
def分配字段(自):
self.lhs,self.rhs=self.tokens
del self.tokens
类分析器(对象):
定义语法(self):
前缀_op=Literal('.')。suppress()
choice_op=Literal(“+”).suppress()
lpar=Literal(“(”).suppress()
rpar=Literal(')。suppress()
define=Literal('=')。suppress()
Ident=单词(alphas.upper(),alphanums+“”)
ident=单词(alphas.lower(),alphanums+“”)
选择=前进()
前缀=转发()
进程=标识| lpar+choice+rpar
前缀实际上,这些元素在表达式中,它们只是退化版本(没有运算符的单操作数)。递归定义意味着单个进程将被解析为退化前缀(不带运算符的前缀),而反过来又被解析为退化选择(不带运算符的选择)

您已经以右关联的方式定义了前缀。如果您的意思是左联想,那么它应该是:
前缀
choice = infixNotation(process, 
    [
    ('.', 2, opAssoc.LEFT, Prefix),
    ('+', 2, opAssoc.LEFT, Choice),
    ]
rmdef = ident("destination") + define + choice("rhs")