better error handling, simplified EOI handling with improved input module

This commit is contained in:
ceriel 1989-04-04 14:53:48 +00:00
parent 6877184666
commit 0995f7a809
3 changed files with 47 additions and 79 deletions

View file

@ -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);

View file

@ -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

View file

@ -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);