better error handling, simplified EOI handling with improved input module
This commit is contained in:
parent
6877184666
commit
0995f7a809
3 changed files with 47 additions and 79 deletions
|
@ -41,7 +41,6 @@ int ForeignFlag;
|
||||||
extern int cntlines;
|
extern int cntlines;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int eofseen;
|
|
||||||
extern char options[];
|
extern char options[];
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
|
@ -90,7 +89,7 @@ SkipComment()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (class(ch) == STNL) {
|
if (!(ch & 0200) && class(ch) == STNL) {
|
||||||
LineNumber++;
|
LineNumber++;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
cntlines++;
|
cntlines++;
|
||||||
|
@ -111,6 +110,7 @@ SkipComment()
|
||||||
}
|
}
|
||||||
else if (ch == EOI) {
|
else if (ch == EOI) {
|
||||||
lexerror("unterminated comment");
|
lexerror("unterminated comment");
|
||||||
|
PushBack();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LoadChar(ch);
|
LoadChar(ch);
|
||||||
|
@ -131,7 +131,7 @@ GetString(upto)
|
||||||
len = ISTRSIZE;
|
len = ISTRSIZE;
|
||||||
str->s_str = p = Malloc((unsigned int) ISTRSIZE);
|
str->s_str = p = Malloc((unsigned int) ISTRSIZE);
|
||||||
while (LoadChar(ch), ch != upto) {
|
while (LoadChar(ch), ch != upto) {
|
||||||
if (class(ch) == STNL) {
|
if (!(ch & 0200) && class(ch) == STNL) {
|
||||||
lexerror("newline in string");
|
lexerror("newline in string");
|
||||||
LineNumber++;
|
LineNumber++;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -169,17 +169,8 @@ getch()
|
||||||
{
|
{
|
||||||
register int ch;
|
register int ch;
|
||||||
|
|
||||||
for (;;) {
|
while (LoadChar(ch), (ch & 0200) && ch != EOI) {
|
||||||
LoadChar(ch);
|
error("non-ascii '\\%03o' read", ch & 0377);
|
||||||
if ((ch & 0200) && ch != EOI) {
|
|
||||||
error("non-ascii '\\%03o' read", ch & 0377);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (ch == EOI) {
|
|
||||||
eofseen = 1;
|
|
||||||
return '\n';
|
|
||||||
}
|
}
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
@ -188,7 +179,7 @@ CheckForLineDirective()
|
||||||
{
|
{
|
||||||
register int ch = getch();
|
register int ch = getch();
|
||||||
register int i = 0;
|
register int i = 0;
|
||||||
char buf[IDFSIZE + 2];
|
char buf[IDFSIZE];
|
||||||
register char *c = buf;
|
register char *c = buf;
|
||||||
|
|
||||||
|
|
||||||
|
@ -201,7 +192,7 @@ CheckForLineDirective()
|
||||||
* Do not skip newlines
|
* Do not skip newlines
|
||||||
*/
|
*/
|
||||||
ch = getch();
|
ch = getch();
|
||||||
if (class(ch) == STNL) {
|
if (class(ch) == STNL || class(ch) == STEOI) {
|
||||||
LineNumber++;
|
LineNumber++;
|
||||||
error(s_error);
|
error(s_error);
|
||||||
return;
|
return;
|
||||||
|
@ -211,12 +202,14 @@ CheckForLineDirective()
|
||||||
i = i*10 + (ch - '0');
|
i = i*10 + (ch - '0');
|
||||||
ch = getch();
|
ch = getch();
|
||||||
}
|
}
|
||||||
while (ch != '"' && class(ch) != STNL) ch = getch();
|
while (ch != '"' && class(ch) != STNL && class(ch) != STEOI)
|
||||||
|
ch = getch();
|
||||||
if (ch == '"') {
|
if (ch == '"') {
|
||||||
c = buf;
|
c = buf;
|
||||||
do {
|
do {
|
||||||
*c++ = ch = getch();
|
ch = getch();
|
||||||
if (class(ch) == STNL) {
|
if (c < &buf[IDFSIZE]) *c++ = ch;
|
||||||
|
if (class(ch) == STNL || class(ch) == STEOI) {
|
||||||
LineNumber++;
|
LineNumber++;
|
||||||
error(s_error);
|
error(s_error);
|
||||||
return;
|
return;
|
||||||
|
@ -225,28 +218,21 @@ CheckForLineDirective()
|
||||||
*--c = '\0';
|
*--c = '\0';
|
||||||
do {
|
do {
|
||||||
ch = getch();
|
ch = getch();
|
||||||
} while (class(ch) != STNL);
|
} while (class(ch) != STNL && class(ch) != STEOI);
|
||||||
/*
|
/*
|
||||||
* Remember the file name
|
* Remember the file name
|
||||||
*/
|
*/
|
||||||
if (!eofseen && strcmp(FileName,buf)) {
|
if (class(ch) == STNL && strcmp(FileName,buf)) {
|
||||||
FileName = Salloc(buf,(unsigned) strlen(buf) + 1);
|
FileName = Salloc(buf,(unsigned) strlen(buf) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (eofseen) {
|
if (class(ch) == STEOI) {
|
||||||
error(s_error);
|
error(s_error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LineNumber = i;
|
LineNumber = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
UnloadChar(ch)
|
|
||||||
{
|
|
||||||
if (ch == EOI) eofseen = 1;
|
|
||||||
else PushBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
LLlex()
|
LLlex()
|
||||||
{
|
{
|
||||||
|
@ -265,20 +251,8 @@ LLlex()
|
||||||
return tk->tk_symb;
|
return tk->tk_symb;
|
||||||
}
|
}
|
||||||
|
|
||||||
again1:
|
|
||||||
if (eofseen) {
|
|
||||||
eofseen = 0;
|
|
||||||
ch = EOI;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
again:
|
again:
|
||||||
LoadChar(ch);
|
ch = getch();
|
||||||
if ((ch & 0200) && ch != EOI) {
|
|
||||||
error("non-ascii '\\%03o' read", ch & 0377);
|
|
||||||
goto again;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tk->tk_lineno = LineNumber;
|
tk->tk_lineno = LineNumber;
|
||||||
|
|
||||||
switch (class(ch)) {
|
switch (class(ch)) {
|
||||||
|
@ -289,7 +263,7 @@ again:
|
||||||
cntlines++;
|
cntlines++;
|
||||||
#endif
|
#endif
|
||||||
CheckForLineDirective();
|
CheckForLineDirective();
|
||||||
goto again1;
|
goto again;
|
||||||
|
|
||||||
case STSKIP:
|
case STSKIP:
|
||||||
goto again;
|
goto again;
|
||||||
|
@ -308,7 +282,7 @@ again:
|
||||||
SkipComment();
|
SkipComment();
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
UnloadChar(nch);
|
PushBack();
|
||||||
}
|
}
|
||||||
if (ch == '&') return tk->tk_symb = AND;
|
if (ch == '&') return tk->tk_symb = AND;
|
||||||
if (ch == '~') return tk->tk_symb = NOT;
|
if (ch == '~') return tk->tk_symb = NOT;
|
||||||
|
@ -348,7 +322,7 @@ again:
|
||||||
default :
|
default :
|
||||||
crash("(LLlex, STCOMP)");
|
crash("(LLlex, STCOMP)");
|
||||||
}
|
}
|
||||||
UnloadChar(nch);
|
PushBack();
|
||||||
return tk->tk_symb = ch;
|
return tk->tk_symb = ch;
|
||||||
|
|
||||||
case STIDF:
|
case STIDF:
|
||||||
|
@ -364,7 +338,7 @@ again:
|
||||||
}
|
}
|
||||||
} while(in_idf(ch));
|
} while(in_idf(ch));
|
||||||
|
|
||||||
UnloadChar(ch);
|
PushBack();
|
||||||
*tag = '\0';
|
*tag = '\0';
|
||||||
if (*(tag - 1) == '_') {
|
if (*(tag - 1) == '_') {
|
||||||
lexerror("last character of an identifier may not be an underscore");
|
lexerror("last character of an identifier may not be an underscore");
|
||||||
|
@ -436,7 +410,7 @@ again:
|
||||||
else {
|
else {
|
||||||
state = End;
|
state = End;
|
||||||
if (ch == 'H') base = 16;
|
if (ch == 'H') base = 16;
|
||||||
else UnloadChar(ch);
|
else PushBack();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -462,7 +436,7 @@ again:
|
||||||
state = End;
|
state = End;
|
||||||
if (ch != 'H') {
|
if (ch != 'H') {
|
||||||
lexerror("H expected after hex number");
|
lexerror("H expected after hex number");
|
||||||
UnloadChar(ch);
|
PushBack();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -478,7 +452,7 @@ again:
|
||||||
state = Hex;
|
state = Hex;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
UnloadChar(ch);
|
PushBack();
|
||||||
ch = *--np;
|
ch = *--np;
|
||||||
*np++ = '\0';
|
*np++ = '\0';
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
@ -582,7 +556,7 @@ lexwarning(W_ORDINARY, "overflow in constant");
|
||||||
LoadChar(ch);
|
LoadChar(ch);
|
||||||
if (!(ch == '+' || ch == '-' || is_dig(ch)))
|
if (!(ch == '+' || ch == '-' || is_dig(ch)))
|
||||||
goto noscale;
|
goto noscale;
|
||||||
UnloadChar(ch);
|
PushBack();
|
||||||
}
|
}
|
||||||
if (np < &buf[NUMSIZE]) *np++ = 'E';
|
if (np < &buf[NUMSIZE]) *np++ = 'E';
|
||||||
LoadChar(ch);
|
LoadChar(ch);
|
||||||
|
@ -605,7 +579,7 @@ lexwarning(W_ORDINARY, "overflow in constant");
|
||||||
|
|
||||||
noscale:
|
noscale:
|
||||||
*np++ = '\0';
|
*np++ = '\0';
|
||||||
UnloadChar(ch);
|
PushBack();
|
||||||
|
|
||||||
if (np >= &buf[NUMSIZE]) {
|
if (np >= &buf[NUMSIZE]) {
|
||||||
tk->TOK_REL = Salloc("0.0", 5);
|
tk->TOK_REL = Salloc("0.0", 5);
|
||||||
|
|
|
@ -166,13 +166,13 @@ $(CURRDIR)main: $(OBJ) $(CURRDIR)Makefile
|
||||||
$(CC) $(LDFLAGS) $(OBJ) $(OLIBS) -o $(CURRDIR)main
|
$(CC) $(LDFLAGS) $(OBJ) $(OLIBS) -o $(CURRDIR)main
|
||||||
-size $(CURRDIR)main
|
-size $(CURRDIR)main
|
||||||
|
|
||||||
$(CURRDIR)omain: $(OBJ) $(CURRDIR)Makefile
|
$(CURRDIR)omain: $(OBJ) #$(CURRDIR)Makefile
|
||||||
$(CC) $(LDFLAGS) $(OBJ) $(OLIBS) -o $(CURRDIR)omain
|
#$(CC) $(LDFLAGS) $(OBJ) $(OLIBS) -o $(CURRDIR)omain
|
||||||
size $(CURRDIR)omain
|
#size $(CURRDIR)omain
|
||||||
|
|
||||||
$(CURRDIR)cemain: $(OBJ) $(CURRDIR)Makefile
|
$(CURRDIR)cemain: $(OBJ) #$(CURRDIR)Makefile
|
||||||
$(CC) $(LDFLAGS) $(OBJ) $(OLIBS) -o $(CURRDIR)cemain
|
#$(CC) $(LDFLAGS) $(OBJ) $(OLIBS) -o $(CURRDIR)cemain
|
||||||
size $(CURRDIR)cemain
|
#size $(CURRDIR)cemain
|
||||||
|
|
||||||
|
|
||||||
#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
|
#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
|
||||||
|
|
|
@ -120,8 +120,10 @@ define(id, scope, kind)
|
||||||
) {
|
) {
|
||||||
switch(df->df_kind) {
|
switch(df->df_kind) {
|
||||||
case D_INUSE:
|
case D_INUSE:
|
||||||
if (kind != D_INUSE) {
|
if (kind != D_INUSE && kind != D_ERROR) {
|
||||||
error("identifier \"%s\" already used; may not be redefined in this scope", df->df_idf->id_text);
|
error("identifier \"%s\" already used; may not be redefined in this scope", df->df_idf->id_text);
|
||||||
|
df->df_kind = D_ERROR;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return df;
|
return df;
|
||||||
|
|
||||||
|
@ -158,12 +160,9 @@ define(id, scope, kind)
|
||||||
break;
|
break;
|
||||||
case D_FORWTYPE:
|
case D_FORWTYPE:
|
||||||
if (kind & (D_FORWTYPE|D_TYPE)) return df;
|
if (kind & (D_FORWTYPE|D_TYPE)) return df;
|
||||||
else {
|
error("identifier \"%s\" must be a type", id->id_text);
|
||||||
error("identifier \"%s\" must be a type",
|
df->df_kind = D_ERROR;
|
||||||
id->id_text);
|
break;
|
||||||
}
|
|
||||||
return df;
|
|
||||||
|
|
||||||
case D_FORWARD:
|
case D_FORWARD:
|
||||||
/* A forward reference, for which we may now have
|
/* A forward reference, for which we may now have
|
||||||
found a definition.
|
found a definition.
|
||||||
|
@ -171,29 +170,24 @@ define(id, scope, kind)
|
||||||
if (! (kind & (D_FORWARD | D_FORWMODULE))) {
|
if (! (kind & (D_FORWARD | D_FORWMODULE))) {
|
||||||
FreeNode(df->for_node);
|
FreeNode(df->for_node);
|
||||||
}
|
}
|
||||||
|
df->df_kind = D_ERROR; /* avoiding error message */
|
||||||
/* Fall through */
|
break;
|
||||||
|
|
||||||
case D_ERROR:
|
|
||||||
/* A definition generated by the compiler, because
|
|
||||||
it found an error. Maybe, the user gives a
|
|
||||||
definition after all.
|
|
||||||
*/
|
|
||||||
if (kind & (D_TYPE|D_PROCEDURE|D_CONST)) {
|
|
||||||
df->df_flags = D_DEFINED;
|
|
||||||
}
|
|
||||||
df->df_kind = kind;
|
|
||||||
return df;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kind != D_ERROR) {
|
if (kind != D_ERROR && df->df_kind != D_ERROR) {
|
||||||
/* Avoid spurious error messages
|
/* Avoid spurious error messages
|
||||||
*/
|
*/
|
||||||
error("identifier \"%s\" already declared",
|
error("identifier \"%s\" already declared",
|
||||||
id->id_text);
|
id->id_text);
|
||||||
}
|
}
|
||||||
|
if (df->df_scope == scope || df->df_kind == D_ERROR) {
|
||||||
|
df->df_kind = kind;
|
||||||
|
if (kind & (D_TYPE|D_PROCEDURE|D_CONST)) {
|
||||||
|
df->df_flags = D_DEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
return df;
|
return df;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return MkDef(id, scope, kind);
|
return MkDef(id, scope, kind);
|
||||||
|
|
Loading…
Reference in a new issue