Advertisement
Guest User

parser.mly

a guest
Apr 9th, 2016
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.46 KB | None | 0 0
  1. /* vim:sts=2:sw=2:et:et:cc=80
  2. * parser.mly: A parser definition for pli-beancompiler
  3. *
  4. * Shared on pastebin for the fine folks on freenode.#ocaml
  5. */
  6.  
  7. %token <int> INT_LIT
  8. %token <string> STR_LIT
  9. %token <string> IDENTIFIER
  10. %token <string> FIELD
  11. %token TRUE
  12. %token FALSE
  13. %token AND
  14. %token BOOL_KW
  15. %token DO
  16. %token OD
  17. %token ELSE
  18. %token END
  19. %token IF
  20. %token FI
  21. %token INT_KW
  22. %token NOT
  23. %token OR
  24. %token PROC
  25. %token READ
  26. %token REF
  27. %token THEN
  28. %token TYPEDEF
  29. %token VAL
  30. %token WHILE
  31. %token WRITE
  32. %token BINARY_MINUS
  33. %token BINARY_PLUS
  34. %token BINARY_MULTIPLICATION
  35. %token BINARY_DIVISION
  36. %token INEQUALITY
  37. %token LESSER_EQUALITY
  38. %token GREATER_EQUALITY
  39. %token LESSER_THAN
  40. %token GREATER_THAN
  41. %token EQUALITY
  42. %token ASSIGN
  43. %token COMMA
  44. %token COLON
  45. %token SEMICOLON
  46. %token L_BRACE
  47. %token R_BRACE
  48. %token L_PAREN
  49. %token R_PAREN
  50. %token L_BRACK
  51. %token R_BRACK
  52. %token COMMENT
  53. %token REFERENCE_END
  54. %token EOF
  55. %start prog
  56. %type <Tuple> prog
  57. %%
  58. prog:
  59. | prog_typedefs prog_procs
  60. { ($1, $2) }
  61. ;
  62.  
  63. prog_typedefs:
  64. | type_def prog_typedefs
  65. { $1 :: $2 }
  66. | /* Nothing */
  67. { [] }
  68. ;
  69.  
  70. prog_procs:
  71. | proc_def prog_procs
  72. { $1 :: $2 }
  73. | /* Nothing */
  74. { [] }
  75. ;
  76.  
  77. type_def:
  78. | TYPEDEF type_spec id
  79. { ($3, $2) }
  80. ;
  81.  
  82. type_spec:
  83. /* TODO Make these rules yield consistent types? Will require a bit of
  84. * design-work, or at least discussion to work out what the best
  85. * approach here is. (Translation: MAK! HEEELLLLPPPP!)
  86. */
  87. | type_kw
  88. { $1 }
  89. | L_BRACE type_spec_field_defs R_BRACE
  90. /* Currently, type_(...) yields a non-empty list of 2-tuples,
  91. * (id, type_spec)
  92. */
  93. { $2 }
  94. | id
  95. { $1 }
  96. ;
  97.  
  98. type_kw:
  99. | BOOL_KW
  100. { `String "bool" }
  101. | INT_KW
  102. { `String "int" }
  103. ;
  104.  
  105. /* Type specification field definitions. */
  106. type_spec_field_defs:
  107. /* This list must be non-empty. So, no epsilon rule. */
  108. | type_spec_field_def type_spec_field_defs_
  109. { $1 :: $2 }
  110. ;
  111.  
  112. type_spec_field_defs_:
  113. | COMMA type_spec_field_def type_spec_field_defs_
  114. { $2 :: $3 }
  115. | /* Nothing */
  116. { [] } /* Get that accumulator fired up. */
  117. ;
  118.  
  119. type_spec_field_def:
  120. | id COLON type_spec
  121. { ($1, $3) }
  122. ;
  123.  
  124. ref:
  125. | id ref_
  126. { $1 :: $2 } /* Add 'root' of the ref to the head of the list. */
  127. ;
  128.  
  129. ref_:
  130. | FIELD ref_
  131. { $1 :: $2 } /* Add fld to the head of the list. */
  132. | /* Nothing */
  133. { [] } /* Start an empty list. */
  134. ;
  135.  
  136. id:
  137. | IDENTIFIER
  138. { `String $1 }
  139. ;
  140.  
  141. proc_def:
  142. /* TODO Worth discussing if proc_vars should be separate from proc_body.
  143. * I've gone with yes here because I think that's probably going to
  144. * be handy later on, and the spec mandates that they exist before
  145. * the procedure body.
  146. */
  147. | PROC proc_head proc_var_decs proc_body END
  148. { ($2, $3, $4) }
  149. ;
  150.  
  151. proc_head:
  152. | id L_PAREN proc_params R_PAREN
  153. { ($1, $3) }
  154. ;
  155.  
  156. proc_params:
  157. | formal_param formal_params_
  158. { $1 :: $2 }
  159. | /* Nothing */
  160. { [] }
  161. ;
  162.  
  163. formal_params_:
  164. /* Exists to neatly handle the case of a single parameter, which shouldn't
  165. * have a comma after it.
  166. */
  167. | COMMA formal_param formal_params_
  168. { $2 :: $3 }
  169. | /* Nothing */
  170. { [] }
  171. ;
  172.  
  173. formal_param:
  174. | passing_indicator type_spec ref
  175. /* NOTE I've chosen to put ref here instead of id, as I'm pretty sure that
  176. * a _reference_ is intended, to allow people to write (for example)
  177. * foo(z.f1) , which wouldn't be possible if args were only
  178. * identifiers.
  179. */
  180. { ($1, $2, $3) } /* Form a tuple of the subcomponents. */
  181. ;
  182.  
  183. passing_indicator:
  184. | VAL
  185. { `String "val" }
  186. | REF
  187. { `String "ref" }
  188. ;
  189.  
  190. proc_var_decs:
  191. | var_decl proc_var_decs
  192. { $1 :: $2 }
  193. | /* Nothing */
  194. { [] }
  195. ;
  196.  
  197. var_decl:
  198. | type_spec id SEMICOLON
  199. { ($1, $2) }
  200. ;
  201.  
  202. proc_body:
  203. |
  204. { [] }
  205. ;
  206.  
  207. stmt:
  208. | atomic_stmt
  209. { $1 }
  210. | comp_stmt
  211. { $1 }
  212. ;
  213.  
  214. stmt_list:
  215. | stmt stmt_list
  216. { $1 :: $2 }
  217. | /* Nothing */
  218. { [] }
  219. ;
  220.  
  221. atomic_stmt:
  222. | ref ASSIGN assign_rvalue SEMICOLON
  223. { (`String "assign", $1, $3) }
  224. | READ ref SEMICOLON
  225. { (`String "read", $2, Null) }
  226. | WRITE expr SEMICOLON
  227. { (`String "write", $2, Null) }
  228. | id L_PAREN expr_list R_PAREN SEMICOLON
  229. { (`String "proc", $1, $3) }
  230. ;
  231.  
  232. /* rvalue start */
  233. assign_rvalue:
  234. | expr
  235. { (`String "expr", $1) }
  236. | L_BRACE a_rvalue_struct R_BRACE
  237. { (`String "struct", $2) }
  238. ;
  239.  
  240. a_rvalue_struct:
  241. | rvalue_field_init a_rvalue_struct_
  242. { $1 :: $2 }
  243. | /* Nothing. */
  244. { [] }
  245. ;
  246.  
  247. a_rvalue_struct_:
  248. | COMMA rvalue_field_init a_rvalue_struct_
  249. { $2 :: $3 }
  250. | /* Nothing. */
  251. { [] }
  252. ;
  253.  
  254. rvalue_field_init:
  255. | id EQUALITY assign_rvalue
  256. { ($1, $3) }
  257. ;
  258. /* rvalue end */
  259.  
  260. comp_stmt:
  261. /* Seems the sanest way to do things is to handle
  262. * both the has-else and no-else cases in the same
  263. * thing.
  264. */
  265. | IF expr THEN stmt_list else_block FI
  266. { (`String "comp_if", $2, $4, $4) }
  267. | WHILE expr DO stmt_list OD
  268. { (`String "comp_while", $2, $4, Null) }
  269. ;
  270.  
  271. else_block:
  272. | ELSE stmt_list
  273. { $2 }
  274. | /* Nothing. */
  275. { [] }
  276.  
  277. expr_list:
  278. | expr expr_list_
  279. { $1 :: $2 }
  280. | /* Nothing */
  281. { [] }
  282. ;
  283.  
  284. expr_list_:
  285. | COMMA expr expr_list_
  286. { $2 :: $3 }
  287. | /* Nothing */
  288. { [] }
  289. ;
  290.  
  291. expr:
  292. | expr_ref
  293. { $1 }
  294. | const
  295. { $1 }
  296. | L_PAREN expr R_PAREN
  297. { $2 }
  298. | expr binop expr
  299. { ($2, $1, $3) }
  300. | unop expr
  301. { ($2, $1, Null) }
  302. ;
  303.  
  304. expr_ref:
  305. | ref
  306. { (`String "ref", $1) }
  307. ;
  308.  
  309. const:
  310. | INT_LIT
  311. { (`String "int_lit", $1) }
  312. | STR_LIT
  313. { (`String "str_lit", $1) }
  314. | TRUE
  315. { (`String "bool_lit", `String "true") }
  316. | FALSE
  317. { (`String "bool_lit", `String "false") }
  318. ;
  319.  
  320. binop:
  321. | BINARY_MINUS
  322. { `String "binop_minus" }
  323. | BINARY_PLUS
  324. { `String "binop_plus" }
  325. | BINARY_MULTIPLICATION
  326. { `String "binop_multi" }
  327. | BINARY_DIVISION
  328. { `String "binop_division" }
  329. | INEQUALITY
  330. { `String "binop_ineq" }
  331. | LESSER_EQUALITY
  332. { `String "binop_leq" }
  333. | GREATER_EQUALITY
  334. { `String "binop_geq" }
  335. | LESSER_THAN
  336. { `String "binop_lesser" }
  337. | GREATER_THAN
  338. { `String "binop_greater" }
  339. | EQUALITY
  340. { `String "binop_equality" }
  341. | AND
  342. { `String "binop_and" }
  343. | OR
  344. { `String "binop_or" }
  345. ;
  346.  
  347. unop:
  348. /* NOTE: Unary minus is handled (currently) in the int_lit lexing.
  349. */
  350. | NOT
  351. { `String "unop_not" }
  352. ;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement