From 118c5c06600f6b3bed3cc1879df1017cfe936496 Mon Sep 17 00:00:00 2001 From: Derval Guillaume <gderval@uliege.be> Date: Fri, 2 Dec 2022 23:29:35 +0100 Subject: [PATCH] pass; --- src/gboml/gboml.lark | 30 ++++++++++----------- src/gboml/parsing.py | 26 +++++++++++++++--- tests/instances/ko_parsing/wrong_global.txt | 5 ++++ tests/instances/ok/complex_parsing.txt | 2 ++ tests/instances/ok/good_global.txt | 16 +++++++++++ 5 files changed, 60 insertions(+), 19 deletions(-) create mode 100644 tests/instances/ko_parsing/wrong_global.txt create mode 100644 tests/instances/ok/good_global.txt diff --git a/src/gboml/gboml.lark b/src/gboml/gboml.lark index a5864f7..33149d6 100644 --- a/src/gboml/gboml.lark +++ b/src/gboml/gboml.lark @@ -15,27 +15,27 @@ separated_list{sub, sep}: _separated_list{sub, sep} _separated_maybe_empty_list{sub, sep}: _separated_list{sub, sep}? separated_maybe_empty_list{sub, sep}: _separated_list{sub, sep}? plist{content}: content* +_block_repeat_or_pass{name, content}: name (_PASS ";" | content+) +_block_shortcut{name, content}: name (_PASS? ";" | content) +_PASS.1: "pass" // HEADER start: [time_horizon] global_block program_block program_block: _program* ?time_horizon: "#TIMEHORIZON" "T" "=" INT ";" -global_block: ("#GLOBAL" definition*)? +global_block: _block_repeat_or_pass{"#GLOBAL",definition}? _program: node | hyperedge // NODES ?node: node_definition | node_import -node_definition: "#NODE" var_or_param [loop] \ - parameters_block \ - program_block \ - variables_block \ - constraints_block \ - objectives_block - -parameters_block: ("#PARAMETERS" definition*)? -variables_block: "#VARIABLES" variable_definition* -constraints_block: ("#CONSTRAINTS" constraint*)? -objectives_block: ("#OBJECTIVES" objective*)? +node_definition: _block_shortcut{_node_header, _node_content} +_node_header: "#NODE" var_or_param [loop] +_node_content: parameters_block program_block variables_block constraints_block objectives_block + +parameters_block: (_block_repeat_or_pass{"#PARAMETERS",definition})? +variables_block: _block_repeat_or_pass{"#VARIABLES",variable_definition} +constraints_block: (_block_repeat_or_pass{"#CONSTRAINTS",constraint})? +objectives_block: (_block_repeat_or_pass{"#OBJECTIVES",objective})? node_import: "#NODE" ID "=" "import" var_or_param "from" STRING node_redefs node_redefs: ("with" redefinition*) | ";" @@ -45,9 +45,9 @@ variable_scope_change: ID SCOPE ";" // HYPEREDGES ?hyperedge: hyperedge_definition | hyperedge_import -hyperedge_definition: "#HYPEREDGE" var_or_param [loop] \ - parameters_block \ - constraints_block +hyperedge_definition: _block_shortcut{_hyperedge_header, _hyperedge_content} +_hyperedge_header: "#HYPEREDGE" var_or_param [loop] +_hyperedge_content: parameters_block constraints_block hyperedge_import: "#HYPEREDGE" ID "=" "import" var_or_param "from" STRING hyperedge_redefs hyperedge_redefs: "with" definition* | ";" diff --git a/src/gboml/parsing.py b/src/gboml/parsing.py index 83fd7cf..376053b 100644 --- a/src/gboml/parsing.py +++ b/src/gboml/parsing.py @@ -118,7 +118,13 @@ def _lark_to_gboml(tree: Tree, filename: Optional[str] = None) -> GBOMLGraph: def program_block(self, meta: Meta, *childrens: list[Node | HyperEdge]) -> NodesAndHyperEdges: return self.NodesAndHyperEdges([x for x in childrens if isinstance(x, Node)], [x for x in childrens if isinstance(x, HyperEdge)]) - def hyperedge_definition(self, meta: Meta, name: VarOrParam, loop: Optional[Loop], param_block: list[Definition], constraint_block: list[Constraint]): + def hyperedge_definition(self, meta: Meta, name: VarOrParam, loop: Optional[Loop], + param_block: list[Definition] = None, constraint_block: list[Constraint] = None): + if constraint_block is None: + constraint_block = [] + if param_block is None: + param_block = [] + if loop is None: if len(name.path) != 1 or len(name.path[0].indices) != 0: raise Exception(f"Invalid name for node: {name}") @@ -126,9 +132,21 @@ def _lark_to_gboml(tree: Tree, filename: Optional[str] = None) -> GBOMLGraph: else: return HyperEdgeGenerator(name, loop, param_block, constraint_block, meta=meta) - def node_definition(self, meta: Meta, name: VarOrParam, loop: Optional[Loop], param_block: list[Definition], subprogram_block: NodesAndHyperEdges, - variable_block: list[VariableDefinition], constraint_block: list[Constraint], - objectives_block: list[Objective]): + def node_definition(self, meta: Meta, name: VarOrParam, loop: Optional[Loop], + param_block: list[Definition] = None, subprogram_block: NodesAndHyperEdges = None, + variable_block: list[VariableDefinition] = None, constraint_block: list[Constraint] = None, + objectives_block: list[Objective] = None): + if objectives_block is None: + objectives_block = [] + if constraint_block is None: + constraint_block = [] + if variable_block is None: + variable_block = [] + if param_block is None: + param_block = [] + if subprogram_block is None: + subprogram_block = self.NodesAndHyperEdges([], []) + if loop is None: if len(name.path) != 1 or len(name.path[0].indices) != 0: raise Exception(f"Invalid name for node: {name}") diff --git a/tests/instances/ko_parsing/wrong_global.txt b/tests/instances/ko_parsing/wrong_global.txt new file mode 100644 index 0000000..67d6345 --- /dev/null +++ b/tests/instances/ko_parsing/wrong_global.txt @@ -0,0 +1,5 @@ +#GLOBAL + +#NODE x + #VARIABLES + internal: a; \ No newline at end of file diff --git a/tests/instances/ok/complex_parsing.txt b/tests/instances/ok/complex_parsing.txt index fed325b..2259377 100644 --- a/tests/instances/ok/complex_parsing.txt +++ b/tests/instances/ok/complex_parsing.txt @@ -15,8 +15,10 @@ c internal; #NODE nodeL[i] for i in [0:10] #VARIABLES + pass; #HYPEREDGE E[i] for i in [0:10] #CONSTRAINTS + pass; #NODE node1 #PARAMETERS a = 2; diff --git a/tests/instances/ok/good_global.txt b/tests/instances/ok/good_global.txt new file mode 100644 index 0000000..559373b --- /dev/null +++ b/tests/instances/ok/good_global.txt @@ -0,0 +1,16 @@ +#GLOBAL + pass; + +#NODE x + #VARIABLES + internal: a; + +#NODE y + pass; + +#NODE z; + +#HYPEREDGE e; + +#HYPEREDGE e2 + pass; \ No newline at end of file -- GitLab