Browse Source

Created a dedicated file for the single line instruction

Chimrod 3 tháng trước cách đây
mục cha
commit
692d66ba7e

+ 2 - 2
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)
 )

+ 1 - 1
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

+ 0 - 4
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.

+ 2 - 3
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 

+ 0 - 62
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 }

+ 65 - 0
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 }
+    | 
+      { [] }
+