{ "info": { "author": "Sasa Trifunovic", "author_email": "sasa.s.trifunovic@gmail.com", "bugtrack_url": null, "classifiers": [], "description": "Purple\r\n======\r\n\r\nPurple has two main parts: \r\n * parser\r\n * tree maker\r\n \r\nParser\r\n------\r\n\r\nPurple parser is dynamic as he can parse any non-left-recursive grammar.\r\nGrammar is part defined by the user and part which is necessary \r\nto create ParseText obj. Grammar is represented in form of a dict, eg::\r\n\r\n grammar = {\"baseexpr\" : [[\"mathop\"]],\r\n \t\t\"mathop\": [[\"number\",\"operator\",\"mathop\"],[\"number\"]],\r\n\t \"operator\":[[\"plus\"],[\"minus\"]]}\r\n\r\n\t\t\t\r\n2nd argument which is required to create ParseText obj is grammar's start symbol.\r\nIn this case \"baseexpr\" would be the one.\r\n\r\nAfter creating ParseText obj ::\r\n\r\n parser = ParserText(grammar, \"baseexpr\")\r\n\r\nto check if some list of tokens (list of token type to be more precise) can be generated \r\nfrom specified grammar just call parse method (which returns True or False)\r\nwith token list as its argument::\r\n\r\n parser.parse(token_list)\r\n\r\nDuring parsing process, parser is making trace which indicates how to build\r\nsomething that very much resembles to AST.\r\n\r\nAST\r\n---\r\n\r\nEvery symbol in a grammar should be represented with a class of its own. \r\nDepending if symbol is a \"leaf\" or a \"node\" (it's a leaf if it doesn't have production rule\r\notherwise it's a node) corresponding class should inherit from LeafNode or Node class.\r\n\r\nSome \"leaf\" symbols obviously don't have any semantic meaning like `and` so for them there is\r\nno need to be represented with a class.\r\n\r\nSemantic meaning of each symbol is defined by overriding Node's `dooperation()` method.\r\nFor 'leaf' symbols if not overriden dooperation will return value of token associated with that\r\nparticular symbol.\r\nSo in our example for symbols mathop, operator and plus we would have::\r\n\r\n import operator\r\n\r\n class MathOpNode(Node):\r\n\t def dooperation(self):\r\n if len(self.childrens) == 3:\r\n op_func = self.childrens[1].dooperation()\r\n arg_1 = self.childrens[0].dooperation()\r\n arg_2 = self.childrens[2].dooperation()\r\n return op_func(arg_1,arg_2)\r\n else:\r\n return self.childrens[0].dooperation()\r\n \r\n class OperatorNode(Node):\r\n\t def dooperation(self):\r\n\t\t return self.childrens[0].dooperation()\r\n \r\n class PlusNode(LeafNode):\r\n\t dooperation():\r\n\t\t return operator.add\r\n\r\nFinal stage is to create dict with symbols as keys and theirs corresponding classes as values.::\r\n\r\n nodes={\r\n\t \"mathopnode\" : MathOpNode,\r\n\t \"operator\" : OperatorNode,\r\n\t \"plus\" : PlusNode,\r\n\t .\r\n\t .\r\n\t .\r\n }\r\n\r\n\r\nTo build AST(SDT) first create AST obj with token list, start node (object corresponding to start symbol), \r\ngrammar and nodes as arguments :code:`ast = AST(token_list, start_node, grammar, nodes)` \r\nand then call create_tree method with start symbol and trace (from parser) as arguments :code:`ast.create_tree(start_symbol, trace)`.\r\nAfter that tree is created and its root is :code:`tree_nodes`'s first element.\r\n\r\nAssuming you have defined semantics (with overriding :code:`dooperation()`) for every symbol, to execute your source code\r\nyou can just call :code:`ast.execute()` , which calls :code:`dooperation()` on the root of the ast.", "description_content_type": null, "docs_url": null, "download_url": "https://github.com/4toblerone/Purple/tarball/0.1", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/4toblerone/Purple", "keywords": "dsl framework domain specific language", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "purple-framework", "package_url": "https://pypi.org/project/purple-framework/", "platform": "", "project_url": "https://pypi.org/project/purple-framework/", "project_urls": { "Download": "https://github.com/4toblerone/Purple/tarball/0.1", "Homepage": "https://github.com/4toblerone/Purple" }, "release_url": "https://pypi.org/project/purple-framework/0.1/", "requires_dist": null, "requires_python": null, "summary": "Framework for building dsls.", "version": "0.1" }, "last_serial": 1316084, "releases": { "0.1": [] }, "urls": [] }