qsp_single_line.mly 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. %%
  2. empty:
  3. | {}
  4. (** The whole block is parametrized over a token named END. In most of the
  5. cases this token indicate the end of line, but in the case of recursive
  6. inline instruction, this can become an empty marker (because the whole
  7. instruction is nested inside a end_line terminated block)
  8. *)
  9. %public inlined_block(END):
  10. | s = terminated(instruction, END)
  11. { s }
  12. | a = onliner(ACT) END
  13. { let loc, label, statements, _, _ = a in
  14. let label = Analyzer.Expression.v label in
  15. Analyzer.Instruction.act loc ~label statements
  16. }
  17. (* This case create a conflict in the resolution : the case
  18. if a: if b: '' else ''
  19. can be interpreted as
  20. if a: (if b: '' else '')
  21. or
  22. if a: (if b: '') else ''
  23. *)
  24. | a = onliner(IF)
  25. else_opt = preceded(ELSE, inlined_block(empty))?
  26. END
  27. { let loc, expr, statements, loc_s, _body = a in
  28. let elifs = []
  29. and else_ = match else_opt with
  30. | None -> None
  31. | Some instructions -> Some ($loc(else_opt), [ instructions ]) in
  32. Analyzer.Instruction.if_
  33. loc
  34. (loc_s, Analyzer.Expression.v expr, statements)
  35. ~elifs
  36. ~else_
  37. }
  38. final_inline_instruction:
  39. | hd = inline_instruction
  40. tl = inlined_block(empty)
  41. { tl :: hd }
  42. | hd = inline_instruction
  43. COMMENT
  44. { (Analyzer.Instruction.comment $loc) :: hd }
  45. onliner(TOKEN):
  46. | TOKEN
  47. e = expression
  48. COLUMN
  49. s = rev (final_inline_instruction)
  50. { $loc, e, s, $loc(s), None }
  51. (* This is basicaly just a loop to add as many instruction separated by & *)
  52. inline_instruction:
  53. | hd = inline_instruction
  54. tl = instruction
  55. AMPERSAND+
  56. { tl :: hd }
  57. |
  58. { [] }