// Grammar file for Lark-parser
// At this time is only used for parsing target state references of transitions.
// In the future will contain rules for anything else that needs to be parsed, including our action language

%import common.WS
%ignore WS

%import common.SIGNED_NUMBER
%import common.ESCAPED_STRING

_PATH_SEP: "/" 
PARENT_NODE: ".." 
CURRENT_NODE: "." 
IDENTIFIER: /[A-Za-z_][A-Za-z_0-9]*/ 

// target of a transition
state_ref: path | "(" path ("," path)+ ")" 

?path: absolute_path | relative_path 
absolute_path: _PATH_SEP _path_sequence
relative_path: _path_sequence
_path_sequence: (CURRENT_NODE | PARENT_NODE | IDENTIFIER) (_PATH_SEP _path_sequence)?


// We use the same operators and operator precedence rules as Python

COMPARE_OPERATOR: "==" | "!=" | ">" | ">=" | "<" | "<="
ADD_OPERATOR: "+" | "-"
MULT_OPERATOR: "*" | "/" | "//" | "%"

?expr: or_expr

?or_expr: and_expr
        | or_expr "or" and_expr    -> or

?and_expr: atom
         | and_expr "and" not_expr  -> and

?not_expr: comp_expr
         | "not" comp_expr           -> not

?comp_expr: add_expr
          | comp_expr COMPARE_OPERATOR add_expr -> compare


?add_expr: mult_expr
         | add_expr ADD_OPERATOR mult_expr -> add


?mult_expr: unary
          | mult_expr MULT_OPERATOR unary -> mult

?unary: atom
      | "-" atom  -> neg

?atom: IDENTIFIER               -> identifier
     | "(" expr ")"             -> group
     | literal
     | func_call
     | array

array: "[" (expr ("," expr)*)? "]"

?literal: ESCAPED_STRING -> string
        | SIGNED_NUMBER -> number
        | bool_literal -> bool

?bool_literal: TRUE | FALSE

func_call: atom "(" param_list ")"
param_list: ( expr ("," expr)* )?  -> params

TRUE: "true"
FALSE: "false"


?stmt: assignment

assignment: lhs "=" expr

?lhs: IDENTIFIER