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