lex core dumps on Sun 4 (because of start conditions?)

Kenneth Fox [UC90_439875] fox at emunix.emich.edu
Wed Jan 16 02:01:42 AEST 1991


I've been having a severe problem running lex on a Sun 4.  The problem
occurs under both SunOS 4.1 and 4.0.3.  It seems to be specific to sparc
as the file lexes fine on a Sun 3 (4.1) and microVAX II (Ultrix v3.0).

The bug itself seems to be caused by start conditions, and only when more
than 5 patterns active in the same start condition are used.  This could
be all wrong because I haven't extensively tested the failure conditions.
I can't give any better guess because lex is stripped as distributed by
Sun.

Another problem I have is that pattern lookahead doesn't seem to work when
a start condition is active.  Lex generates a message that an extra slash
has been removed.  Is this "correct"?  Personally, I think it would be
useful to specify left AND right context...

Hopefully, somebody with source code access will post a better explanation.

I apologize for such a large post (with such long lines), but I don't know
what part of this file is exactly causing the problem...  I'm praying that
the long lines will go through, but if they don't I'd be happy to send
somebody a good copy through mail.

			Thanks in advance,

			Ken Fox (fox at emunix.emich.edu)

------------------------------ Cut Here ------------------------------

%{
/*
** Ken Fox (fox at emunix.emich.edu)
**
** this code is in the public domain.
**
** this is a fragment of an Oracle SQL*FORMS converter.  It's big
** and ugly, but that shouldn't surprise anybody that's work with
** Oracle products before... 8-)
**
** use 4 character tabs for best results.
**
*/

#include <stdio.h>
#include <ctype.h>
#include "generic.h"		/* lex won't complain about not having these */
#include "global.h"
#include "y.tab.h"

#define MAX_VALUE_LEN	10240

extern long strtol();
extern double atof();

int readEscapeCode();
int readComment();
char *readString();
char *readValue();
char *readLine();

int inputLineCount = 1;

extern char *inputFileName;
extern YYSTYPE yylval;

#undef input
#undef unput

extern int inputUpper();
extern int inputRaw();

#define ReadKeywords()		input = inputUpper; BEGIN 0
#define ReadValues()		input = inputRaw; BEGIN ASSIGN

int (*input)() = inputUpper;
%}

%e		2000
%p		5000
%n		2000
%k		500
%a		4000
%o		4000

WS		[^a-zA-Z0-9]
D		[0-9]
H		[0-9a-fA-F]

%START ASSIGN

%%

[ \t]*														;
"/*"														{ (void)readComment(); }
\n															{ ++inputLineCount; }

DEFINE														{ return(T_DEFINE); }

FORM/{WS}													{ return(T_FORM); }
PROCEDURE/{WS}												{ return(T_PROCEDURE); }
TRIGGER														{ return(T_TRIGGER); }
STEP/{WS}													{ return(T_STEP); }
BLOCK/{WS}													{ return(T_BLOCK); }
FIELD/{WS}													{ return(T_FIELD); }
REFERENCE/{WS}												{ return(T_REFERENCE); }
SCREEN/{WS}													{ return(T_SCREEN); }
PAGE/{WS}													{ return(T_PAGE); }

ENDDEFINE													{ return(T_ENDDEFINE); }

ABORT														{ return(T_ABORT); }
APPLICATION													{ return(T_APPLICATION); }
ARRAY_SIZE													{ return(T_ARRAY_SIZE); }
AUTOHELP													{ return(T_AUTOHELP); }
AUTOSKIP													{ return(T_AUTOSKIP); }
BASE_LINE													{ return(T_BASE_LINE); }
BASE_TABLE													{ return(T_BASE_TABLE); }
BOILER														{ return(T_BOILER); }
BORDER														{ return(T_BORDER); }
COLUMN/{WS}													{ return(T_COLUMN); }
COLUMN_SECURITY												{ return(T_COLUMN_SECURITY); }
DATATYPE													{ return(T_DATATYPE); }
DEFAULT/{WS}												{ return(T_DEFAULT); }
DEFAULT_MENU_APPLICATION									{ return(T_DEFAULT_MENU_APPLICATION); }
DEFINITION													{ return(T_DEFINITION); }
DESCRIPTION													{ return(T_DESCRIPTION); }
DISPLAYED													{ return(T_DISPLAYED); }
DISPLAY_LENGTH												{ return(T_DISPLAY_LENGTH); }
DISSOLVE													{ return(T_DISSOLVE); }
ECHO														{ return(T_ECHO); }
EDIT_WORD_WRAP												{ return(T_EDIT_WORD_WRAP); }
EDIT_X														{ return(T_EDIT_X); }
EDIT_Y														{ return(T_EDIT_Y); }
ENFORCE_KEY_FROM											{ return(T_ENFORCE_KEY_FROM); }
FAILURE_STEP												{ return(T_FAILURE_STEP); }
FAIL_MESSAGE												{ return(T_FAIL_MESSAGE); }
FIXED_LENGTH												{ return(T_FIXED_LENGTH); }
GROUP_NAME													{ return(T_GROUP_NAME); }
HELP														{ return(T_HELP); }
HIGH_VALUE													{ return(T_HIGH_VALUE); }
HORIZONTAL_SCROLL_BAR										{ return(T_HORIZONTAL_SCROLL_BAR); }
IGNORE														{ return(T_IGNORE); }
INPUT/{WS}													{ return(T_INPUT); }
INPUT_MASK													{ return(T_INPUT_MASK); }
IN_MENU														{ return(T_IN_MENU); }
LABEL														{ return(T_LABEL); }
LENGTH														{ return(T_LENGTH); }
LINE/{WS}													{ return(T_LINE); }
LINES_PER_ROW												{ return(T_LINES_PER_ROW); }
LOV_TEXT													{ return(T_LOV_TEXT); }
LOV_TITLE													{ return(T_LOV_TITLE); }
LOV_X														{ return(T_LOV_X); }
LOV_Y														{ return(T_LOV_Y); }
LOW_VALUE													{ return(T_LOW_VALUE); }
MANDATORY													{ return(T_MANDATORY); }
MODE														{ return(T_MODE); }
MOUSE_NAVIGATION_LIMIT										{ return(T_MOUSE_NAVIGATION_LIMIT); }
NAME														{ return(T_NAME); }
NEW_CURSOR													{ return(T_NEW_CURSOR); }
ORDERING													{ return(T_ORDERING); }
OUTPUT_MASK													{ return(T_OUTPUT_MASK); }
OWNER														{ return(T_OWNER); }
PAGE_PX0													{ return(T_PAGE_PX0); }
PAGE_PXS													{ return(T_PAGE_PXS); }
PAGE_PY0													{ return(T_PAGE_PY0); }
PAGE_PYS													{ return(T_PAGE_PYS); }
PAGE_SX0													{ return(T_PAGE_SX0); }
PAGE_SY0													{ return(T_PAGE_SY0); }
PAGE_XS														{ return(T_PAGE_XS); }
PAGE_YS														{ return(T_PAGE_YS); }
POPUP														{ return(T_POPUP); }
PRIMARY_KEY													{ return(T_PRIMARY_KEY); }
QUERY/{WS}													{ return(T_QUERY); }
QUERY_LENGTH												{ return(T_QUERY_LENGTH); }
REVERSE														{ return(T_REVERSE); }
ROOT_MENU													{ return(T_ROOT_MENU); }
ROWS_BUFFERED												{ return(T_ROWS_BUFFERED); }
ROWS_DISPLAYED												{ return(T_ROWS_DISPLAYED); }
SHOW_KEY													{ return(T_SHOW_KEY); }
SUCCESS_STEP												{ return(T_SUCCESS_STEP); }
TABLE														{ return(T_TABLE); }
TEXT														{ return(T_TEXT); }
TITLE														{ return(T_TITLE); }
TRIGGER_TYPE												{ return(T_TRIGGER_TYPE); }
UNIQUE_KEY													{ return(T_UNIQUE_KEY); }
UPDATE/{WS}													{ return(T_UPDATE); }
UPDATE_KEY													{ return(T_UPDATE_KEY); }
UPDATE_NULL													{ return(T_UPDATE_NULL); }
UPPERCASE													{ return(T_UPPERCASE); }
VALIDATION_UNIT												{ return(T_VALIDATION_UNIT); }
VERTICAL_SCROLL_BAR											{ return(T_VERTICAL_SCROLL_BAR); }

"="															{ ReadValues(); return('='); }

/*
** BUGGY!
**
** this is where the problem is... combining
** the decimal and hexadecimal integer patterns
** into one pattern with an or (|) avoids the
** core dump.
*/

<ASSIGN>(({D}*\.{D}+)|({D}+\.{D}*))([eE][+-]?{D}+)?{WS}*$	{ ReadKeywords(); ++inputLineCount; fprintf(stderr, "REAL\n"); yylval.vReal = atof(yytext); return(T_REAL); }
<ASSIGN>{D}+{WS}*$											{ ReadKeywords(); ++inputLineCount; fprintf(stderr, "INTEGER\n"); yylval.vInteger = strtol(yytext, NULL, 0); return(T_INTEGER); }
<ASSIGN>0[Xx]{D}+{WS}*$										{ ReadKeywords(); ++inputLineCount; fprintf(stderr, "INTEGER\n"); yylval.vInteger = strtol(yytext, NULL, 0); return(T_INTEGER); }
<ASSIGN>(([Oo][Nn])|([Oo][Ff][Ff])){WS}*$					{ ReadKeywords(); ++inputLineCount; fprintf(stderr, "BOOLEAN\n"); yylval.vBoolean = (tolower(yytext[1]) == 'n') ? True : False; return(T_BOOLEAN); }
<ASSIGN>"<<<"												{ ReadKeywords(); fprintf(stderr, "<<<\n"); yylval.vString = readValue(); return(T_STRING); }
<ASSIGN>.													{ ReadKeywords(); fprintf(stderr, "STRING\n"); yylval.vString = readLine(yytext[0]); return(T_STRING); }

.															{ return(yytext[0]); }

%%


int readEscapeCode()

