用于构建DSL的框架。
purple-framework的Python项目详细描述
- 紫色有两个主要部分:
- 分析器
- 造树机
分析器
紫色解析器是动态的,因为他可以解析任何非左递归语法。 语法是用户定义的一部分,是必要的一部分 创建parseText对象。语法以听写的形式表示,例如:
grammar = {"baseexpr" : [["mathop"]], "mathop": [["number","operator","mathop"],["number"]], "operator":[["plus"],["minus"]]}
创建ParseText对象所需的第二个参数是语法的起始符号。 在这种情况下,“baseexpr”就是其中之一。
创建ParseText对象后
parser = ParserText(grammar, "baseexpr")
检查是否可以生成一些令牌列表(更精确地说是令牌类型列表) 从指定的语法调用parse方法(返回True或False) 以令牌列表作为参数:
parser.parse(token_list)
在解析过程中,解析器正在进行跟踪,该跟踪指示如何构建 与ast非常相似的东西。
ast
语法中的每个符号都应该用它自己的类来表示。 取决于符号是“叶”还是“节点”(如果没有生产规则,则为叶 否则它是一个节点)对应的类应该继承自leafnode或node类。
一些“叶子”符号显然没有任何语义意义,比如 不需要用类来表示
每个符号的语义是通过重写节点的dooperation()方法定义的。 如果不重写“leaf”符号,dooperation将返回与该符号相关联的令牌值。 特殊符号。 因此,在我们的符号mathop,operator and plus示例中,我们将得到:
import operator class MathOpNode(Node): def dooperation(self): if len(self.childrens) == 3: op_func = self.childrens[1].dooperation() arg_1 = self.childrens[0].dooperation() arg_2 = self.childrens[2].dooperation() return op_func(arg_1,arg_2) else: return self.childrens[0].dooperation() class OperatorNode(Node): def dooperation(self): return self.childrens[0].dooperation() class PlusNode(LeafNode): dooperation(): return operator.add
最后一步是创建dict,其中符号作为键,相应的类作为值。
nodes={ "mathopnode" : MathOpNode, "operator" : OperatorNode, "plus" : PlusNode, . . . }
要构建ast(sdt),首先使用token list、start node(与start symbol对应的对象)创建ast obj,
语法和节点作为参数ast = AST(token_list, start_node, grammar, nodes)
然后调用create_tree方法,其中start symbol和trace(来自解析器)作为参数ast.create_tree(start_symbol, trace)
。
在创建树之后,它的根是tree_nodes
的第一个元素。
假设您已经为每个符号定义了语义(覆盖dooperation()
),以执行您的源代码
你可以调用ast.execute()
,它调用ast的根上的dooperation()