Parsed TextX Model does not have `commands` attribute

62 views Asked by At

I parsed text using TextX. When I want to process the commands using a for loop, I get THIS:

grammar.tx

Traceback (most recent call last):
  File "C:/Users/user/SomerandomIDE/program/program/parser.py", line 100, in <module>
    main()
  File "C:/Users/user/SomerandomIDE/program/program/parser.py", line 94, in main
    program.do_it(True, True, True)
  File "C:/Users/user/SomerandomIDE/program/program/parser.py", line 85, in do_it
    if cont and intp:   cont, err = self.interpret()
  File "C:/Users/user/SomerandomIDE/program/program/parser.py", line 78, in interpret
    self._interpret(model)
  File "C:/Users/user/SomerandomIDE/program/program/parser.py", line 50, in _interpret
    for c in model.commands:
AttributeError: module 'textx.model' has no attribute 'commands'

main.py

import os
from textx import *
from textx.export import *


class Parser(object):

  def __init__(self, meta_model_path='grammar.tx', model_str='print("Hello")'):
    self.tree = []
    self.meta_model_path = os.path.abspath(meta_model_path)
    self.model_str = model_str
    self.mm = None
    self.model = None

  def __str__(self):
    return str(self.tree)

  def _interpret_function(self, c):
    result = {}
    result['type'] = 'func'
    result['callee'] = c.callee
    result['args'] = []
    for arg in c.args.arg:
      if arg.__class__.__name__ == 'UnnamedArgument':
        result['args'].append([arg.a.a])
      elif arg.__class__.__name__ == 'NamedArgument':
        result['args'].append([arg.a.a, arg.b.a])
    return result

  def _interpret_definition(self, c):
    result = {}
    result['type'] = 'defi'
    result['a'] = c.a.a
    result['b'] = c.b.a
    return result

  def _interpret_statement(self, c):
    result = {}
    result['type'] = 'stat'
    result['callee'] = c.callee
    result['checker_a'] = c.checker.a
    result['checker_b'] = c.checker.b
    result['checker_sign'] = c.checker.sign
    result['effect'] = c.effect.objs
    return result

  def _interpret(self, model):
    print(model)

    for c in model.commands:
      if c.__class__.__name__ == 'Statement':
        self.tree.append(self._interpret_statement(c))
      elif c.__class__.__name__ == 'Function':
        self.tree.append(self._interpret_function(c))
      elif c.__class__.__name__ == 'Definition':
        self.tree.append(self._interpret_definition(c))

  def export_meta_model(self, mm):
    metamodel_export(self.mm, os.path.abspath('grammar.dot'))
    return [True, None]

  def export_model(self, model):
    model_export(self.model, os.path.abspath('program.dot'))
    return [True, None]

  def interpret(self):
    print(-1)
    self.mm = metamodel_from_file(self.meta_model_path, debug=False)
    print(0)
    try:
      # self.model = self.mm.model_from_str(self.model_str)
      self.model = self.mm.model_from_file(os.path.abspath('program.prg'))
      print(type(self.model))
    except TextXSyntaxError as err:
      print('Syntax Error @ {}:{}'.format(err.line, err.col))
      print('{}'.format(err.message))
      return [False, err]
    print(1)
    self._interpret(model)
    print(2)
    return [True, None]

  def do_it(self, exp_mm=False, exp_m=False, intp=True):  # My naming skills :)
    cont = True
    err = None
    if cont and intp:   cont, err = self.interpret()
    if cont and exp_mm: cont, err = self.export_meta_model()
    if cont and exp_m:  cont, err = self.export_model()


def main(debug=False):
  program = Parser()
  print('Inp Done')
  program.do_it(True, True, True)
  print('Done')
  print(program)


if __name__ == "__main__":
  main()

program.prg

print("Heelo");
print("World");

The code is copied from the robot tutorial and about 50% is modified from the original to fit my needs.

1

There are 1 answers

0
Penguin On

I don't know why, but changing from def _interpret(self, model): and model to def _interpret(self): and self.model worked.

- def _interpret(self, model):
+ def _interpret(self):
-   print(model)
+   print(self.model)

    for c in model.commands:
      if c.__class__.__name__ == 'Statement':
        self.tree.append(self._interpret_statement(c))
      elif c.__class__.__name__ == 'Function':
        self.tree.append(self._interpret_function(c))
      elif c.__class__.__name__ == 'Definition':
        self.tree.append(self._interpret_definition(c))