%{ module T = Qsp_syntax.T %} %parameter %start main %on_error_reduce expression instruction unary_operator assignation_operator %% main: | before_location* LOCATION_START EOL+ expressions = line_statement* LOCATION_END { Analyzer.Location.location $loc expressions } before_location: | EOL {} | COMMENT EOL { } (* All these statement should terminate with EOL *) line_statement: | COMMENT EOL+ { Analyzer.Instruction.comment $loc } | COLUMN i=IDENT EOL* { Analyzer.Instruction.location $loc i } | s = terminated(instruction, line_sep) | s = terminated(inline_action, line_sep) { s } | a = action_bloc(IF, elif_else_body) { let loc, expression, statements, loc_s, body = a in let elifs, else_ = match body with | None -> [], [] | Some (elifs, else_) -> (elifs, else_) in Analyzer.Instruction.if_ loc (loc_s, expression, statements) ~elifs ~else_ } | a = action_bloc(ACT, empty_body) { let loc, label, statements, _, _ = a in Analyzer.Instruction.act loc ~label statements } (** Represent an instruction which can either be on a single line, or created in a block until an END *) %inline action_bloc(TOKEN, BODY): | TOKEN e = expression COLUMN EOL+ s = line_statement* b = BODY END TOKEN? line_sep { $loc, e, s, $loc(s), b } empty_body: | { None } elif: | ELIF e = expression COLUMN EOL+ s = line_statement* { $loc, e, s } else_: | ELSE EOL+ expressions = line_statement* { expressions } | { [] } elif_else_body: | elifs = elif* else_ = else_ { Some (elifs, else_) } %inline line_sep: | EOL+ | AMPERSAND+ EOL* {}