1/* DLGLexerBase.c 2 * 3 * SOFTWARE RIGHTS 4 * 5 * We reserve no LEGAL rights to the Purdue Compiler Construction Tool 6 * Set (PCCTS) -- PCCTS is in the public domain. An individual or 7 * company may do whatever they wish with source code distributed with 8 * PCCTS or the code generated by PCCTS, including the incorporation of 9 * PCCTS, or its output, into commerical software. 10 * 11 * We encourage users to develop software with PCCTS. However, we do ask 12 * that credit is given to us for developing PCCTS. By "credit", 13 * we mean that if you incorporate our source code into one of your 14 * programs (commercial product, research project, or otherwise) that you 15 * acknowledge this fact somewhere in the documentation, research report, 16 * etc... If you like PCCTS and have developed a nice tool with the 17 * output, please mention that you developed it using PCCTS. In 18 * addition, we ask that this header remain intact in our source code. 19 * As long as these guidelines are kept, we expect to continue enhancing 20 * this system and expect to make other tools available as they are 21 * completed. 22 * 23 * ANTLR 1.33 24 * Terence Parr 25 * Parr Research Corporation 26 * with Purdue University and AHPCRC, University of Minnesota 27 * 1989-2000 28 */ 29 30#include "pcctscfg.h" 31 32#include "pccts_stdio.h" 33#include "pccts_stdlib.h" 34 35PCCTS_NAMESPACE_STD 36 37/* I have to put this here due to C++ limitation 38 * that you can't have a 'forward' decl for enums. 39 * I hate C++!!!!!!!!!!!!!!! 40 */ 41 42// MR1 43// MR1 10-Apr-97 133MR1 Prevent use of varying sizes for the 44// MR1 ANTLRTokenType enum 45// MR1 46 47enum ANTLRTokenType { TER_HATES_CPP=0, ITS_UTTER_GARBAGE, // MR1 48 WITH_SOME_GOOD_IDEAS=9999}; // MR1 49 50#define ANTLR_SUPPORT_CODE 51 52#include "pcctscfg.h" 53#include DLEXERBASE_H 54#include APARSER_H // MR23 55 56DLGLexerBase:: 57DLGLexerBase(DLGInputStream *in, 58 unsigned bufsize, 59 int _interactive, 60 int _track_columns) 61{ 62 this->_bufsize = bufsize; 63 this->_lextext = new DLGChar[_bufsize]; 64 if ( this->_lextext==NULL ) { 65 panic("text buffer is NULL"); 66 } 67 this->_begexpr = this->_endexpr = NULL; 68 this->ch = this->bufovf = 0; 69 this->nextpos = NULL; 70 this->cl = 0; 71 this->add_erase = 0; 72 this->input = in; 73 this->_begcol = 0; 74 this->_endcol = 0; 75 this->_line = 1; 76 this->charfull = 0; 77 this->automaton = 0; 78 this->token_to_fill = NULL; 79 this->interactive = _interactive; 80 this->track_columns = _track_columns; 81 this->debugLexerFlag = 0; // MR1 82 this->parser = NULL; // MR1 83 this->lexErrCount=0; // MR11 84} 85 86// MR19 THM 87 88void DLGLexerBase::reset() 89{ 90 this->charfull = 0; 91 this->_begcol = 0; 92 this->_endcol = 0; 93 this->automaton = 0; 94 this->_line=1; 95 this->lexErrCount=0; 96} 97 98void DLGLexerBase:: 99setInputStream( DLGInputStream *in ) 100{ 101 this->input = in; 102 _line = 1; 103 charfull = 0; 104} 105 106/* saves dlg state, but not what feeds dlg (such as file position) */ 107void DLGLexerBase:: 108saveState(DLGState *state) 109{ 110 state->input = input; 111 state->interactive = interactive; 112 state->track_columns = track_columns; 113 state->auto_num = automaton; 114 state->add_erase = add_erase; 115 state->lookc = ch; 116 state->char_full = charfull; 117 state->begcol = _begcol; 118 state->endcol = _endcol; 119 state->line = _line; 120 state->lextext = _lextext; 121 state->begexpr = _begexpr; 122 state->endexpr = _endexpr; 123 state->bufsize = _bufsize; 124 state->bufovf = bufovf; 125 state->nextpos = nextpos; 126 state->class_num = cl; 127 state->debugLexerFlag = debugLexerFlag; // MR1 128 state->parser = parser; // MR1 129} 130 131void DLGLexerBase:: 132restoreState(DLGState *state) 133{ 134 input = state->input; 135 interactive = state->interactive; 136 track_columns = state->track_columns; 137 automaton = state->auto_num; 138 add_erase = state->add_erase; 139 ch = state->lookc; 140 charfull = state->char_full; 141 _begcol = state->begcol; 142 _endcol = state->endcol; 143 _line = state->line; 144 _lextext = state->lextext; 145 _begexpr = state->begexpr; 146 _endexpr = state->endexpr; 147 _bufsize = state->bufsize; 148 bufovf = state->bufovf; 149 nextpos = state->nextpos; 150 cl = state->class_num; 151 debugLexerFlag = state->debugLexerFlag; // MR1 152 parser = state->parser; // MR1 153} 154 155/* erase what is currently in the buffer, and get a new reg. expr */ 156void DLGLexerBase:: 157skip() 158{ 159 add_erase = 1; 160} 161 162/* don't erase what is in the lextext buffer, add on to it */ 163void DLGLexerBase:: 164more() 165{ 166 add_erase = 2; 167} 168 169/* substitute c for the reg. expr last matched and is in the buffer */ 170void DLGLexerBase:: 171replchar(DLGChar c) 172{ 173 /* can't allow overwriting null at end of string */ 174 if (_begexpr < &_lextext[_bufsize-1]){ 175 *_begexpr = c; 176 *(_begexpr+1) = '\0'; 177 } 178 _endexpr = _begexpr; 179 if (c != '\0') { 180 nextpos = _begexpr + 1; 181 } 182 else { 183 nextpos = _begexpr; /* MR30 Zero terminates string. */ 184 } 185} 186 187/* replace the string s for the reg. expr last matched and in the buffer */ 188 189#ifdef _MSC_VER // MR23 190//Turn off "assignment within conditional expression" warning 191#pragma warning(disable : 4706) 192#endif 193void DLGLexerBase:: 194replstr(const DLGChar *s) /* MR20 const */ 195{ 196 register DLGChar *l= &_lextext[_bufsize -1]; 197 198 nextpos = _begexpr; 199 if (s){ 200 while ((nextpos <= l) && (*(nextpos++) = *(s++))){ 201 /* empty */ 202 } 203 /* correct for NULL at end of string */ 204 nextpos--; 205 } 206 if ((nextpos <= l) && (*(--s) == 0)){ 207 bufovf = 0; 208 }else{ 209 bufovf = 1; 210 } 211 *(nextpos) = '\0'; 212 _endexpr = nextpos - 1; 213} 214#ifdef _MSC_VER // MR23 215#pragma warning(default: 4706) 216#endif 217 218void DLGLexerBase:: 219errstd(const char *s) /* MR20 const */ 220{ 221 lexErrCount++; /* MR11 */ 222 /* MR23 */ printMessage(stderr, 223 "%s near line %d (text was '%s')\n", 224 ((s == NULL) ? "Lexical error" : s), 225 _line,_lextext); 226} 227 228int DLGLexerBase:: 229err_in() 230{ 231 /* MR23 */ printMessage(stderr,"No input stream, function, or string\n"); 232 /* return eof to get out gracefully */ 233 return EOF; 234} 235 236ANTLRTokenType DLGLexerBase:: 237erraction() 238{ 239 errstd("invalid token"); 240 advance(); 241 skip(); 242 return (ANTLRTokenType) 0; // bogus, but satisfies compiler 243} 244 245_ANTLRTokenPtr DLGLexerBase:: 246getToken() 247{ 248 if ( token_to_fill==NULL ) panic("NULL token_to_fill"); 249 ANTLRTokenType tt = nextTokenType(); 250 _ANTLRTokenPtr tk = token_to_fill->makeToken(tt, _lextext,_line); 251 return tk; 252} 253 254void DLGLexerBase:: 255panic(const char *msg) /* MR20 const */ 256{ 257 if (parser) //MR23 258 parser->panic(msg); //MR23 259 else //MR23 260 { 261 /* MR23 */ printMessage(stderr, "DLG panic: %s\n", msg); 262 // 263 // 7-Apr-97 133MR1 264 // 265 exit(PCCTS_EXIT_FAILURE); // MR1 266 } 267} 268 269ANTLRParser * DLGLexerBase:: // MR1 270setParser(ANTLRParser *p) { // MR1 271 ANTLRParser *oldValue=parser; // MR1 272 parser=p; // MR1 273 return oldValue; // MR1 274} // MR1 275 // MR1 276ANTLRParser * DLGLexerBase:: // MR1 277getParser() { // MR1 278 return parser; // MR1 279} // MR1 280 // MR1 281int DLGLexerBase:: // MR1 282debugLexer(int newValue) { // MR1 283 int oldValue=debugLexerFlag; // MR1 284 debugLexerFlag=newValue; // MR1 285 return oldValue; // MR1 286} // MR1 287 288//MR23 289int DLGLexerBase::printMessage(FILE* pFile, const char* pFormat, ...) 290{ 291 va_list marker; 292 va_start( marker, pFormat ); 293 294 int iRet = 0; 295 if (parser) 296 parser->printMessageV(pFile, pFormat, marker); 297 else 298 iRet = vfprintf(pFile, pFormat, marker); 299 300 va_end( marker ); 301 return iRet; 302} 303