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