aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/qparser/dune4
-rwxr-xr-xlib/qparser/explain.sh2
-rw-r--r--lib/qparser/expression_parser.messages4
-rw-r--r--lib/qparser/parser.mly5
-rw-r--r--lib/qparser/qsp_instruction.mly62
-rw-r--r--lib/qparser/qsp_single_line.mly65
6 files changed, 70 insertions, 72 deletions
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 }
+ |
+ { [] }
+