diff --git a/Testing/models/model_cmplx_in_abstr_seq1.txt b/Testing/models/model_cmplx_in_abstr_seq1.txt index f03c61d..35fc5d3 100644 --- a/Testing/models/model_cmplx_in_abstr_seq1.txt +++ b/Testing/models/model_cmplx_in_abstr_seq1.txt @@ -1,5 +1,5 @@ #! rules -S{i}:A():A2::cell => A()::cell +S{i}::A()::A2::cell => A()::cell #! complexes A2 = A().A() diff --git a/Testing/models/model_cmplx_in_abstr_seq2.txt b/Testing/models/model_cmplx_in_abstr_seq2.txt index 801026b..a8aeb53 100644 --- a/Testing/models/model_cmplx_in_abstr_seq2.txt +++ b/Testing/models/model_cmplx_in_abstr_seq2.txt @@ -1,2 +1,2 @@ #! rules -S{i}:A():A().A()::cell => A()::cell +S{i}::A()::A().A()::cell => A()::cell diff --git a/Testing/models/model_miyoshi.txt b/Testing/models/model_miyoshi.txt index 845a192..ce014a7 100644 --- a/Testing/models/model_miyoshi.txt +++ b/Testing/models/model_miyoshi.txt @@ -1,8 +1,8 @@ #! rules -S{u}:KaiC():KaiC6::cyt => S{p}:KaiC():KaiC6::cyt @ (kcat1*[KaiA2()::cyt]*[KaiC6::cyt])/(Km + [KaiC6::cyt]) -S{p}:KaiC():KaiC6::cyt => S{u}:KaiC():KaiC6::cyt @ (kcat2*[KaiB4{a}.KaiA2()::cyt]*[KaiC6::cyt])/(Km + [KaiC6::cyt]) -T{u}:KaiC():KaiC6::cyt => T{p}:KaiC():KaiC6::cyt @ (kcat3*[KaiA2()::cyt]*[KaiC6::cyt])/(Km + [KaiC6::cyt]) -T{p}:KaiC():KaiC6::cyt => T{u}:KaiC():KaiC6::cyt @ (kcat4*[KaiB4{a}.KaiA2()::cyt]*[KaiC6::cyt])/(Km + [KaiC6::cyt]) +S{u}::KaiC()::KaiC6::cyt => S{p}::KaiC()::KaiC6::cyt @ (kcat1*[KaiA2()::cyt]*[KaiC6::cyt])/(Km + [KaiC6::cyt]) +S{p}::KaiC()::KaiC6::cyt => S{u}::KaiC()::KaiC6::cyt @ (kcat2*[KaiB4{a}.KaiA2()::cyt]*[KaiC6::cyt])/(Km + [KaiC6::cyt]) +T{u}::KaiC()::KaiC6::cyt => T{p}::KaiC()::KaiC6::cyt @ (kcat3*[KaiA2()::cyt]*[KaiC6::cyt])/(Km + [KaiC6::cyt]) +T{p}::KaiC()::KaiC6::cyt => T{u}::KaiC()::KaiC6::cyt @ (kcat4*[KaiB4{a}.KaiA2()::cyt]*[KaiC6::cyt])/(Km + [KaiC6::cyt]) KaiB4{i}::cyt => KaiB4{a}::cyt @ (kcatb2*[KaiB4{i}::cyt])/(Kmb2 + [KaiB4{i}::cyt]) KaiB4{a}::cyt => KaiB4{i}::cyt @ (kcatb1*[KaiB4{a}::cyt])/(Kmb1 + [KaiB4{a}::cyt]) KaiB4{a}.KaiA2()::cyt => KaiB4{a}::cyt + KaiA2()::cyt @ k12*[KaiB4{a}.KaiA2()::cyt] diff --git a/Testing/models/model_with_complexes.txt b/Testing/models/model_with_complexes.txt index b431ca8..ed08060 100644 --- a/Testing/models/model_with_complexes.txt +++ b/Testing/models/model_with_complexes.txt @@ -1,8 +1,8 @@ - #! rules +#! rules // commenting -X(T{a}):XX::rep => X(T{o}):XX::rep @ k2*[X().X()::rep] -K{i}:X():XYZ::rep => K{p}:X():XYZ::rep @ k1*[X().Y().Z()::rep] // also here -=> P{f}:XP::rep @ 1/(1+([X().P{_}::rep])**4) // ** means power (^) +X(T{a})::XX::rep => X(T{o})::XX::rep @ k2*[X().X()::rep] +K{i}::X()::XYZ::rep => K{p}::X()::XYZ::rep @ k1*[X().Y().Z()::rep] // also here +=> P{f}::XP::rep @ 1/(1+([X().P{_}::rep])**4) // ** means power (^) #! inits // here diff --git a/Testing/models/model_with_variable.txt b/Testing/models/model_with_variable.txt index 05fefa1..04fa9a0 100644 --- a/Testing/models/model_with_variable.txt +++ b/Testing/models/model_with_variable.txt @@ -1,7 +1,7 @@ #! rules // commenting -T{a}:X():?::rep => T{o}:X():?::rep @ k2*[X().X()::rep] ; ? = { XX, XY } -K{i}:X():XY::rep => K{p}:X():XY::rep @ k1*[X().Y().Z().X()::rep] // also here +T{a}::X()::?::rep => T{o}::X()::?::rep @ k2*[X().X()::rep] ; ? = { XX, XY } +K{i}::X()::XY::rep => K{p}::X()::XY::rep @ k1*[X().Y().Z().X()::rep] // also here #! inits // here diff --git a/eBCSgen/Parsing/ParseBCSL.py b/eBCSgen/Parsing/ParseBCSL.py index 990fe7a..86c711f 100644 --- a/eBCSgen/Parsing/ParseBCSL.py +++ b/eBCSgen/Parsing/ParseBCSL.py @@ -4,7 +4,7 @@ from numpy import inf from copy import deepcopy from lark import Lark, Transformer, Tree -from lark import UnexpectedCharacters, UnexpectedToken +from lark import UnexpectedCharacters, UnexpectedToken, UnexpectedEOF from lark.load_grammar import _TERMINAL_NAMES import regex from sortedcontainers import SortedList @@ -106,16 +106,16 @@ def to_side(self): model: (sections)* rules (sections | rules)* sections: inits | definitions | complexes | regulation - rules: RULES_START _NL+ ((rule|COMMENT) _NL+)* rule _NL* - inits: INITS_START _NL+ ((init|COMMENT) _NL+)* init _NL* - definitions: DEFNS_START _NL+ ((definition|COMMENT) _NL+)* definition _NL* - complexes: COMPLEXES_START _NL+ ((cmplx_dfn|COMMENT) _NL+)* cmplx_dfn _NL* + rules: RULES_START _NL+ (rule _NL+)* rule _NL* + inits: INITS_START _NL+ (init _NL+)* init _NL* + definitions: DEFNS_START _NL+ (definition _NL+)* definition _NL* + complexes: COMPLEXES_START _NL+ (cmplx_dfn _NL+)* cmplx_dfn _NL* regulation: REGULATION_START _NL+ regulation_def _NL* - init: const? rate_complex (COMMENT)? - definition: def_param "=" number (COMMENT)? - rule: ((label)? side ARROW side ("@" rate)? (";" variable)? (COMMENT)?) | ((label)? side BI_ARROW side ("@" rate "|" rate)? (";" variable)? (COMMENT)?) - cmplx_dfn: cmplx_name "=" value (COMMENT)? + init: const? rate_complex + definition: def_param "=" number + rule: ((label)? side ARROW side ("@" rate)? (";" variable)?) | ((label)? side BI_ARROW side ("@" rate "|" rate )? (";" variable)?) + cmplx_dfn: cmplx_name "=" value side: (const? complex "+")* (const? complex)? complex: (abstract_sequence|value|cmplx_name) DOUBLE_COLON compartment @@ -157,9 +157,9 @@ def to_side(self): EXTENDED_GRAMMAR = """ abstract_sequence: atomic_complex | atomic_structure_complex | structure_complex - atomic_complex: atomic ":" (VAR | value) - atomic_structure_complex: atomic ":" structure ":" (VAR | value) - structure_complex: structure ":" (VAR | value) + atomic_complex: atomic "::" (VAR | value) + atomic_structure_complex: atomic "::" structure "::" (VAR | value) + structure_complex: structure "::" (VAR | value) variable: VAR "=" "{" cmplx_name ("," cmplx_name)+ "}" VAR: "?" @@ -695,7 +695,7 @@ def __init__(self, start): + REGULATIONS_GRAMMAR ) self.parser = Lark( - grammar, parser="lalr", propagate_positions=False, maybe_placeholders=False + grammar, parser="earley", propagate_positions=False, maybe_placeholders=False ) self.terminals = dict((v, k) for k, v in _TERMINAL_NAMES.items()) @@ -796,4 +796,14 @@ def syntax_check(self, expression: str) -> Result: "column": u.column, }, ) + except UnexpectedEOF as u: + return Result( + False, + { + "unexpected": str(u.token), + "expected": self.replace(u.expected), + "line": u.line, + "column": u.column, + }, + ) return Result(True, tree)