001: //### This file created by BYACC 1.8(/Java extension 1.1)
002: //### Java capabilities added 7 Jan 97, Bob Jamison
003: //### Updated : 27 Nov 97 -- Bob Jamison, Joe Nieten
004: //### 01 Jan 98 -- Bob Jamison -- fixed generic semantic constructor
005: //### 01 Jun 99 -- Bob Jamison -- added Runnable support
006: //### 06 Aug 00 -- Bob Jamison -- made state variables class-global
007: //### 03 Jan 01 -- Bob Jamison -- improved flags, tracing
008: //### 16 May 01 -- Bob Jamison -- added custom stack sizing
009: //### Please send bug reports to rjamison@lincom-asg.com
010: //### static char yysccsid[] = "@(#)yaccpar 1.8 (Berkeley) 01/20/90";
011:
012: package hotsax.html.sax;
013:
014: //#line 3 "HtmlParser.y"
015:
016: /* package name generated by BYACC/J command line: -J*/
017:
018: import java.io.*;
019:
020: //#line 20 "HtmlParser.java"
021:
022: /**
023: * Encapsulates yacc() parser functionality in a Java
024: * class for quick code development
025: */
026: public class HtmlParser {
027:
028: boolean yydebug; //do I want debug output?
029: int yynerrs; //number of errors so far
030: int yyerrflag; //was there an error?
031: int yychar; //the current working character
032:
033: //########## MESSAGES ##########
034: //###############################################################
035: // method: debug
036: //###############################################################
037: void debug(String msg) {
038: if (yydebug)
039: System.out.println(msg);
040: }
041:
042: //########## STATE STACK ##########
043: final static int YYSTACKSIZE = 500; //maximum stack sizeint statestk[],stateptr; //state stack
044: int stateptrmax; //highest index of stackptr
045: int statemax; //state when highest index reached
046: //###############################################################
047: // methods: state stack push,pop,drop,peek
048: //###############################################################
049:
050: void state_push(int state) {
051: if (stateptr >= YYSTACKSIZE) //overflowed?
052: return;
053: statestk[++stateptr] = state;
054: if (stateptr > statemax) {
055: statemax = state;
056: stateptrmax = stateptr;
057: }
058: }
059:
060: int state_pop() {
061: if (stateptr < 0) //underflowed?
062: return -1;
063: return statestk[stateptr--];
064: }
065:
066: void state_drop(int cnt) {
067: int ptr;
068: ptr = stateptr - cnt;
069: if (ptr < 0)
070: return;
071: stateptr = ptr;
072: }
073:
074: int state_peek(int relative) {
075: int ptr;
076: ptr = stateptr - relative;
077: if (ptr < 0)
078: return -1;
079: return statestk[ptr];
080: }
081:
082: //###############################################################
083: // method: init_stacks : allocate and prepare stacks
084: //###############################################################
085: boolean init_stacks() {
086: statestk = new int[YYSTACKSIZE];
087: stateptr = -1;
088: statemax = -1;
089: stateptrmax = -1;
090: val_init();
091: return true;
092: }
093:
094: //###############################################################
095: // method: dump_stacks : show n levels of the stacks
096: //###############################################################
097: void dump_stacks(int count) {
098: int i;
099: System.out.println("=index==state====value= s:" + stateptr
100: + " v:" + valptr);
101: for (i = 0; i < count; i++)
102: System.out.println(" " + i + " " + statestk[i]
103: + " " + valstk[i]);
104: System.out.println("======================");
105: }
106:
107: //########## SEMANTIC VALUES ##########
108: //public class HtmlParserVal is defined in HtmlParserVal.java
109:
110: String yytext;//user variable to return contextual strings
111: HtmlParserVal yyval; //used to return semantic vals from action routines
112: HtmlParserVal yylval;//the 'lval' (result) I got from yylex()
113: HtmlParserVal valstk[];
114: int valptr;
115:
116: //###############################################################
117: // methods: value stack push,pop,drop,peek.
118: //###############################################################
119: void val_init() {
120: valstk = new HtmlParserVal[YYSTACKSIZE];
121: yyval = new HtmlParserVal(0);
122: yylval = new HtmlParserVal(0);
123: valptr = -1;
124: }
125:
126: void val_push(HtmlParserVal val) {
127: if (valptr >= YYSTACKSIZE)
128: return;
129: valstk[++valptr] = val;
130: }
131:
132: HtmlParserVal val_pop() {
133: if (valptr < 0)
134: return new HtmlParserVal(-1);
135: return valstk[valptr--];
136: }
137:
138: void val_drop(int cnt) {
139: int ptr;
140: ptr = valptr - cnt;
141: if (ptr < 0)
142: return;
143: valptr = ptr;
144: }
145:
146: HtmlParserVal val_peek(int relative) {
147: int ptr;
148: ptr = valptr - relative;
149: if (ptr < 0)
150: return new HtmlParserVal(-1);
151: return valstk[ptr];
152: }
153:
154: //#### end semantic value section ####
155: public final static short UNDEFINED = 257;
156: public final static short SOF = 258;
157: public final static short TAG_START = 259;
158: public final static short TAG_END = 260;
159: public final static short TAG_EMPTY = 261;
160: public final static short ATTR = 262;
161: public final static short VAL = 263;
162: public final static short TEXT = 264;
163: public final static short COMMENT = 265;
164: public final static short PI = 266;
165: public final static short DOCTYPE = 267;
166: public final static short CDATA = 268;
167: public final static short TAG_START_COMPLETE = 269;
168: public final static short EOF = 270;
169: public final static short YYERRCODE = 256;
170: final static short yylhs[] = { -1, 0, 1, 0, 3, 0, 2, 2, 4, 5, 5, 5,
171: 5, 5, 5, 5, 5, 5, 5, 5, };
172: final static short yylen[] = { 2, 0, 0, 3, 0, 4, 1, 2, 1, 1, 1, 1,
173: 1, 1, 1, 1, 1, 1, 1, 1, };
174: final static short yydefred[] = { 0, 0, 0, 0, 0, 3, 9, 11, 14, 12,
175: 13, 18, 19, 16, 15, 17, 10, 0, 6, 8, 5, 7, };
176: final static short yydgoto[] = { 2, 3, 17, 4, 18, 19, };
177: final static short yysindex[] = { -223, 0, 0, -234, -235, 0, 0, 0,
178: 0, 0, 0, 0, 0, 0, 0, 0, 0, -259, 0, 0, 0, 0, };
179: final static short yyrindex[] = { 37, -247, 0, 0, 0, 0, 0, 0, 0, 0,
180: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
181: final static short yygindex[] = { 0, 0, 0, 0, 21, 0, };
182: final static int YYTABLESIZE = 38;
183: final static short yytable[] = { 6, 7, 8, 9, 10, 11, 12, 13, 14,
184: 15, 16, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 6, 7, 8, 9,
185: 10, 11, 12, 13, 14, 15, 16, 1, 5, 1, 21, };
186: final static short yycheck[] = { 259, 260, 261, 262, 263, 264, 265,
187: 266, 267, 268, 269, 270, 259, 260, 261, 262, 263, 264, 265,
188: 266, 267, 268, 269, 270, 259, 260, 261, 262, 263, 264, 265,
189: 266, 267, 268, 269, 258, 270, 0, 17, };
190: final static short YYFINAL = 2;
191: final static short YYMAXTOKEN = 270;
192: final static String yyname[] = { "end-of-file", null, null, null,
193: null, null, null, null, null, null, null, null, null, null,
194: null, null, null, null, null, null, null, null, null, null,
195: null, null, null, null, null, null, null, null, null, null,
196: null, null, null, null, null, null, null, null, null, null,
197: null, null, null, null, null, null, null, null, null, null,
198: null, null, null, null, null, null, null, null, null, null,
199: null, null, null, null, null, null, null, null, null, null,
200: null, null, null, null, null, null, null, null, null, null,
201: null, null, null, null, null, null, null, null, null, null,
202: null, null, null, null, null, null, null, null, null, null,
203: null, null, null, null, null, null, null, null, null, null,
204: null, null, null, null, null, null, null, null, null, null,
205: null, null, null, null, null, null, null, null, null, null,
206: null, null, null, null, null, null, null, null, null, null,
207: null, null, null, null, null, null, null, null, null, null,
208: null, null, null, null, null, null, null, null, null, null,
209: null, null, null, null, null, null, null, null, null, null,
210: null, null, null, null, null, null, null, null, null, null,
211: null, null, null, null, null, null, null, null, null, null,
212: null, null, null, null, null, null, null, null, null, null,
213: null, null, null, null, null, null, null, null, null, null,
214: null, null, null, null, null, null, null, null, null, null,
215: null, null, null, null, null, null, null, null, null, null,
216: null, null, null, null, null, null, null, null, null, null,
217: null, null, null, null, null, null, null, null, null, null,
218: null, null, null, "UNDEFINED", "SOF", "TAG_START",
219: "TAG_END", "TAG_EMPTY", "ATTR", "VAL", "TEXT", "COMMENT",
220: "PI", "DOCTYPE", "CDATA", "TAG_START_COMPLETE", "EOF", };
221: final static String yyrule[] = { "$accept : document",
222: "document :", "$$1 :", "document : SOF $$1 EOF", "$$2 :",
223: "document : SOF $$2 docstuff EOF", "docstuff : start",
224: "docstuff : docstuff start", "start : elements",
225: "elements : TAG_START", "elements : TAG_START_COMPLETE",
226: "elements : TAG_END", "elements : ATTR", "elements : VAL",
227: "elements : TAG_EMPTY", "elements : DOCTYPE",
228: "elements : PI", "elements : CDATA", "elements : TEXT",
229: "elements : COMMENT", };
230:
231: //#line 49 "HtmlParser.y"
232:
233: private HtmlLexer lexer;
234:
235: private int stateptr; // possible bug in parser generator
236: private int statestk[];
237:
238: /* Helpers */
239:
240: private ParserDelegate delegate;
241:
242: public ParserDelegate getDelegate() {
243: return delegate;
244: }
245:
246: private HtmlParserVal tagName;
247:
248: private int yylex() {
249: int yyl_token = -1;
250: try {
251: yyl_token = lexer._yylex();
252:
253: if (yydebug)
254: System.out.println("token: " + yyl_token + " "
255: + yyname[yyl_token] + " " + yylval.toString());
256: } catch (IOException e) {
257: System.err.println("IO error :" + e);
258: }
259: return yyl_token;
260: }
261:
262: public void yyerror(String error) {
263: System.err.println("Error: " + error);
264: }
265:
266: public HtmlParser(Reader r) {
267: lexer = new HtmlLexer(r, this );
268: delegate = new ParserDelegate(this );
269: }
270:
271: // testing -----------
272: static boolean interactive;
273:
274: public static void main(String args[]) throws IOException {
275: System.out.println("BYACC/Java with JFlex HtmlParser");
276:
277: HtmlParser yyparser;
278: if (args.length > 0) {
279: // parse a file
280: yyparser = new HtmlParser(new FileReader(args[0]));
281: if (args.length > 1)
282: yyparser.yydebug = true;
283: } else {
284: // interactive mode
285: System.out.println("[Quit with CTRL-D]");
286: System.out.print("Expression: ");
287: interactive = true;
288: yyparser = new HtmlParser(new InputStreamReader(System.in));
289: }
290:
291: yyparser.yyparse();
292:
293: if (interactive) {
294: System.out.println();
295: System.out.println("Have a nice day");
296: }
297: }
298:
299: //#line 284 "HtmlParser.java"
300: //###############################################################
301: // method: yylexdebug : check lexer state
302: //###############################################################
303: void yylexdebug(int state, int ch) {
304: String s = null;
305: if (ch < 0)
306: ch = 0;
307: if (ch <= YYMAXTOKEN) //check index bounds
308: s = yyname[ch]; //now get it
309: if (s == null)
310: s = "illegal-symbol";
311: debug("state " + state + ", reading " + ch + " (" + s + ")");
312: }
313:
314: //The following are now global, to aid in error reporting
315: int yyn; //next next thing to do
316: int yym; //
317: int yystate; //current parsing state from state table
318: String yys; //current token string
319:
320: //###############################################################
321: // method: yyparse : parse input and execute indicated items
322: //###############################################################
323: int yyparse() {
324: boolean doaction;
325: init_stacks();
326: yynerrs = 0;
327: yyerrflag = 0;
328: yychar = -1; //impossible char forces a read
329: yystate = 0; //initial state
330: state_push(yystate); //save it
331: while (true) //until parsing is done, either correctly, or w/error
332: {
333: doaction = true;
334: if (yydebug)
335: debug("loop");
336: //#### NEXT ACTION (from reduction table)
337: for (yyn = yydefred[yystate]; yyn == 0; yyn = yydefred[yystate]) {
338: if (yydebug)
339: debug("yyn:" + yyn + " state:" + yystate
340: + " yychar:" + yychar);
341: if (yychar < 0) //we want a char?
342: {
343: yychar = yylex(); //get next token
344: if (yydebug)
345: debug(" next yychar:" + yychar);
346: //#### ERROR CHECK ####
347: if (yychar < 0) //it it didn't work/error
348: {
349: yychar = 0; //change it to default string (no -1!)
350: if (yydebug)
351: yylexdebug(yystate, yychar);
352: }
353: }//yychar<0
354: yyn = yysindex[yystate]; //get amount to shift by (shift index)
355: if ((yyn != 0) && (yyn += yychar) >= 0
356: && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) {
357: if (yydebug)
358: debug("state " + yystate
359: + ", shifting to state " + yytable[yyn]);
360: //#### NEXT STATE ####
361: yystate = yytable[yyn];//we are in a new state
362: state_push(yystate); //save it
363: val_push(yylval); //push our lval as the input for next rule
364: yychar = -1; //since we have 'eaten' a token, say we need another
365: if (yyerrflag > 0) //have we recovered an error?
366: --yyerrflag; //give ourselves credit
367: doaction = false; //but don't process yet
368: break; //quit the yyn=0 loop
369: }
370:
371: yyn = yyrindex[yystate]; //reduce
372: if ((yyn != 0) && (yyn += yychar) >= 0
373: && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { //we reduced!
374: if (yydebug)
375: debug("reduce");
376: yyn = yytable[yyn];
377: doaction = true; //get ready to execute
378: break; //drop down to actions
379: } else //ERROR RECOVERY
380: {
381: if (yyerrflag == 0) {
382: yyerror("syntax error");
383: yynerrs++;
384: }
385: if (yyerrflag < 3) //low error count?
386: {
387: yyerrflag = 3;
388: while (true) //do until break
389: {
390: if (stateptr < 0) //check for under & overflow here
391: {
392: yyerror("stack underflow. aborting..."); //note lower case 's'
393: return 1;
394: }
395: yyn = yysindex[state_peek(0)];
396: if ((yyn != 0) && (yyn += YYERRCODE) >= 0
397: && yyn <= YYTABLESIZE
398: && yycheck[yyn] == YYERRCODE) {
399: if (yydebug)
400: debug("state "
401: + state_peek(0)
402: + ", error recovery shifting to state "
403: + yytable[yyn] + " ");
404: yystate = yytable[yyn];
405: state_push(yystate);
406: val_push(yylval);
407: doaction = false;
408: break;
409: } else {
410: if (yydebug)
411: debug("error recovery discarding state "
412: + state_peek(0) + " ");
413: if (stateptr < 0) //check for under & overflow here
414: {
415: yyerror("Stack underflow. aborting..."); //capital 'S'
416: return 1;
417: }
418: state_pop();
419: val_pop();
420: }
421: }
422: } else //discard this token
423: {
424: if (yychar == 0)
425: return 1; //yyabort
426: if (yydebug) {
427: yys = null;
428: if (yychar <= YYMAXTOKEN)
429: yys = yyname[yychar];
430: if (yys == null)
431: yys = "illegal-symbol";
432: debug("state "
433: + yystate
434: + ", error recovery discards token "
435: + yychar + " (" + yys + ")");
436: }
437: yychar = -1; //read another
438: }
439: }//end error recovery
440: }//yyn=0 loop
441: if (!doaction) //any reason not to proceed?
442: continue; //skip action
443: yym = yylen[yyn]; //get count of terminals on rhs
444: if (yydebug)
445: debug("state " + yystate + ", reducing " + yym
446: + " by rule " + yyn + " (" + yyrule[yyn] + ")");
447: if (yym > 0) //if count of rhs not 'nil'
448: yyval = val_peek(yym - 1); //get current semantic value
449: switch (yyn) {
450: //########## USER-SUPPLIED ACTIONS ##########
451: case 2:
452: //#line 18 "HtmlParser.y"
453: {
454: delegate.startDocument();
455: }
456: break;
457: case 3:
458: //#line 19 "HtmlParser.y"
459: {
460: delegate.endDocument();
461: }
462: break;
463: case 4:
464: //#line 20 "HtmlParser.y"
465: {
466: delegate.startDocument();
467: }
468: break;
469: case 5:
470: //#line 22 "HtmlParser.y"
471: {
472: delegate.endDocument();
473: }
474: break;
475: case 9:
476: //#line 32 "HtmlParser.y"
477: {
478: delegate.startElement();
479: tagName = yyval;
480: }
481: break;
482: case 10:
483: //#line 33 "HtmlParser.y"
484: {
485: delegate.startElement(tagName);
486: }
487: break;
488: case 11:
489: //#line 34 "HtmlParser.y"
490: {
491: delegate.endElement(yyval);
492: }
493: break;
494: case 12:
495: //#line 35 "HtmlParser.y"
496: {
497: delegate.addAttribute(yyval);
498: }
499: break;
500: case 14:
501: //#line 37 "HtmlParser.y"
502: {
503: delegate.startElement();
504: tagName = yyval;
505: }
506: break;
507: case 15:
508: //#line 38 "HtmlParser.y"
509: {
510: delegate.startDTD(yyval);
511: }
512: break;
513: case 16:
514: //#line 39 "HtmlParser.y"
515: {
516: delegate.processingInstruction(yyval);
517: }
518: break;
519: case 17:
520: //#line 40 "HtmlParser.y"
521: {
522: delegate.startCDATA();
523: }
524: break;
525: case 18:
526: //#line 41 "HtmlParser.y"
527: {
528: delegate.characters(yyval);
529: }
530: break;
531: case 19:
532: //#line 42 "HtmlParser.y"
533: {
534: delegate.comment(yyval);
535: }
536: break;
537: //#line 487 "HtmlParser.java"
538: //########## END OF USER-SUPPLIED ACTIONS ##########
539: }//switch
540: //#### Now let's reduce... ####
541: if (yydebug)
542: debug("reduce");
543: state_drop(yym); //we just reduced yylen states
544: yystate = state_peek(0); //get new state
545: val_drop(yym); //corresponding value drop
546: yym = yylhs[yyn]; //select next TERMINAL(on lhs)
547: if (yystate == 0 && yym == 0)//done? 'rest' state and at first TERMINAL
548: {
549: debug("After reduction, shifting from state 0 to state "
550: + YYFINAL + "");
551: yystate = YYFINAL; //explicitly say we're done
552: state_push(YYFINAL); //and save it
553: val_push(yyval); //also save the semantic value of parsing
554: if (yychar < 0) //we want another character?
555: {
556: yychar = yylex(); //get next character
557: if (yychar < 0)
558: yychar = 0; //clean, if necessary
559: if (yydebug)
560: yylexdebug(yystate, yychar);
561: }
562: if (yychar == 0) //Good exit (if lex returns 0 ;-)
563: break; //quit the loop--all DONE
564: }//if yystate
565: else //else not done yet
566: { //get next state and push, for next yydefred[]
567: yyn = yygindex[yym]; //find out where to go
568: if ((yyn != 0) && (yyn += yystate) >= 0
569: && yyn <= YYTABLESIZE
570: && yycheck[yyn] == yystate)
571: yystate = yytable[yyn]; //get new state
572: else
573: yystate = yydgoto[yym]; //else go to new defred
574: debug("after reduction, shifting from state "
575: + state_peek(0) + " to state " + yystate + "");
576: state_push(yystate); //going again, so push state & val...
577: val_push(yyval); //for next action
578: }
579: }//main loop
580: return 0;//yyaccept!!
581: }
582:
583: //## end of method parse() ######################################
584:
585: //## run() --- for Thread #######################################
586: /**
587: * A default run method, used for operating this parser
588: * object in the background. It is intended for extending Thread
589: * or implementing Runnable. Turn off with -Jnorun .
590: */
591: public void run() {
592: yyparse();
593: }
594:
595: //## end of method run() ########################################
596:
597: //## Constructors ###############################################
598: /**
599: * Default constructor. Turn off with -Jnoconstruct .
600:
601: */
602: public HtmlParser() {
603: //nothing to do
604: }
605:
606: /**
607: * Create a parser, setting the debug to true or false.
608: * @param debugMe true for debugging, false for no debug.
609: */
610: public HtmlParser(boolean debugMe) {
611: yydebug = debugMe;
612: }
613: //###############################################################
614:
615: }
616: //################### END OF CLASS ##############################
|