QSParser.fsp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. %{
  2. open QS
  3. let except str = failwithf "%s" str
  4. let exceptP (p:Parsing.IParseState) str =
  5. let p = p.ParserLocalStore.["LexBuffer"] :?> Microsoft.FSharp.Text.Lexing.LexBuffer<char>
  6. printfn "%A" p.Lexeme
  7. printfn "%A" p.StartPos
  8. printfn "%A" p.EndPos
  9. failwithf "%s" str
  10. let parse_error_rich = Some (fun (ctxt: Microsoft.FSharp.Text.Parsing.ParseErrorContext<_>) ->
  11. let p =
  12. ctxt.ParseState.ParserLocalStore.["LexBuffer"] :?> Microsoft.FSharp.Text.Lexing.LexBuffer<char>
  13. //|> unbox
  14. printfn "%A" ctxt.CurrentToken
  15. printfn "%A" p.Lexeme
  16. printfn "%A" p.StartPos
  17. printfn "%A" p.EndPos
  18. printfn "start col: %d" p.StartPos.Column
  19. printfn "%A" (p.StartPos.AbsoluteOffset, ctxt.CurrentToken))
  20. %}
  21. %token <string> ID COMMENT TSTRING
  22. %token <int> INT
  23. %token <float> FLOAT
  24. %token <string> STARTLOC
  25. %token ENDLOC
  26. //%token
  27. %token PLUS MINUS TIMES DIVIDE
  28. %token EQ GT GE LT LE // =, >, >=, <, <=
  29. %token MOD
  30. %token AND OR
  31. %token COMMA
  32. %token AMP // &
  33. %token LBRACE RBRACE // { }
  34. %token LBRACK RBRACK // [ ]
  35. %token LPAREN RPAREN // ( )
  36. %token NO OBJ
  37. %token EOF
  38. %token SHARP
  39. %token DOLLAR
  40. %token IF ACT
  41. %token COLON ELSE ELSEIF
  42. %token NEWLINE
  43. %token END
  44. %token SET LET
  45. %token EQP EQM INC DECR // += -= ++ --
  46. %token NEQ // ! | <>
  47. // associativity and precedences
  48. // очередность [%left; %left; ...] влияет! Чем ниже - тем приоритетнее операция.
  49. %left OR
  50. %left AND
  51. %right NO
  52. %left EQ GT GE LT LE NEQ
  53. %right OBJ
  54. %left PLUS MINUS
  55. %left MOD
  56. %left TIMES DIVIDE
  57. %left NEWLINE
  58. %nonassoc RPAREN
  59. %nonassoc LPAREN
  60. %left COMMA
  61. %left COLON
  62. %left AMP
  63. //%nonassoc NEWLINE
  64. // start
  65. %start start parseStatements
  66. %type <QS.Location list> start
  67. %type <QS.Statements list> parseStatements
  68. //%type <QS.Statements list> start
  69. %%
  70. start:
  71. //| { { Location.Name = ""; Location.Statements = [] } }
  72. | error { except "blah-blah" }
  73. | EOF { [] }
  74. | NEWLINE start { $2 }
  75. | loc start { $1::$2 }
  76. parseStatements:
  77. | NEWLINE parseStatements { $2 }
  78. | EOF { [] }
  79. | statements { $1 }
  80. loc:
  81. | error { except "error in loc" }
  82. | STARTLOC NEWLINE
  83. statements
  84. ENDLOC { Location($1, $3) }
  85. //| { exceptP parseState "начало локации не найдено" }
  86. end_:
  87. | { failwithf "отсутствует end" }
  88. | END { }
  89. elseif:
  90. | ELSEIF expr COLON NEWLINE statements { [If($2, $5, [])] }
  91. | ELSEIF expr COLON NEWLINE statements elseif { [If($2, $5, $6)] }
  92. | ELSEIF expr COLON NEWLINE statements ELSE NEWLINE statements { [If($2, $5, $8)] }
  93. statements:
  94. | { [] }
  95. | error { except "statements" }
  96. | states NEWLINE statements { $1@$3 }
  97. | assertOp EQ LBRACE NEWLINE statements RBRACE NEWLINE statements { AssertCode($1, $5) :: $8 }
  98. | COMMENT NEWLINE statements { Comment $1::$3 }
  99. | COLON ID NEWLINE statements { Sign $2::$4 }
  100. | ACT seq_ COLON states NEWLINE statements { Act($2, $4)::$6 }
  101. | ACT seq_ COLON IF expr COLON states NEWLINE statements { Act($2, [If($5, $7, [])])::$9 }
  102. | ACT seq_ COLON ACT seq_ COLON states NEWLINE statements { Act($2, [Act($5, $7)])::$9 }
  103. | ACT seq_ COLON NEWLINE statements END NEWLINE statements { Act($2, $5)::$8 }
  104. | IF expr COLON states NEWLINE statements { If($2, $4, [])::$6 }
  105. | IF expr COLON IF expr COLON states NEWLINE statements { If($2, [If($5, $7, [])], [])::$9 }
  106. | IF expr COLON ACT seq_ COLON states NEWLINE statements { If($2, [Act($5, $7)], [])::$9 }
  107. | IF expr COLON NEWLINE statements END NEWLINE statements { If($2, $5, [])::$8 }
  108. | IF expr COLON states ELSE states NEWLINE statements { If($2, $4, $6)::$8 }
  109. | IF expr COLON NEWLINE statements ELSE NEWLINE statements END NEWLINE statements { If($2, $5, $8)::$11 }
  110. | IF expr COLON NEWLINE statements elseif END NEWLINE statements { If($2, $5, $6)::$9 }
  111. //| ID seq_ COLON states NEWLINE statements { Constr($1, $2, $4)::$6 }
  112. //| ID seq_ COLON ID seq_ COLON states NEWLINE statements { Constr($1, $2, [Constr($4, $5, $7)])::$9 }
  113. //| ID seq_ COLON states ELSE states NEWLINE statements { Constr($1, $2, $4 @ $6)::$8 }
  114. //| ID seq_ COLON NEWLINE statements END NEWLINE statements { Constr($1, $2, $5)::$8 }
  115. //| IF expr COLON NEWLINE statements ELSEIF expr COLON NEWLINE statements END NEWLINE statements { If($2, $5, [If($7, $10, [])])::$13 }
  116. //| ELSEIF expr COLON NEWLINE statements { [If($2, $5, [])] }
  117. //| ID seq_ COLON NEWLINE statements ELSE NEWLINE statements END NEWLINE statements { Constr($1, $2, $5 @ $8)::$11 }
  118. states:
  119. | state AMP ACT seq_ COLON states { $1::[Act($4, $6)] }
  120. | state AMP states { $1 :: $3 }
  121. | state AMP COMMENT { $1::[Comment $3] }
  122. | state { [$1] }
  123. id:
  124. | ID { $1 }
  125. | TIMES ID { "*" + $2 }
  126. temp:
  127. | id { Func($1, []) }
  128. | id LPAREN RPAREN { Func($1, []) }
  129. | id LPAREN expr COMMA seq_ RPAREN { Func($1, $3::$5) }
  130. | TSTRING { Val(value.String $1) }
  131. state:
  132. | assertOp EQ expr { Assert( $1, $3 ) }
  133. | assertOp EQ ID val_ { Assert( $1, Func($3, [Val $4]) ) } // st_1 = input 'Введите сумму'
  134. | assertOp EQP expr { Assert( $1, Expr(Plus, $1, $3) ) }
  135. | assertOp EQM expr { Assert( $1, Expr(Minus, $1, $3) ) }
  136. /*
  137. Общий вид вызова оператора
  138. имя_оператора аргумент1, аргумент2, ...
  139. или
  140. имя_оператора (аргумент1, аргумент2, ...) */
  141. //id f(v)
  142. //id v, v2
  143. //*pl 'Яблок' + яблоко
  144. //*pl 'Груш' + груша
  145. | temp { ExprS $1 }
  146. | temp PLUS expr { ExprS( Expr(Plus, $1, $3) ) }
  147. | id seq_ { FuncS($1, $2) }
  148. ass:
  149. | id { Var $1 }
  150. | SET id { Var $2 }
  151. | LET id { Var $2 }
  152. assertOp:
  153. //| id { Var $1 }
  154. //| id LBRACK seq_ RBRACK { Func("idx", (Var $1)::$3) }
  155. | ass { $1 }
  156. | ass LBRACK seq_ RBRACK { Func("idx", $1::$3) }
  157. seq_:
  158. | expr COMMA seq_ { $1 :: $3 }
  159. | expr { [$1] }
  160. //| { [] }
  161. seqval:
  162. | val_ COMMA seqval { (Val $1)::$3 }
  163. | val_ { [Val $1] }
  164. //| { [] }
  165. expr:
  166. | val_ { Val $1 }
  167. | ID { Var $1 }
  168. | ID LPAREN RPAREN { Func($1, []) }
  169. | ID LPAREN seq_ RPAREN { Func($1, $3) }
  170. | ID LBRACK seq_ RBRACK { Func("idx", (Var $1)::$3) }
  171. | NO expr { UnarExpr(No, $2) } //if ((a+b)/c)=45+54 or (b<5 or c>45) and no obj 'лопата' and $f=$vvv+'RRRRR':p 'OK' & goto 'Next'
  172. | OBJ expr { UnarExpr(Obj, $2) }
  173. | LPAREN expr RPAREN { $2 }
  174. | expr PLUS expr { Expr.Expr(Plus, $1, $3) }
  175. | expr MINUS expr { Expr.Expr(Minus, $1, $3) }
  176. | MINUS INT %prec MINUS { Val(Int -$2) }
  177. | expr TIMES expr { Expr.Expr(Times, $1, $3) }
  178. | expr DIVIDE expr { Expr.Expr(Divide, $1, $3) }
  179. | expr EQ expr { Expr.Expr(Eq, $1, $3) }
  180. | expr GT expr { Expr.Expr(Gt, $1, $3) }
  181. | expr GE expr { Expr.Expr(Ge, $1, $3) }
  182. | expr LT expr { Expr.Expr(Lt, $1, $3) }
  183. | expr LE expr { Expr.Expr(Le, $1, $3) }
  184. | expr NEQ expr { Expr.Expr(Ne, $1, $3) }
  185. | expr AND expr { Expr.Expr(And, $1, $3) }
  186. | expr OR expr { Expr.Expr(Or, $1, $3) }
  187. | expr MOD expr { Expr(Mod, $1, $3) }
  188. val_:
  189. | INT { Int $1 }
  190. | FLOAT { Float $1 }
  191. | TSTRING { value.String $1 }
  192. %%