{
	int letter;

	switch (letter = inputRaw())
	{
		case 'g':
			return('\007');
		case 'b':
			return('\b');
		case 'f':
			return('\f');
		case 'n':
			return('\n');
		case 'r':
			return('\r');
		case 't':
			return('\t');
		case '\\':
			return('\\');
		default:
			if (isdigit(letter))
			{
				char buffer[10];
				char *ptr = buffer;
				int base = 10;

				if (letter == '0')
				{
					letter = inputRaw();
					if ((letter == 'x') || (letter == 'X'))
					{
						letter = inputRaw();
						base = 16;
					}
					else
					{
						unput(letter);
						letter = '0';
						base = 8;
					}
				}

				while ((isdigit(letter) || ((base == 16) && isxdigit(letter))) &&
					   (ptr - buffer < 3))
				{
					*ptr++ = letter;
					letter = inputRaw();
				}
				unput(letter);
				*ptr = 0;

				return((int)strtol(buffer, NULL, base));
			}
			else
			{
				return(letter);
			}
	}
}


int readComment()

{
	int letter;
	int level = 1;
	int commentStart = inputLineCount;

	while ((level > 0) && ((letter = inputRaw()) > 0))
	{
		if (letter == '*')
		{
			if (inputRaw() == '/')
			{
				--level;
			}
		}
		else if (letter == '\n')
		{
			++inputLineCount;
		}
		else if (letter == '/')
		{
			if (inputRaw() == '*')
			{
				++level;
			}
		}
	}

	if (level == 0)
	{
		return(1);
	}
	else
	{
		fprintf(stderr, "file \"%s\": line %d: syntax error: unterminated comment\n",
				inputFileName, commentStart);

		return(0);
	}
}


char *readString(quote)

int quote;

{
	static char buffer[MAX_VALUE_LEN];
	int stringStart = inputLineCount;
	char *ptr = buffer;

	while ((*ptr = inputRaw()) > 0)
	{
		if (*ptr == quote)
		{
			*ptr = 0;
			return(buffer);
		}
		else if (*ptr == '\\')
		{
			*ptr = (char)readEscapeCode();
		}
		else if (*ptr == '\n')
		{
			++inputLineCount;
		}

		if (++ptr - buffer >= MAX_VALUE_LEN)
		{
			fprintf(stderr, "file \"%s\": line %d: syntax error: string too long\n",
					inputFileName, stringStart);

			*buffer = 0;
			return(buffer);
		}
	}

	fprintf(stderr, "file \"%s\": line %d: syntax error: unterminated string?\n",
			inputFileName, stringStart);

	*buffer = 0;
	return(buffer);
}


char *readValue()

{
	static char buffer[MAX_VALUE_LEN];
	int stringStart = inputLineCount;
	char *ptr = buffer;
	int letter;
	int foundTerminator = 0;

	while (((letter = inputRaw()) > 0) && (isspace(letter)))
		;

	unput(letter);

	while ((*ptr = inputRaw()) > 0)
	{
		if (*ptr == '<')
		{
			if (++foundTerminator >= 3)
			{
				*ptr = 0;
				return(buffer);
			}
			continue;
		}
		else
		{
			if (foundTerminator)
			{
				while (foundTerminator--)
				{
					*ptr++ = '<';
				}
			}
			if (*ptr == '\n')
			{
				++inputLineCount;
			}
		}

		if (++ptr - buffer >= MAX_VALUE_LEN)
		{
			fprintf(stderr, "file \"%s\": line %d: syntax error: string too long\n",
					inputFileName, stringStart);

			*buffer = 0;
			return(buffer);
		}
	}

	fprintf(stderr, "file \"%s\": line %d: syntax error: unterminated string?\n",
			inputFileName, stringStart);

	*buffer = 0;
	return(buffer);
}


char *readLine(letter)

int letter;

{
	static char buffer[MAX_VALUE_LEN];
	char *ptr = buffer;

	while ((isspace(letter)) && ((letter = inputRaw()) > 0))
		;

	unput(letter);

	while ((*ptr = inputRaw()) > 0)
	{
		if (*ptr == '\n')
		{
			unput(*ptr);

			do
			{
				--ptr;
			}
			while ((isspace(*ptr)) && (ptr >= buffer));

			if (ptr >= buffer)
			{
				*(ptr + 1) = 0;
			}
			else
			{
				*buffer = 0;
			}

			return(buffer);
		}
		else
		{
			++ptr;
		}
	}

	fprintf(stderr, "file \"%s\": line %d: syntax error: line does not end in carriage return\n",
			inputFileName, inputLineCount);

	*buffer = 0;
	return(buffer);
}


int unput(c)

int c;

{
	extern char *yysptr;

	*yysptr++ = yytchar = c;
}


int inputRaw()

{
	yytchar = (yysptr > yysbuf) ? *--yysptr : getc(yyin);
	return((yytchar == EOF) ? 0 : yytchar);
}


int inputUpper()

{
	yytchar = (yysptr > yysbuf) ? *--yysptr : getc(yyin);
	return((yytchar == EOF) ? 0 : toupper(yytchar));
}



More information about the Comp.sys.sun mailing list