/tryocaml/js_of_ocaml-patched/runtime/parsing.js

http://github.com/cago/tryocaml · JavaScript · 236 lines · 182 code · 16 blank · 38 comment · 38 complexity · 219f3883d33489065c5935fee9ab14eb MD5 · raw file

  1. /***********************************************************************/
  2. /* */
  3. /* Objective Caml */
  4. /* */
  5. /* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
  6. /* */
  7. /* Copyright 1996 Institut National de Recherche en Informatique et */
  8. /* en Automatique. All rights reserved. This file is distributed */
  9. /* under the terms of the GNU Library General Public License, with */
  10. /* the special exception on linking described in file ../LICENSE. */
  11. /* */
  12. /***********************************************************************/
  13. /* $Id: parsing.c 8983 2008-08-06 09:38:25Z xleroy $ */
  14. /* The PDA automaton for parsers generated by camlyacc */
  15. /* The pushdown automata */
  16. //Provides: caml_parse_engine
  17. //Requires: caml_lex_array
  18. function caml_parse_engine(tables, env, cmd, arg)
  19. {
  20. var ERRCODE = 256;
  21. var START = 0;
  22. var TOKEN_READ = 1;
  23. var STACKS_GROWN_1 = 2;
  24. var STACKS_GROWN_2 = 3;
  25. var SEMANTIC_ACTION_COMPUTED = 4;
  26. var ERROR_DETECTED = 5;
  27. var loop = 6;
  28. var testshift = 7;
  29. var shift = 8;
  30. var shift_recover = 9;
  31. var reduce = 10;
  32. var READ_TOKEN = 0;
  33. var RAISE_PARSE_ERROR = 1;
  34. var GROW_STACKS_1 = 2;
  35. var GROW_STACKS_2 = 3;
  36. var COMPUTE_SEMANTIC_ACTION = 4;
  37. var CALL_ERROR_FUNCTION = 5;
  38. var env_s_stack = 1;
  39. var env_v_stack = 2;
  40. var env_symb_start_stack = 3;
  41. var env_symb_end_stack = 4;
  42. var env_stacksize = 5;
  43. var env_stackbase = 6;
  44. var env_curr_char = 7;
  45. var env_lval = 8;
  46. var env_symb_start = 9;
  47. var env_symb_end = 10;
  48. var env_asp = 11;
  49. var env_rule_len = 12;
  50. var env_rule_number = 13;
  51. var env_sp = 14;
  52. var env_state = 15;
  53. var env_errflag = 16;
  54. var tbl_actions = 1;
  55. var tbl_transl_const = 2;
  56. var tbl_transl_block = 3;
  57. var tbl_lhs = 4;
  58. var tbl_len = 5;
  59. var tbl_defred = 6;
  60. var tbl_dgoto = 7;
  61. var tbl_sindex = 8;
  62. var tbl_rindex = 9;
  63. var tbl_gindex = 10;
  64. var tbl_tablesize = 11;
  65. var tbl_table = 12;
  66. var tbl_check = 13;
  67. var tbl_error_function = 14;
  68. var tbl_names_const = 15;
  69. var tbl_names_block = 16;
  70. if (!tables.dgoto) {
  71. tables.defred = caml_lex_array (tables[tbl_defred]);
  72. tables.sindex = caml_lex_array (tables[tbl_sindex]);
  73. tables.check = caml_lex_array (tables[tbl_check]);
  74. tables.rindex = caml_lex_array (tables[tbl_rindex]);
  75. tables.table = caml_lex_array (tables[tbl_table]);
  76. tables.len = caml_lex_array (tables[tbl_len]);
  77. tables.lhs = caml_lex_array (tables[tbl_lhs]);
  78. tables.gindex = caml_lex_array (tables[tbl_gindex]);
  79. tables.dgoto = caml_lex_array (tables[tbl_dgoto]);
  80. }
  81. var res = 0, n, n1, n2, state1;
  82. // RESTORE
  83. var sp = env[env_sp];
  84. var state = env[env_state];
  85. var errflag = env[env_errflag];
  86. exit:for (;;) {
  87. switch(cmd) {
  88. case START:
  89. state = 0;
  90. errflag = 0;
  91. // Fall through
  92. case loop:
  93. n = tables.defred[state];
  94. if (n != 0) { cmd = reduce; break; }
  95. if (env[env_curr_char] >= 0) { cmd = testshift; break; }
  96. res = READ_TOKEN;
  97. break exit;
  98. /* The ML code calls the lexer and updates */
  99. /* symb_start and symb_end */
  100. case TOKEN_READ:
  101. if (arg instanceof Array) {
  102. env[env_curr_char] = tables[tbl_transl_block][arg[0] + 1];
  103. env[env_lval] = arg[1];
  104. } else {
  105. env[env_curr_char] = tables[tbl_transl_const][arg + 1];
  106. env[env_lval] = 0;
  107. }
  108. // Fall through
  109. case testshift:
  110. n1 = tables.sindex[state];
  111. n2 = n1 + env[env_curr_char];
  112. if (n1 != 0 && n2 >= 0 && n2 <= tables[tbl_tablesize] &&
  113. tables.check[n2] == env[env_curr_char]) {
  114. cmd = shift; break;
  115. }
  116. n1 = tables.rindex[state];
  117. n2 = n1 + env[env_curr_char];
  118. if (n1 != 0 && n2 >= 0 && n2 <= tables[tbl_tablesize] &&
  119. tables.check[n2] == env[env_curr_char]) {
  120. n = tables.table[n2];
  121. cmd = reduce; break;
  122. }
  123. if (errflag <= 0) {
  124. res = CALL_ERROR_FUNCTION;
  125. break exit;
  126. }
  127. // Fall through
  128. /* The ML code calls the error function */
  129. case ERROR_DETECTED:
  130. if (errflag < 3) {
  131. errflag = 3;
  132. for (;;) {
  133. state1 = env[env_s_stack][sp + 1];
  134. n1 = tables.sindex[state1];
  135. n2 = n1 + ERRCODE;
  136. if (n1 != 0 && n2 >= 0 && n2 <= tables[tbl_tablesize] &&
  137. tables.check[n2] == ERRCODE) {
  138. cmd = shift_recover; break;
  139. } else {
  140. if (sp <= env[env_stackbase]) return RAISE_PARSE_ERROR;
  141. /* The ML code raises Parse_error */
  142. sp--;
  143. }
  144. }
  145. } else {
  146. if (env[env_curr_char] == 0) return RAISE_PARSE_ERROR;
  147. /* The ML code raises Parse_error */
  148. env[env_curr_char] = -1;
  149. cmd = loop; break;
  150. }
  151. // Fall through
  152. case shift:
  153. env[env_curr_char] = -1;
  154. if (errflag > 0) errflag--;
  155. // Fall through
  156. case shift_recover:
  157. state = tables.table[n2];
  158. sp++;
  159. if (sp >= env[env_stacksize]) {
  160. res = GROW_STACKS_1;
  161. break exit;
  162. }
  163. // Fall through
  164. /* The ML code resizes the stacks */
  165. case STACKS_GROWN_1:
  166. env[env_s_stack][sp + 1] = state;
  167. env[env_v_stack][sp + 1] = env[env_lval];
  168. env[env_symb_start_stack][sp + 1] = env[env_symb_start];
  169. env[env_symb_end_stack][sp + 1] = env[env_symb_end];
  170. cmd = loop;
  171. break;
  172. case reduce:
  173. var m = tables.len[n];
  174. env[env_asp] = sp;
  175. env[env_rule_number] = n;
  176. env[env_rule_len] = m;
  177. sp = sp - m + 1;
  178. m = tables.lhs[n];
  179. state1 = env[env_s_stack][sp];
  180. n1 = tables.gindex[m];
  181. n2 = n1 + state1;
  182. if (n1 != 0 && n2 >= 0 && n2 <= tables[tbl_tablesize] &&
  183. tables.check[n2] == state1)
  184. state = tables.table[n2];
  185. else
  186. state = tables.dgoto[m];
  187. if (sp >= env[env_stacksize]) {
  188. res = GROW_STACKS_2;
  189. break exit;
  190. }
  191. // Fall through
  192. /* The ML code resizes the stacks */
  193. case STACKS_GROWN_2:
  194. res = COMPUTE_SEMANTIC_ACTION;
  195. break exit;
  196. /* The ML code calls the semantic action */
  197. case SEMANTIC_ACTION_COMPUTED:
  198. env[env_s_stack][sp + 1] = state;
  199. env[env_v_stack][sp + 1] = arg;
  200. var asp = env[env_asp];
  201. env[env_symb_end_stack][sp + 1] = env[env_symb_end_stack][asp + 1];
  202. if (sp > asp) {
  203. /* This is an epsilon production. Take symb_start equal to symb_end. */
  204. env[env_symb_start_stack][sp + 1] = env[env_symb_end_stack][asp + 1];
  205. }
  206. cmd = loop; break;
  207. /* Should not happen */
  208. default:
  209. return RAISE_PARSE_ERROR;
  210. }
  211. }
  212. // SAVE
  213. env[env_sp] = sp;
  214. env[env_state] = state;
  215. env[env_errflag] = errflag;
  216. return res;
  217. }
  218. //Provides: caml_set_parser_trace const
  219. //Dummy function!
  220. function caml_set_parser_trace() { return 0; }