{"action":"created","issue":{"url":"https://api.github.com/repos/igordejanovic/textX/issues/24","repository_url":"https://api.github.com/repos/igordejanovic/textX","labels_url":"https://api.github.com/repos/igordejanovic/textX/issues/24/labels{/name}","comments_url":"https://api.github.com/repos/igordejanovic/textX/issues/24/comments","events_url":"https://api.github.com/repos/igordejanovic/textX/issues/24/events","html_url":"https://github.com/igordejanovic/textX/issues/24","id":157352407,"number":24,"title":"Recursion difference with Arpeggio and textX","user":{"login":"SnookEE","id":250132,"avatar_url":"https://avatars.githubusercontent.com/u/250132?v=3","gravatar_id":"","url":"https://api.github.com/users/SnookEE","html_url":"https://github.com/SnookEE","followers_url":"https://api.github.com/users/SnookEE/followers","following_url":"https://api.github.com/users/SnookEE/following{/other_user}","gists_url":"https://api.github.com/users/SnookEE/gists{/gist_id}","starred_url":"https://api.github.com/users/SnookEE/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SnookEE/subscriptions","organizations_url":"https://api.github.com/users/SnookEE/orgs","repos_url":"https://api.github.com/users/SnookEE/repos","events_url":"https://api.github.com/users/SnookEE/events{/privacy}","received_events_url":"https://api.github.com/users/SnookEE/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":6,"created_at":"2016-05-28T18:57:07Z","updated_at":"2016-05-31T14:49:04Z","closed_at":null,"body":"The following grammar definition in Arpeggio works properly and is able to parse a\r\npython arithmetic string.\r\n\r\n```python\r\ndef expression(): return op_prec6\r\ndef op_prec6():   return op_prec5,  ZeroOrMore(['|'],              op_prec5)\r\ndef op_prec5():   return op_prec4,  ZeroOrMore(['^'],              op_prec4)\r\ndef op_prec4():   return op_prec3,  ZeroOrMore(['&'],              op_prec3)\r\ndef op_prec3():   return op_prec2,  ZeroOrMore(['<<','>>'],        op_prec2)\r\ndef op_prec2():   return op_prec1,  ZeroOrMore(['+','-'],          op_prec1)\r\ndef op_prec1():   return op_prec0,  ZeroOrMore(['*','/','%','//'], op_prec0)\r\ndef op_prec0():   return op_prime,  ZeroOrMore(['**'],             op_prime)\r\ndef op_unary():   return                       ['-','+','~'],      op_prime\r\ndef op_prime():   return [(\"(\", expression, \")\"),number,op_unary]\r\ndef calc():       return OneOrMore(expression), EOF\r\ndef number():     return _(r'\\d+')\r\n```\r\n\r\nbut when that same grammar is expressed in the textX syntax it fails with an infinite recursion.\r\n\r\n```python\r\narith_grammar = '''\r\n/*  2 */ expression: op_prec6;\r\n/*  3 */ op_prec6:   op_prec5 | ('|'                         | op_prec5)*;\r\n/*  4 */ op_prec5:   op_prec4 | ('^'                         | op_prec4)*;\r\n/*  5 */ op_prec4:   op_prec3 | ('&'                         | op_prec3)*;\r\n/*  6 */ op_prec3:   op_prec2 | ('<<' | '>>'                 | op_prec2)*;\r\n/*  7 */ op_prec2:   op_prec1 | ('+'  | '-'                  | op_prec1)*;\r\n/*  8 */ op_prec1:   op_prec0 | ('*'  | '\\/' | '%' | '\\/\\/'  | op_prec0)*;\r\n/*  9 */ op_prec0:   op_prime | ('**'                        | op_prime)*;\r\n/* 10 */ op_unary:              ('-'  | '+' | '~'            | op_prime);\r\n/* 11 */ op_prime: ('(' expression ')') | INT | op_unary;\r\n/* 12 */ calc: expressions+=expression;\r\n'''\r\n\r\narith_meta = metamodel_from_str(arith_grammar)\r\nmetamodel_export(arith_meta, 'arith_model.dot')\r\n```\r\nThe error message is as follows\r\n```\r\nTraceback (most recent call last):\r\n  File \"C:/home/workspace_cdt/fpga_projects/python/grammer/meta-hdl.py\", line 134, in <module>\r\n    arith_meta = metamodel_from_str(arith_grammar)\r\n  File \"C:\\Anaconda2\\envs\\parse_env\\lib\\site-packages\\textx\\metamodel.py\", line 474, in metamodel_from_str\r\n    language_from_str(lang_desc, metamodel)\r\n  File \"C:\\Anaconda2\\envs\\parse_env\\lib\\site-packages\\textx\\textx.py\", line 857, in language_from_str\r\n    lang_parser = parser.getASG()\r\n  File \"C:\\Anaconda2\\envs\\parse_env\\lib\\site-packages\\arpeggio\\__init__.py\", line 1433, in getASG\r\n    sem_actions[sa_name].second_pass(self, asg_node)\r\n  File \"C:\\Anaconda2\\envs\\parse_env\\lib\\site-packages\\textx\\textx.py\", line 354, in second_pass\r\n    self._resolve_rule_refs(grammar_parser, model_parser)\r\n  File \"C:\\Anaconda2\\envs\\parse_env\\lib\\site-packages\\textx\\textx.py\", line 284, in _resolve_rule_refs\r\n    cls._tx_peg_rule = resolve(cls._tx_peg_rule, cls.__name__)\r\n  File \"C:\\Anaconda2\\envs\\parse_env\\lib\\site-packages\\textx\\textx.py\", line 278, in resolve\r\n    return _inner_resolve(node, cls_rule_name)\r\n  File \"C:\\Anaconda2\\envs\\parse_env\\lib\\site-packages\\textx\\textx.py\", line 247, in _inner_resolve\r\n\r\n...Repeat enough times to blow up the stack...\r\n\r\n  File \"C:\\Anaconda2\\envs\\parse_env\\lib\\site-packages\\textx\\textx.py\", line 253, in _inner_resolve\r\n    if initial_rule_name in model_parser.metamodel:\r\n  File \"C:\\Anaconda2\\envs\\parse_env\\lib\\site-packages\\textx\\metamodel.py\", line 411, in __contains__\r\n    self[name]\r\n  File \"C:\\Anaconda2\\envs\\parse_env\\lib\\site-packages\\textx\\metamodel.py\", line 377, in __getitem__\r\n    if name in self._current_namespace:\r\nRecursionError: maximum recursion depth exceeded\r\n```\r\n\r\nThank you for your work. "},"comment":{"url":"https://api.github.com/repos/igordejanovic/textX/issues/comments/222712343","html_url":"https://github.com/igordejanovic/textX/issues/24#issuecomment-222712343","issue_url":"https://api.github.com/repos/igordejanovic/textX/issues/24","id":222712343,"user":{"login":"SnookEE","id":250132,"avatar_url":"https://avatars.githubusercontent.com/u/250132?v=3","gravatar_id":"","url":"https://api.github.com/users/SnookEE","html_url":"https://github.com/SnookEE","followers_url":"https://api.github.com/users/SnookEE/followers","following_url":"https://api.github.com/users/SnookEE/following{/other_user}","gists_url":"https://api.github.com/users/SnookEE/gists{/gist_id}","starred_url":"https://api.github.com/users/SnookEE/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SnookEE/subscriptions","organizations_url":"https://api.github.com/users/SnookEE/orgs","repos_url":"https://api.github.com/users/SnookEE/repos","events_url":"https://api.github.com/users/SnookEE/events{/privacy}","received_events_url":"https://api.github.com/users/SnookEE/received_events","type":"User","site_admin":false},"created_at":"2016-05-31T14:49:04Z","updated_at":"2016-05-31T14:49:04Z","body":"Thanks for your help in figuring out those issues. Here is where it ended up. This is a fun tool, thank you for your efforts.\r\n\r\n```python\r\nfrom textx.metamodel import metamodel_from_str\r\nfrom textx.export import metamodel_export\r\nfrom textx.export import model_export\r\n\r\nsmall_model = False\r\n\r\nif small_model:\r\n\r\n# def number():     return _(r'\\d*\\.\\d*|\\d+')\r\n# def factor():     return [number, (\"(\", expression, \")\")]\r\n# def term():       return factor, ZeroOrMore([\"*\",\"/\"], factor)\r\n# def expression(): return term,   ZeroOrMore([\"+\", \"-\"], term)\r\n# def calc():       return OneOrMore(expression), EOF\r\n\r\n# () -> sequence       -> \\s+ delineated\r\n# [] -> ordered choice ->  |  delineated\r\n\r\n    arith_grammar = '''\r\n    expression: term    ( ('+' | '-')    term)*;\r\n    factor:     ('(' expression ')') | INT;\r\n    term:       factor  ( ('*' | '\\/') factor)*;\r\n    calc:       expressions+=expression;\r\n    '''\r\n\r\n    arith_meta = metamodel_from_str(arith_grammar)\r\n    metamodel_export(arith_meta, 'arith_model.dot')\r\n\r\n    input_expr = \"(2*3)+4\"\r\n\r\n    arith_expr = arith_meta.model_from_str(input_expr,debug=False)\r\n    model_export(arith_expr, 'arith_expr.dot')\r\n\r\nelse:\r\n\r\n    arith_grammar = '''\r\n    expr: prec6;\r\n    prec6:   op=prec5  (op=op6   op=prec5)*;\r\n    prec5:   op=prec4  (op=op5   op=prec4)*;\r\n    prec4:   op=prec3  (op=op4   op=prec3)*;\r\n    prec3:   op=prec2  (op=op3   op=prec2)*;\r\n    prec2:   op=prec1  (op=op2   op=prec1)*;\r\n    prec1:   op=prec0  (op=op1   op=prec0)*;\r\n    prec0:   op=term   (op=op0   op=term)*;\r\n    unary:              op=opU   op=term;\r\n    term:   ('(' op=prec6 ')') | op=number | op=unary;\r\n    op6:  '|'                       ;\r\n    op5:  '^'                       ;\r\n    op4:  '&'                       ;\r\n    op3:  '<<' | '>>'               ;\r\n    op2:  '+'  | '-'                ;\r\n    op1:  '*'  | '\\/' | '%' | '\\/\\/';\r\n    op0:  '**'                      ;\r\n    opU:  '-'  | '+' | '~'          ;\r\n    number: /\\d+/;\r\n    '''\r\n\r\n    input_expr = \"(2**3-1)*32--3\"\r\n    arith_meta = metamodel_from_str(arith_grammar + 'calc:    expressions+=expr;')\r\n    metamodel_export(arith_meta, 'arith_model.dot')\r\n\r\n    arith_expr = arith_meta.model_from_str(input_expr,debug=False)\r\n    model_export(arith_expr, 'arith_expr.dot')\r\n```"}}
{"actor":{"display_login":"SnookEE"}}