1# jay skeleton 2 3# character in column 1 determines outcome... 4# # is a comment 5# . is copied 6# t is copied as //t if -t is set 7# other lines are interpreted to call jay procedures 8 9.// created by jay 0.7 (c) 1998 Axel.Schreiner@informatik.uni-osnabrueck.de 10. 11 prolog ## %{ ... %} prior to the first %% 12 13.// %token constants 14. 15 tokens public static final int 16. 17. /** thrown for irrecoverable syntax errors and stack overflow. 18. */ 19. public static class yyException extends java.lang.Exception { 20. public yyException (String message) { 21. super(message); 22. } 23. } 24. 25. /** must be implemented by a scanner object to supply input to the parser. 26. */ 27. public interface yyInput { 28. /** move on to next token. 29. @return false if positioned beyond tokens. 30. @throws IOException on input error. 31. */ 32. boolean advance () throws java.io.IOException; 33. /** classifies current token. 34. Should not be called if advance() returned false. 35. @return current %token or single character. 36. */ 37. int token (); 38. /** associated with current token. 39. Should not be called if advance() returned false. 40. @return value for token(). 41. */ 42. Object value (); 43. } 44. 45. /** simplified error message. 46. @see <a href="#yyerror(java.lang.String, java.lang.String[])">yyerror</a> 47. */ 48. public void yyerror (String message) { 49. yyerror(message, null); 50. } 51. 52. /** (syntax) error message. 53. Can be overwritten to control message format. 54. @param message text to be displayed. 55. @param expected vector of acceptable tokens, if available. 56. */ 57. public void yyerror (String message, String[] expected) { 58. if (expected != null && expected.length > 0) { 59. System.err.print(message+", expecting"); 60. for (int n = 0; n < expected.length; ++ n) 61. System.err.print(" "+expected[n]); 62. System.err.println(); 63. } else 64. System.err.println(message); 65. } 66. 67. /** debugging support, requires the package jay.yydebug. 68. Set to null to suppress debugging messages. 69. */ 70t protected jay.yydebug.yyDebug yydebug; 71. 72 debug ## tables for debugging support 73. 74. /** index-checked interface to yyNames[]. 75. @param token single character or %token value. 76. @return token name or [illegal] or [unknown]. 77. */ 78t public static final String yyname (int token) { 79t if (token < 0 || token > yyNames.length) return "[illegal]"; 80t String name; 81t if ((name = yyNames[token]) != null) return name; 82t return "[unknown]"; 83t } 84. 85. /** computes list of expected tokens on error by tracing the tables. 86. @param state for which to compute the list. 87. @return list of token names. 88. */ 89. protected String[] yyExpecting (int state) { 90. int token, n, len = 0; 91. boolean[] ok = new boolean[yyNames.length]; 92. 93. if ((n = yySindex[state]) != 0) 94. for (token = n < 0 ? -n : 0; 95. token < yyNames.length && n+token < yyTable.length; ++ token) 96. if (yyCheck[n+token] == token && !ok[token] && yyNames[token] != null) { 97. ++ len; 98. ok[token] = true; 99. } 100. if ((n = yyRindex[state]) != 0) 101. for (token = n < 0 ? -n : 0; 102. token < yyNames.length && n+token < yyTable.length; ++ token) 103. if (yyCheck[n+token] == token && !ok[token] && yyNames[token] != null) { 104. ++ len; 105. ok[token] = true; 106. } 107. 108. String result[] = new String[len]; 109. for (n = token = 0; n < len; ++ token) 110. if (ok[token]) result[n++] = yyNames[token]; 111. return result; 112. } 113. 114. /** the generated parser, with debugging messages. 115. Maintains a state and a value stack, currently with fixed maximum size. 116. @param yyLex scanner. 117. @param yydebug debug message writer implementing yyDebug, or null. 118. @return result of the last reduction, if any. 119. @throws yyException on irrecoverable parse error. 120. */ 121. public Object yyparse (yyInput yyLex, Object yydebug) 122. throws java.io.IOException, yyException { 123t this.yydebug = (jay.yydebug.yyDebug)yydebug; 124. return yyparse(yyLex); 125. } 126. 127. /** initial size and increment of the state/value stack [default 256]. 128. This is not final so that it can be overwritten outside of invocations 129. of yyparse(). 130. */ 131. protected int yyMax; 132. 133. /** executed at the beginning of a reduce action. 134. Used as $$ = yyDefault($1), prior to the user-specified action, if any. 135. Can be overwritten to provide deep copy, etc. 136. @param first value for $1, or null. 137. @return first. 138. */ 139. protected Object yyDefault (Object first) { 140. return first; 141. } 142. 143. /** the generated parser. 144. Maintains a state and a value stack, currently with fixed maximum size. 145. @param yyLex scanner. 146. @return result of the last reduction, if any. 147. @throws yyException on irrecoverable parse error. 148. */ 149. public Object yyparse (yyInput yyLex) 150. throws java.io.IOException, yyException { 151. if (yyMax <= 0) yyMax = 256; // initial size 152. int yyState = 0, yyStates[] = new int[yyMax]; // state stack 153. Object yyVal = null, yyVals[] = new Object[yyMax]; // value stack 154. int yyToken = -1; // current input 155. int yyErrorFlag = 0; // #tks to shift 156. 157 local ## %{ ... %} after the first %% 158 159. yyLoop: for (int yyTop = 0;; ++ yyTop) { 160. if (yyTop >= yyStates.length) { // dynamically increase 161. int[] i = new int[yyStates.length+yyMax]; 162. System.arraycopy(yyStates, 0, i, 0, yyStates.length); 163. yyStates = i; 164. Object[] o = new Object[yyVals.length+yyMax]; 165. System.arraycopy(yyVals, 0, o, 0, yyVals.length); 166. yyVals = o; 167. } 168. yyStates[yyTop] = yyState; 169. yyVals[yyTop] = yyVal; 170t if (yydebug != null) yydebug.push(yyState, yyVal); 171. 172. yyDiscarded: for (;;) { // discarding a token does not change stack 173. int yyN; 174. if ((yyN = yyDefRed[yyState]) == 0) { // else [default] reduce (yyN) 175. if (yyToken < 0) { 176. yyToken = yyLex.advance() ? yyLex.token() : 0; 177t if (yydebug != null) 178t yydebug.lex(yyState, yyToken, yyname(yyToken), yyLex.value()); 179. } 180. if ((yyN = yySindex[yyState]) != 0 && (yyN += yyToken) >= 0 181. && yyN < yyTable.length && yyCheck[yyN] == yyToken) { 182t if (yydebug != null) 183t yydebug.shift(yyState, yyTable[yyN], yyErrorFlag-1); 184. yyState = yyTable[yyN]; // shift to yyN 185. yyVal = yyLex.value(); 186. yyToken = -1; 187. if (yyErrorFlag > 0) -- yyErrorFlag; 188. continue yyLoop; 189. } 190. if ((yyN = yyRindex[yyState]) != 0 && (yyN += yyToken) >= 0 191. && yyN < yyTable.length && yyCheck[yyN] == yyToken) 192. yyN = yyTable[yyN]; // reduce (yyN) 193. else 194. switch (yyErrorFlag) { 195. 196. case 0: 197. yyerror("syntax error", yyExpecting(yyState)); 198t if (yydebug != null) yydebug.error("syntax error"); 199. 200. case 1: case 2: 201. yyErrorFlag = 3; 202. do { 203. if ((yyN = yySindex[yyStates[yyTop]]) != 0 204. && (yyN += yyErrorCode) >= 0 && yyN < yyTable.length 205. && yyCheck[yyN] == yyErrorCode) { 206t if (yydebug != null) 207t yydebug.shift(yyStates[yyTop], yyTable[yyN], 3); 208. yyState = yyTable[yyN]; 209. yyVal = yyLex.value(); 210. continue yyLoop; 211. } 212t if (yydebug != null) yydebug.pop(yyStates[yyTop]); 213. } while (-- yyTop >= 0); 214t if (yydebug != null) yydebug.reject(); 215. throw new yyException("irrecoverable syntax error"); 216. 217. case 3: 218. if (yyToken == 0) { 219t if (yydebug != null) yydebug.reject(); 220. throw new yyException("irrecoverable syntax error at end-of-file"); 221. } 222t if (yydebug != null) 223t yydebug.discard(yyState, yyToken, yyname(yyToken), 224t yyLex.value()); 225. yyToken = -1; 226. continue yyDiscarded; // leave stack alone 227. } 228. } 229. int yyV = yyTop + 1-yyLen[yyN]; 230t if (yydebug != null) 231t yydebug.reduce(yyState, yyStates[yyV-1], yyN, YYRules.getRule[yyN], yyLen[yyN]); 232. yyVal = yyDefault(yyV > yyTop ? null : yyVals[yyV]); 233. switch (yyN) { 234 235 actions ## code from the actions within the grammar 236 237. } 238. yyTop -= yyLen[yyN]; 239. yyState = yyStates[yyTop]; 240. int yyM = yyLhs[yyN]; 241. if (yyState == 0 && yyM == 0) { 242t if (yydebug != null) yydebug.shift(0, yyFinal); 243. yyState = yyFinal; 244. if (yyToken < 0) { 245. yyToken = yyLex.advance() ? yyLex.token() : 0; 246t if (yydebug != null) 247t yydebug.lex(yyState, yyToken,yyname(yyToken), yyLex.value()); 248. } 249. if (yyToken == 0) { 250t if (yydebug != null) yydebug.accept(yyVal); 251. return yyVal; 252. } 253. continue yyLoop; 254. } 255. if ((yyN = yyGindex[yyM]) != 0 && (yyN += yyState) >= 0 256. && yyN < yyTable.length && yyCheck[yyN] == yyState) 257. yyState = yyTable[yyN]; 258. else 259. yyState = yyDgoto[yyM]; 260t if (yydebug != null) yydebug.shift(yyStates[yyTop], yyState); 261. continue yyLoop; 262. } 263. } 264. } 265. 266 tables ## tables for rules, default reduction, and action calls 267. 268 epilog ## text following second %% 269