text.py 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import os
  2. from lark import Lark
  3. from sccd.action_lang.parser import text as action_lang
  4. from sccd.statechart.static.tree import *
  5. from sccd.cd.globals import *
  6. _grammar_dir = os.path.dirname(__file__)
  7. with open(os.path.join(_grammar_dir, "statechart.g")) as file:
  8. _sc_grammar = action_lang.action_lang_grammar + file.read()
  9. # Lark transformer for parsetree-less parsing of expressions
  10. class StatechartTransformer(action_lang.ExpressionTransformer):
  11. def __init__(self):
  12. super().__init__()
  13. self.globals: Globals = None
  14. # override
  15. def duration_literal(self, node):
  16. d = SCDurationLiteral(node[0])
  17. self.globals.durations.append(d)
  18. return d
  19. # Event declaration parsing
  20. def event_decl_list(self, node):
  21. pos_events = []
  22. neg_events = []
  23. for n in node:
  24. if n.data == "pos":
  25. pos_events.append(n.children[0])
  26. elif n.data == "neg":
  27. neg_events.append(n.children[0])
  28. return (pos_events, neg_events)
  29. def event_decl(self, node):
  30. event_name = node[0].value
  31. event_id = self.globals.events.assign_id(event_name)
  32. return EventDecl(id=event_id, name=event_name, params_decl=node[1])
  33. # Global variables so we don't have to rebuild our parser every time
  34. # Obviously not thread-safe
  35. _transformer = StatechartTransformer()
  36. _parser = Lark(_sc_grammar, parser="lalr", start=["expr", "block", "event_decl_list", "state_ref", "semantic_choice"], transformer=_transformer)
  37. # Exported functions:
  38. def parse_expression(globals: Globals, text: str) -> Expression:
  39. _transformer.globals = globals
  40. return _parser.parse(text, start="expr")
  41. def parse_block(globals: Globals, text: str) -> Block:
  42. _transformer.globals = globals
  43. return _parser.parse(text, start="block")
  44. def parse_events_decl(globals: Globals, text: str) -> Tuple[List[EventDecl], List[EventDecl]]:
  45. _transformer.globals = globals
  46. return _parser.parse(text, start="event_decl_list")
  47. def parse_state_ref(text: str):
  48. return _parser.parse(text, start="state_ref")
  49. def parse_semantic_choice(text: str):
  50. return _parser.parse(text, start="semantic_choice")