From 692d66ba7eb0ff55a46b68601b7cd81f825653cb Mon Sep 17 00:00:00 2001 From: Chimrod <> Date: Thu, 8 Aug 2024 10:20:24 +0200 Subject: Created a dedicated file for the single line instruction --- lib/qparser/dune | 4 +-- lib/qparser/explain.sh | 2 +- lib/qparser/expression_parser.messages | 4 --- lib/qparser/parser.mly | 5 ++- lib/qparser/qsp_instruction.mly | 62 -------------------------------- lib/qparser/qsp_single_line.mly | 65 ++++++++++++++++++++++++++++++++++ 6 files changed, 70 insertions(+), 72 deletions(-) create mode 100644 lib/qparser/qsp_single_line.mly (limited to 'lib/qparser') diff --git a/lib/qparser/dune b/lib/qparser/dune index 8297268..eea3815 100644 --- a/lib/qparser/dune +++ b/lib/qparser/dune @@ -14,7 +14,7 @@ (rule (targets parser_messages.ml) - (deps expression_parser.messages tokens.mly qsp_expression.mly qsp_instruction.mly parser.mly) + (deps expression_parser.messages tokens.mly qsp_expression.mly qsp_instruction.mly qsp_single_line.mly parser.mly) (action (with-stdout-to %{targets} (run menhir --base parser.mly --compile-errors %{deps})))) (menhir @@ -24,7 +24,7 @@ (menhir - (modules tokens parser qsp_instruction qsp_expression) + (modules tokens parser qsp_instruction qsp_expression qsp_single_line) (flags --table --external-tokens Tokens) (merge_into parser) ) diff --git a/lib/qparser/explain.sh b/lib/qparser/explain.sh index 609d208..3b44be3 100755 --- a/lib/qparser/explain.sh +++ b/lib/qparser/explain.sh @@ -2,4 +2,4 @@ menhir --explain tokens.mly qsp_expression.mly --base qsp_expression.mly menhir --explain tokens.mly qsp_expression.mly qsp_instruction.mly --base qsp_instruction.mly -menhir --explain tokens.mly qsp_expression.mly qsp_instruction.mly parser.mly --base parser.mly +menhir --explain tokens.mly qsp_expression.mly qsp_instruction.mly qsp_single_line.mly parser.mly --base parser.mly diff --git a/lib/qparser/expression_parser.messages b/lib/qparser/expression_parser.messages index 6d32f16..b708d36 100644 --- a/lib/qparser/expression_parser.messages +++ b/lib/qparser/expression_parser.messages @@ -23,10 +23,6 @@ main: LOCATION_START EOL ACT IDENT COLUMN EOL LOCATION_END A block starting with `ACT` is not closed by `END` If there are nested blocks, the error will points the highest block. -main: LOCATION_START EOL IF IDENT COLUMN ELSE R_PAREN - - Too manies instructions on a single line. - main: LOCATION_START EOL IF IDENT COLUMN EOL IDENT AMPERSAND LOCATION_END Unclosed `IF` block. Another block ends before the `END` instruction. diff --git a/lib/qparser/parser.mly b/lib/qparser/parser.mly index 5c83fc2..d075e3e 100644 --- a/lib/qparser/parser.mly +++ b/lib/qparser/parser.mly @@ -49,9 +49,6 @@ start_location: 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; body; pos; clauses } = a in let elifs, else_ = match clauses with @@ -68,6 +65,8 @@ line_statement: { let {loc; expression; body; _} = a in Analyzer.Instruction.act loc ~label:expression body } + | b = inlined_block(line_sep) + { b } (** Represent an instruction which can either be on a single line, or created in a block until an END diff --git a/lib/qparser/qsp_instruction.mly b/lib/qparser/qsp_instruction.mly index ddcbb8d..d757ab9 100644 --- a/lib/qparser/qsp_instruction.mly +++ b/lib/qparser/qsp_instruction.mly @@ -12,41 +12,6 @@ argument(X): (** At the opposite of an expression, an instruction does not return anything. *) %public instruction: - | s = single_instruction { s } - -(** Action like act or if in a single line *) -%public inline_action: - | a = onliner(ACT) - { let loc, label, statements, _, _ = a in - let label = Analyzer.Expression.v label in - Analyzer.Instruction.act loc ~label statements - } - | a = onliner(IF) - else_opt = preceded(ELSE, instruction)? - { let loc, expr, statements, loc_s, _body = a in - let elifs = [] - and else_ = match else_opt with - | None -> None - | Some instructions -> Some ($loc(else_opt), [ instructions ]) in - Analyzer.Instruction.if_ - loc - (loc_s, Analyzer.Expression.v expr, statements) - ~elifs - ~else_ - } - | a = onliner(IF) - else_ = preceded(ELSE, inline_action) - { let loc, expr, statements, loc_s, _body = a in - let elifs = [] - and else_ = Some ($loc(else_), [ else_ ]) in - - Analyzer.Instruction.if_ - loc - (loc_s, Analyzer.Expression.v expr, statements) - ~elifs - ~else_ - } -single_instruction: | expr = expression { let expr = Analyzer.Expression.v expr in @@ -86,30 +51,3 @@ assignation_operator: | DECR { T.Decr } | MULT_EQUAL { T.Mult } | DIV_EQUAL { T.Div_assign } - -inline_instruction: - | hd = inline_instruction - tl = single_instruction - AMPERSAND+ - { tl :: hd } - | - { [] } - -final_inline_instruction: - | hd = inline_instruction - tl = instruction - | hd = inline_instruction - tl = inline_action - { tl :: hd } - | hd = inline_instruction - COMMENT - { (Analyzer.Instruction.comment $loc) :: hd } - | hd = inline_instruction - { hd } - -onliner(TOKEN): - | TOKEN - e = expression - COLUMN - s = rev (final_inline_instruction) - { $loc, e, s, $loc(s), None } diff --git a/lib/qparser/qsp_single_line.mly b/lib/qparser/qsp_single_line.mly new file mode 100644 index 0000000..9330982 --- /dev/null +++ b/lib/qparser/qsp_single_line.mly @@ -0,0 +1,65 @@ +%% + +empty: + | {} + +(** The whole block is parametrized over a token named END. In most of the + cases this token indicate the end of line, but in the case of recursive + inline instruction, this can become an empty marker (because the whole + instruction is nested inside a end_line terminated block) + *) +%public inlined_block(END): + | s = terminated(instruction, END) + { s } + | a = onliner(ACT) END + { let loc, label, statements, _, _ = a in + let label = Analyzer.Expression.v label in + Analyzer.Instruction.act loc ~label statements + } + (* This case create a conflict in the resolution : the case + if a: if b: '' else '' + can be interpreted as + if a: (if b: '' else '') + or + if a: (if b: '') else '' + *) + | a = onliner(IF) + else_opt = preceded(ELSE, inlined_block(empty))? + END + { let loc, expr, statements, loc_s, _body = a in + let elifs = [] + and else_ = match else_opt with + | None -> None + | Some instructions -> Some ($loc(else_opt), [ instructions ]) in + + Analyzer.Instruction.if_ + loc + (loc_s, Analyzer.Expression.v expr, statements) + ~elifs + ~else_ + } + +final_inline_instruction: + | hd = inline_instruction + tl = inlined_block(empty) + { tl :: hd } + | hd = inline_instruction + COMMENT + { (Analyzer.Instruction.comment $loc) :: hd } + +onliner(TOKEN): + | TOKEN + e = expression + COLUMN + s = rev (final_inline_instruction) + { $loc, e, s, $loc(s), None } + +(* This is basicaly just a loop to add as many instruction separated by & *) +inline_instruction: + | hd = inline_instruction + tl = instruction + AMPERSAND+ + { tl :: hd } + | + { [] } + -- cgit v1.2.3