2 * Copyright 2001-2006 Adrian Thurston <thurston@cs.queensu.ca>
5 /* This file is part of Ragel.
7 * Ragel is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * Ragel is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Ragel; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #define YY_NEVER_INTERACTIVE 1
25 //#define WANT_TOKEN_WRITE
30 #include "parsedata.h"
39 bool inlineWhitespace = true;
40 bool handlingInclude = false;
41 bool multiline = false;
43 /* Used for recognising host language code blocks, init with anything not
44 * involved in the host lang test. */
45 int previous_tokens[2] = { TK_Section, TK_Section };
47 /* These keep track of the start of an inline comment or literal string for
48 * reporting unterminated comments or strings. */
49 int il_comm_lit_first_line;
50 int il_comm_lit_first_column;
52 /* These keep track of the start of a code block for reporting unterminated
54 int il_code_first_line;
55 int il_code_first_column;
57 /* Include Stack data. */
58 YY_BUFFER_STATE buff_stack[INCLUDE_STACK_SIZE];
59 bool multiline_stack[INCLUDE_STACK_SIZE];
60 int inc_stack_ptr = 0;
66 extern int includeDepth;
70 void extendToken( char *data, int len );
73 int emitToken( int token, char *data, int len );
74 int emitNoData( int token );
75 void passThrough( char *data );
76 bool openMachineSpecBlock();
79 enum InlineBlockType {
84 /* Using a wrapper for the parser, must the lex declaration. */
85 #define YY_DECL int ragel_lex()
89 /* Outside an fsm machine specification ("outside code"). */
95 /* Inside a fsm machine specification. */
114 IDENT [a-zA-Z_][a-zA-Z_0-9]*
118 /* Numbers in outter code. */
121 passThrough( yytext );
124 /* Words in outter code. */
127 passThrough( yytext );
130 /* Begin a c style comment. */
134 passThrough( yytext );
136 /* Data in a C style comment. */
137 <OC_C_COM>. extendToken(); passThrough( yytext );
138 <OC_C_COM>\n extendToken(); passThrough( yytext );
140 /* Terminate a C style comment. */
144 passThrough( yytext );
147 /* Begin a C++ style comment. */
151 passThrough( yytext );
153 /* Data in a C++ style comment. */
156 passThrough( yytext );
158 /* Terminate a C++ style comment. */
162 passThrough( yytext );
166 /* Start literals. */
170 passThrough( yytext );
175 passThrough( yytext );
177 /* Various escape sequences in literals. We don't need to get them
178 * all here. We just need to pick off the ones that could confuse us
179 * about the literal we are matchine */
180 <OC_SGL_LIT,OC_DBL_LIT>\\\' extendToken(); passThrough( yytext );
181 <OC_SGL_LIT,OC_DBL_LIT>\\\" extendToken(); passThrough( yytext );
182 <OC_SGL_LIT,OC_DBL_LIT>\\\\ extendToken(); passThrough( yytext );
183 /* Characters in literals. */
184 <OC_DBL_LIT>[^\"] extendToken(); passThrough( yytext );
185 <OC_SGL_LIT>[^\'] extendToken(); passThrough( yytext );
186 /* Terminate a double literal */
190 passThrough( yytext );
192 /* Terminate a single literal. */
196 passThrough( yytext );
202 passThrough( yytext );
205 /* Section Deliminator */
209 return emitNoData( TK_Section );
212 /* Section Deliminator */
216 return emitNoData( TK_Section );
221 passThrough( yytext );
226 passThrough( yytext );
231 passThrough( yytext );
234 /* Any other characters. */
237 passThrough( yytext );
241 <RL_INITIAL,IL_INITIAL>[0-9][0-9]* {
242 return emitToken( TK_UInt, yytext, yyleng );
244 <RL_INITIAL,IL_INITIAL>0x[0-9a-fA-F][0-9a-fA-F]* {
245 return emitToken( TK_Hex, yytext, yyleng );
248 /* Keywords in RL and IL. */
249 <RL_INITIAL>variable\ [a-zA-Z_]+ {
251 inlineBlockType = SemiTerminated;
252 return emitToken( KW_Variable, yytext+9, yyleng-9 );
256 inlineBlockType = SemiTerminated;
257 return emitNoData( KW_Access );
260 return emitNoData( KW_Action );
262 <RL_INITIAL>alphtype {
264 inlineWhitespace = false;
265 inlineBlockType = SemiTerminated;
266 return emitNoData( KW_AlphType );
270 inlineBlockType = SemiTerminated;
271 return emitNoData( KW_GetKey );
274 return emitNoData( KW_When );
277 return emitNoData( KW_Eof );
280 return emitNoData( KW_Err );
283 return emitNoData( KW_Lerr );
286 return emitNoData( KW_To );
289 return emitNoData( KW_From );
295 return emitNoData( KW_Range );
300 return emitNoData( KW_Write );
302 <RL_INITIAL>machine {
303 return emitNoData( KW_Machine );
305 <RL_INITIAL>include {
306 /* Include tokens statments are processed by both the scanner and the
307 * parser. The scanner opens the include file and switches to it and the
308 * parser invokes a new parser for handling the tokens. We use
309 * handlingInclude to indicate that the scanner is processing an include
310 * directive. Ends at ; */
311 handlingInclude = true;
312 return emitNoData( KW_Include );
315 <RL_WRITE>{WSCHAR}+ garble();
318 return emitNoData( ';' );
321 /* These must be synced in rlparse.y */
323 return emitNoData( KW_PChar );
326 return emitNoData( KW_Char );
329 return emitNoData( KW_Hold );
332 return emitNoData( KW_Goto );
335 return emitNoData( KW_Call );
338 return emitNoData( KW_Ret );
341 return emitNoData( KW_CurState );
344 return emitNoData( KW_TargState );
347 return emitNoData( KW_Entry );
350 return emitNoData( KW_Next );
353 return emitNoData( KW_Exec );
356 return emitNoData( KW_Break );
360 <RL_INITIAL,IL_INITIAL,RL_WRITE>{IDENT} {
361 return emitToken( TK_Word, yytext, yyleng );
364 /* Begin a shell style comment. */
369 /* Data in a shell style comment. */
370 <RL_SHELL_COM>[^\n]+ {
373 /* Terminate a C++ style comment. */
380 * Start single and double literals.
391 /* Escape sequences in single and double literals. */
392 <RL_SLIT,RL_DLIT>\\0 extendToken( "\0", 1 );
393 <RL_SLIT,RL_DLIT>\\a extendToken( "\a", 1 );
394 <RL_SLIT,RL_DLIT>\\b extendToken( "\b", 1 );
395 <RL_SLIT,RL_DLIT>\\t extendToken( "\t", 1 );
396 <RL_SLIT,RL_DLIT>\\n extendToken( "\n", 1 );
397 <RL_SLIT,RL_DLIT>\\v extendToken( "\v", 1 );
398 <RL_SLIT,RL_DLIT>\\f extendToken( "\f", 1 );
399 <RL_SLIT,RL_DLIT>\\r extendToken( "\r", 1 );
400 <RL_SLIT,RL_DLIT>\\\n extendToken();
401 <RL_SLIT,RL_DLIT>\\. extendToken( yytext+1, 1 );
403 /* Characters in literals. */
404 <RL_SLIT>[^'] extendToken( yytext, 1 );
405 <RL_DLIT>[^"] extendToken( yytext, 1 );
407 /* Terminate a single literal. */
410 return emitToken( yytext[1] == 'i' ? TK_CiLiteral : TK_Literal, 0, 0 );
412 /* Terminate a double literal */
415 return emitToken( yytext[1] == 'i' ? TK_CiLiteral : TK_Literal, 0, 0 );
419 * Start an OR expression.
423 return emitNoData( RE_SqOpen );
428 return emitNoData( RE_SqOpenNeg );
431 /* Escape sequences in OR expressions. */
432 <RL_OREXP>\\0 { return emitToken( RE_Char, "\0", 1 ); }
433 <RL_OREXP>\\a { return emitToken( RE_Char, "\a", 1 ); }
434 <RL_OREXP>\\b { return emitToken( RE_Char, "\b", 1 ); }
435 <RL_OREXP>\\t { return emitToken( RE_Char, "\t", 1 ); }
436 <RL_OREXP>\\n { return emitToken( RE_Char, "\n", 1 ); }
437 <RL_OREXP>\\v { return emitToken( RE_Char, "\v", 1 ); }
438 <RL_OREXP>\\f { return emitToken( RE_Char, "\f", 1 ); }
439 <RL_OREXP>\\r { return emitToken( RE_Char, "\r", 1 ); }
440 <RL_OREXP>\\\n { garble(); }
441 <RL_OREXP>\\. { return emitToken( RE_Char, yytext+1, 1 ); }
443 /* Range dash in an OR expression. */
445 return emitNoData( RE_Dash );
448 /* Characters in an OR expression. */
450 return emitToken( RE_Char, yytext, 1 );
453 /* Terminate an OR expression. */
456 return emitNoData( RE_SqClose );
460 * Start a regular expression.
464 return emitNoData( RE_Slash );
467 /* Escape sequences in regular expressions. */
468 <RL_REGEXP,RL_REGEXP_OR>\\0 {
469 return emitToken( RE_Char, "\0", 1 );
471 <RL_REGEXP,RL_REGEXP_OR>\\a {
472 return emitToken( RE_Char, "\a", 1 );
474 <RL_REGEXP,RL_REGEXP_OR>\\b {
475 return emitToken( RE_Char, "\b", 1 );
477 <RL_REGEXP,RL_REGEXP_OR>\\t {
478 return emitToken( RE_Char, "\t", 1 );
480 <RL_REGEXP,RL_REGEXP_OR>\\n {
481 return emitToken( RE_Char, "\n", 1 );
483 <RL_REGEXP,RL_REGEXP_OR>\\v {
484 return emitToken( RE_Char, "\v", 1 );
486 <RL_REGEXP,RL_REGEXP_OR>\\f {
487 return emitToken( RE_Char, "\f", 1 );
489 <RL_REGEXP,RL_REGEXP_OR>\\r {
490 return emitToken( RE_Char, "\r", 1 );
492 <RL_REGEXP,RL_REGEXP_OR>\\\n {
495 <RL_REGEXP,RL_REGEXP_OR>\\. {
496 return emitToken( RE_Char, yytext+1, 1 );
499 /* Special characters in a regular expression. */
501 return emitNoData( RE_Dot );
504 return emitNoData( RE_Star );
508 return emitNoData( RE_SqOpenNeg );
512 return emitNoData( RE_SqOpen );
515 /* Range dash in a regular expression or set. */
517 return emitNoData( RE_Dash );
520 /* Terminate an or set or a regular expression. */
523 return emitNoData( RE_SqClose );
526 /* Characters in a regular expression. */
527 <RL_REGEXP,RL_REGEXP_OR>[^/] {
528 return emitToken( RE_Char, yytext, 1 );
531 /* Terminate a regular expression */
532 <RL_REGEXP,RL_REGEXP_OR>\/[i]* {
534 return emitToken( RE_Slash, yytext, yyleng );
537 /* Builtin code move to Builtin initial. */
539 if ( openMachineSpecBlock() ) {
541 return emitNoData( *yytext );
544 /* Start an inline code block. Keep track of where it started in case
545 * it terminates prematurely. Return the open bracket. */
547 inlineBlockType = CurlyDelimited;
548 il_code_first_line = id->last_line;
549 il_code_first_column = id->last_column+1;
551 return emitNoData( *yytext );
556 return emitNoData( TK_DotDot );
560 return emitNoData( TK_ColonGt );
564 return emitNoData( TK_ColonGtGt );
568 return emitNoData( TK_LtColon );
572 return emitNoData( TK_DashDash );
575 /* The instantiation operator. */
577 return emitNoData( TK_ColonEquals );
582 return emitNoData( TK_StartGblError );
585 return emitNoData( TK_AllGblError );
588 return emitNoData( TK_FinalGblError );
591 return emitNoData( TK_NotStartGblError );
594 return emitNoData( TK_NotFinalGblError );
597 return emitNoData( TK_MiddleGblError );
600 /* Local error actions. */
602 return emitNoData( TK_StartLocalError );
605 return emitNoData( TK_AllLocalError );
608 return emitNoData( TK_FinalLocalError );
611 return emitNoData( TK_NotStartLocalError );
614 return emitNoData( TK_NotFinalLocalError );
617 return emitNoData( TK_MiddleLocalError );
622 return emitNoData( TK_StartEOF );
625 return emitNoData( TK_AllEOF );
628 return emitNoData( TK_FinalEOF );
631 return emitNoData( TK_NotStartEOF );
634 return emitNoData( TK_NotFinalEOF );
637 return emitNoData( TK_MiddleEOF );
640 /* To State Actions. */
642 return emitNoData( TK_StartToState );
645 return emitNoData( TK_AllToState );
648 return emitNoData( TK_FinalToState );
651 return emitNoData( TK_NotStartToState );
654 return emitNoData( TK_NotFinalToState );
657 return emitNoData( TK_MiddleToState );
660 /* From State Actions. */
662 return emitNoData( TK_StartFromState );
665 return emitNoData( TK_AllFromState );
668 return emitNoData( TK_FinalFromState );
671 return emitNoData( TK_NotStartFromState );
674 return emitNoData( TK_NotFinalFromState );
677 return emitNoData( TK_MiddleFromState );
681 return emitNoData( TK_Middle );
685 return emitNoData( TK_StartCond );
688 return emitNoData( TK_AllCond );
691 return emitNoData( TK_LeavingCond );
694 /* The Arrow operator. */
696 return emitNoData( TK_Arrow );
699 /* The double arrow operator. */
701 return emitNoData( TK_DoubleArrow );
704 /* Double star (longest match kleene star). */
706 return emitNoData( TK_StarStar );
709 /* Name separator. */
711 return emitNoData( TK_NameSep );
714 /* Opening of longest match. */
716 return emitNoData( TK_BarStar );
719 /* Catch the repetition operator now to free up the parser. Once caught,
720 * Send only the opening brace and rescan the rest so it can be broken
721 * up for the parser. */
722 <RL_INITIAL>\{([0-9]+(,[0-9]*)?|,[0-9]+)\} {
724 return emitNoData( TK_RepOpOpen );
727 /* Section Deliminator */
730 return emitNoData( TK_Section );
734 <RL_INITIAL>[\t\v\f\r ] garble();
740 return emitNoData( TK_SectionNL );
744 /* Any other characters. */
746 return emitNoData( *yytext );
749 /* End of input in a literal is an error. */
750 <RL_SLIT,RL_DLIT><<EOF>> {
751 error(id->first_line, id->first_column) << "unterminated literal" << endl;
755 /* End of input in a comment is an error. */
756 <RL_SHELL_COM><<EOF>> {
757 error(id->first_line, id->first_column) << "unterminated comment" << endl;
761 /* Begin a C style comment. */
764 il_comm_lit_first_line = id->last_line;
765 il_comm_lit_first_column = id->last_column+1;
766 extendToken( yytext, yyleng );
768 /* Data in a C style comment. */
769 <IL_C_COM>\n extendToken( yytext, 1 );
770 <IL_C_COM>. extendToken( yytext, 1 );
772 /* Terminate a C style comment. */
775 return emitToken( IL_Comment, yytext, 2 );
778 /* Begin a C++ style comment. */
781 il_comm_lit_first_line = id->last_line;
782 il_comm_lit_first_column = id->last_column+1;
783 extendToken( yytext, yyleng );
785 /* Data in a C++ style comment. */
787 extendToken( yytext, yyleng );
789 /* Terminate a C++ style comment. */
792 return emitToken( IL_Comment, yytext, 1 );
796 /* Start literals. */
799 il_comm_lit_first_line = id->last_line;
800 il_comm_lit_first_column = id->last_column+1;
801 extendToken( yytext, 1 );
805 il_comm_lit_first_line = id->last_line;
806 il_comm_lit_first_column = id->last_column+1;
807 extendToken( yytext, 1 );
809 /* Various escape sequences in literals. We don't need to get them
810 * all here. We just need to pick off the ones that could confuse us
811 * about the literal we are matching */
812 <IL_SGL_LIT,IL_DBL_LIT>\\' extendToken( yytext, yyleng );
813 <IL_SGL_LIT,IL_DBL_LIT>\\\" extendToken( yytext, yyleng );
814 <IL_SGL_LIT,IL_DBL_LIT>\\\\ extendToken( yytext, yyleng );
815 /* Characters in literals. */
816 <IL_DBL_LIT>[^\"] extendToken( yytext, 1 );
817 <IL_SGL_LIT>[^'] extendToken( yytext, 1 );
819 /* Terminate a double literal */
822 return emitToken( IL_Literal, yytext, 1 );
824 /* Terminate a single literal. */
827 return emitToken( IL_Literal, yytext, 1 );
830 /* Open Brace, increment count of open braces. */
833 return emitToken( IL_Symbol, yytext, 1 );
836 /* Close brace, decrement count of open braces. */
839 if ( inlineBlockType == CurlyDelimited && builtinBrace == 0 ) {
840 /* Inline code block ends. */
842 inlineWhitespace = true;
843 return emitNoData( *yytext );
846 /* Either a semi terminated inline block or only the closing brace of
847 * some inner scope, not the block's closing brace. */
848 return emitToken( IL_Symbol, yytext, 1 );
852 /* May need to terminate the inline block. */
854 if ( inlineBlockType == SemiTerminated ) {
855 /* Inline code block ends. */
857 inlineWhitespace = true;
858 return emitNoData( TK_Semi );
861 /* Not ending. The semi is sent as a token, not a generic symbol. */
862 return emitNoData( *yytext );
866 /* Catch some symbols so they can be
867 * sent as tokens instead as generic symbols. */
869 return emitNoData( *yytext );
872 return emitNoData( TK_NameSep );
876 <IL_INITIAL>{WSCHAR}+ {
877 if ( inlineWhitespace )
878 return emitToken( IL_WhiteSpace, yytext, yyleng );
881 /* Any other characters. */
883 return emitToken( IL_Symbol, yytext, 1 );
887 /* If we are not at the bottom of the include stack, then pop the current
888 * file that we are scanning. Since we are always returning 0 to the parser
889 * it will exit and return to the parser that called it. */
890 if ( inc_stack_ptr > 0 )
895 /* End of input in a literal is an error. */
896 <IL_SGL_LIT,IL_DBL_LIT><<EOF>> {
897 error(il_comm_lit_first_line, il_comm_lit_first_column) <<
898 "unterminated literal" << endl;
902 /* End of input in a comment is an error. */
903 <IL_C_COM,IL_CXX_COM><<EOF>> {
904 error(il_comm_lit_first_line, il_comm_lit_first_column) <<
905 "unterminated comment" << endl;
909 /* End of intput in a code block. */
910 <IL_INITIAL><<EOF>> {
911 error(il_code_first_line, il_code_first_column) <<
912 "unterminated code block" << endl;
918 /* Write out token data, escaping special charachters. */
919 #ifdef WANT_TOKEN_WRITE
920 void writeToken( int token, char *data )
922 cout << "token id " << token << " at " << id->fileName << ":" <<
923 yylloc->first_line << ":" << yylloc->first_column << "-" <<
924 yylloc->last_line << ":" << yylloc->last_column << " ";
927 while ( *data != 0 ) {
929 case '\n': cout << "\\n"; break;
930 case '\t': cout << "\\t"; break;
931 default: cout << *data; break;
940 /* Caclulate line info from yytext. Called on every pattern match. */
941 void updateLineInfo()
943 /* yytext should always have at least one char. */
944 assert( yytext[0] != 0 );
946 /* Scan through yytext up to the last character. */
948 for ( ; p[1] != 0; p++ ) {
949 if ( p[0] == '\n' ) {
954 id->last_column += 1;
958 /* Always consider the last character as not a newline. Newlines at the
959 * end of a token are as any old character at the end of the line. */
960 id->last_column += 1;
962 /* The caller may be about to emit a token, be prepared to pass the line
963 * info to the parser. */
964 yylloc->first_line = id->first_line;
965 yylloc->first_column = id->first_column;
966 yylloc->last_line = id->last_line;
967 yylloc->last_column = id->last_column;
969 /* If the last character was indeed a newline, then wrap ahead now. */
970 if ( p[0] == '\n' ) {
976 /* Eat up a matched pattern that will not be part of a token. */
979 /* Update line information from yytext. */
982 /* The next token starts ahead of the last token. */
983 id->first_line = id->last_line;
984 id->first_column = id->last_column + 1;
987 /* Append data to the end of the token. More token data expected. */
988 void extendToken( char *data, int len )
990 if ( data != 0 && len > 0 )
991 tokbuf.append( data, len );
993 /* Update line information from yytext. */
997 /* Extend, but with no data, more data to come. */
1000 /* Update line information from yytext. */
1005 /* Possibly process include data. */
1006 void processInclude( int token )
1008 static char *incFileName = 0;
1010 if ( handlingInclude ) {
1011 if ( token == KW_Include )
1013 else if ( token == TK_Literal )
1014 incFileName = yylval->data.data;
1015 else if ( token == ';' ) {
1016 /* Terminate the include statement. Start reading from included file. */
1017 handlingInclude = false;
1019 if ( id->active && includeDepth < INCLUDE_STACK_SIZE ) {
1020 /* If there is no section name or input file, default to the curren values. */
1021 if ( incFileName == 0 )
1022 incFileName = id->fileName;
1024 /* Make the new buffer and switch to it. */
1025 FILE *incFile = fopen( incFileName, "rt" );
1026 if ( incFile != 0 ) {
1027 buff_stack[inc_stack_ptr] = YY_CURRENT_BUFFER;
1028 multiline_stack[inc_stack_ptr] = multiline;
1030 yy_switch_to_buffer( yy_create_buffer( incFile, YY_BUF_SIZE ) );
1034 error(*yylloc) << "could not locate include file \"" << incFileName
1044 /* Free the current buffer and move to the previous. */
1045 yy_delete_buffer( YY_CURRENT_BUFFER );
1047 yy_switch_to_buffer( buff_stack[inc_stack_ptr] );
1048 multiline = multiline_stack[inc_stack_ptr];
1050 /* Includes get called only from RL_INITIAL. */
1055 /* Append data to the end of a token and emitToken it to the parser. */
1056 int emitToken( int token, char *data, int len )
1058 /* Append any new data. */
1059 if ( data != 0 && len > 0 )
1060 tokbuf.append( data, len );
1062 /* Duplicate the buffer. */
1063 yylval->data.length = tokbuf.length;
1064 yylval->data.data = new char[tokbuf.length+1];
1065 memcpy( yylval->data.data, tokbuf.data, tokbuf.length );
1066 yylval->data.data[tokbuf.length] = 0;
1068 /* Update line information from yytext. */
1071 /* Write token info. */
1072 #ifdef WANT_TOKEN_WRITE
1073 writeToken( token, tokbuf.data );
1076 /* Clear out the buffer. */
1079 /* The next token starts ahead of the last token. */
1080 id->first_line = id->last_line;
1081 id->first_column = id->last_column + 1;
1083 /* Maintain a record of two tokens back. */
1084 previous_tokens[1] = previous_tokens[0];
1085 previous_tokens[0] = token;
1087 /* Possibly process the include statement; */
1088 processInclude( token );
1093 /* Emit a token with no data to the parser. */
1094 int emitNoData( int token )
1096 /* Return null to the parser. */
1097 yylval->data.data = 0;
1098 yylval->data.length = 0;
1100 /* Update line information from yytext. */
1103 /* Write token info. */
1104 #ifdef WANT_TOKEN_WRITE
1105 writeToken( token, 0 );
1108 /* Clear out the buffer. */
1111 /* The next token starts ahead of the last token. */
1112 id->first_line = id->last_line;
1113 id->first_column = id->last_column + 1;
1115 /* Maintain a record of two tokens back. */
1116 previous_tokens[1] = previous_tokens[0];
1117 previous_tokens[0] = token;
1119 /* Possibly process the include statement; */
1120 processInclude( token );
1125 /* Pass tokens in outter code through to the output. */
1126 void passThrough( char *data )
1128 /* If no errors and we are at the bottom of the include stack (the source
1129 * file listed on the command line) then write out the data. */
1130 if ( gblErrorCount == 0 && inc_stack_ptr == 0 &&
1131 machineSpec == 0 && machineName == 0 )
1133 xmlEscapeHost( *outStream, data );
1137 /* Init a buffer. */
1146 /* Empty out a buffer on destruction. */
1152 /* Free the space allocated for the buffer. */
1153 void Buffer::empty()
1164 /* Grow the buffer when to len allocation. */
1165 void Buffer::upAllocate( int len )
1168 data = (char*) malloc( len );
1170 data = (char*) realloc( data, len );
1176 /* Once processessing of the input is done, signal no more. */
1180 /* Here simply to suppress the unused yyunpt warning. */
1181 void thisFuncIsNeverCalled()
1186 /* Put the scannner back into the outside code start state. */
1187 void beginOutsideCode()
1192 /* Determine if we are opening a machine specification block. */
1193 bool openMachineSpecBlock()
1195 if ( previous_tokens[1] == TK_Section && previous_tokens[0] == TK_Word )
1197 else if ( previous_tokens[0] == TK_Section )
1202 /* Wrapper for the lexer which stores the locations of the value and location
1203 * variables of the parser into globals. The parser is reentrant, however the scanner
1204 * does not need to be, so globals work fine. This saves us passing them around
1205 * all the helper functions. */
1206 int yylex( YYSTYPE *yylval, YYLTYPE *yylloc )