aboutsummaryrefslogtreecommitdiff
path: root/lib/qparser/qsp_single_line.mly
diff options
context:
space:
mode:
Diffstat (limited to 'lib/qparser/qsp_single_line.mly')
-rw-r--r--lib/qparser/qsp_single_line.mly65
1 files changed, 65 insertions, 0 deletions
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 }
+ |
+ { [] }
+