浏览代码

Move some files

Joeri Exelmans 5 年之前
父节点
当前提交
202a78d34a

+ 1 - 2
src/sccd/runtime/expression.py

@@ -7,8 +7,7 @@ class Variable:
         self.value = value
 
 class DataModel:
-    def __init__(self, instance, names: Dict[str, Variable]):
-        self.instance = instance
+    def __init__(self, names: Dict[str, Variable]):
         self.names = names
 
 @dataclass

+ 10 - 3
src/sccd/runtime/statechart_instance.py

@@ -11,13 +11,13 @@ from sccd.runtime.debug import print_debug
 from collections import Counter
 
 ELSE_GUARD = "ELSE_GUARD"
-        
+
 class StatechartInstance(Instance):
     def __init__(self, model, object_manager):
         self.model = model
         self.object_manager = object_manager
 
-        self.data_model = DataModel(self, {
+        self.data_model = DataModel({
             "INSTATE": Variable(self.inState),
         })
 
@@ -38,7 +38,14 @@ class StatechartInstance(Instance):
         self._combo_step = ComboStepState()
         self._small_step = SmallStepState()
 
-        self.next_timer_id = 0 # each time a timer is started, a new unique future event is created for ourselves.
+        # Each time a timer is started (i.e. upon entry of a state with an 'after' transition),
+        # a new unique (for this instance) future event is added to the Controller's event queue,
+        # and the event name of the 'after' transition is set to this new event.
+        # To get unique event names, we use an ever-increasing counter, stored in each instance.
+        # This way we never have to cancel future events upon exiting a state: Upon re-entry,
+        # the event name of the after transition is overwritten, so the previous already scheduled
+        # event for the transition will be ignored.
+        self.next_timer_id = 0
 
     # enter default states, generating a set of output events
     def initialize(self, now: Timestamp) -> Tuple[bool, List[OutputEvent]]:

+ 16 - 12
src/sccd/runtime/xml_loader.py

@@ -3,19 +3,21 @@ import dataclasses
 from typing import List, Any, Optional
 import lxml.etree as ET
 from lark import Lark
-import sccd.compiler
+# import sccd.compiler
 from sccd.runtime.statechart_syntax import *
 from sccd.runtime.event import Event
 from sccd.runtime.semantic_options import SemanticConfiguration
+import sccd.schema
 
-schema_path = os.path.join(
-  os.path.dirname(sccd.compiler.__file__),
-  "schema",
-  "sccd.xsd")
+schema_dir = os.path.dirname(sccd.schema.__file__)
+
+# Schema for XML validation
+schema_path = os.path.join(schema_dir, "sccd.xsd")
 schema = ET.XMLSchema(ET.parse(schema_path))
 
-grammar = open(os.path.join(os.path.dirname(os.path.abspath(__file__)),"grammar.g"))
-l = Lark(grammar, parser="earley", start=["state_ref", "expr"])
+# Grammar for parsing state references and expressions
+grammar = open(os.path.join(schema_dir,"grammar.g"))
+parser = Lark(grammar, parser="lalr", start=["state_ref", "expr"])
 
 
 # Some types immitating the types that are produced by the compiler
@@ -182,7 +184,7 @@ def load_tree(scxml_node) -> Tuple[State, Dict[str, State]]:
   for xml_t, source in transitions:
     # Parse and find target state
     target_string = xml_t.get("target", "")
-    parse_tree = l.parse(target_string, start="state_ref")
+    parse_tree = parser.parse(target_string, start="state_ref")
     def find_state(sequence) -> State:
       if sequence.data == "relative_path":
         el = source
@@ -215,7 +217,7 @@ def load_tree(scxml_node) -> Tuple[State, Dict[str, State]]:
     # Guard
     cond = xml_t.get("cond")
     if cond is not None:
-      parse_tree = l.parse(cond, start="expr")
+      parse_tree = parser.parse(cond, start="expr")
       # print(parse_tree)
       # print(parse_tree.pretty())
       cond_expr = load_expression(parse_tree)
@@ -248,8 +250,9 @@ def load_actions(parent_node) -> List[Action]:
       pass # skip non-action tags
   return actions
 
-class UnknownExpressionType(Exception):
-  pass
+class ParseError(Exception):
+  def __init__(self, msg):
+    self.msg = msg
 
 def load_expression(parse_node) -> Expression:
   if parse_node.data == "func_call":
@@ -263,4 +266,5 @@ def load_expression(parse_node) -> Expression:
   elif parse_node.data == "array":
     elements = [load_expression(e) for e in parse_node.children]
     return Array(elements)
-  raise UnknownExpressionType()
+  raise ParseError("Can't handle expression type: "+parse_node.data)
+  

+ 0 - 0
src/sccd/schema/__init__.py


src/sccd/runtime/grammar.g → src/sccd/schema/grammar.g


src/sccd/compiler/schema/sccd-core.xsd → src/sccd/schema/sccd-core.xsd


src/sccd/compiler/schema/sccd.xsd → src/sccd/schema/sccd.xsd


+ 0 - 9
test/lib/loader.py

@@ -1,16 +1,7 @@
-import os
 from typing import Any
-import lxml.etree as ET
 from dataclasses import dataclass
-import sccd.compiler
 from sccd.runtime.xml_loader import load_model
 
-schema_path = os.path.join(
-  os.path.dirname(sccd.compiler.__file__),
-  "schema",
-  "sccd.xsd")
-schema = ET.XMLSchema(ET.parse(schema_path))
-
 @dataclass
 class Module:
   Model: Any