better (more restrained) error reporting

This commit is contained in:
dick 1989-10-30 16:19:35 +00:00
parent 2fb6605800
commit a817264e90
12 changed files with 46 additions and 112 deletions

View file

@ -8,8 +8,9 @@
!File: errout.h !File: errout.h
#define ERROUT STDERR /* file pointer for writing messages */ #define ERROUT STDERR /* file pointer for writing messages */
#define MAXERR_LINE 5 /* maximum number of error messages given #define ERR_SHADOW 5 /* a syntax error overshadows error messages
on the same input line. */ until ERR_SHADOW symbols have been
accepted without syntax error */
!File: idfsize.h !File: idfsize.h

View file

@ -25,6 +25,9 @@
/* Data about the token yielded */ /* Data about the token yielded */
struct token dot, ahead, aside; struct token dot, ahead, aside;
int token_nmb = 0; /* number of the ahead token */
int tk_nmb_at_last_syn_err = -5/*ERR_SHADOW*/;
/* token number at last syntax error */
#ifndef NOPP #ifndef NOPP
int ReplaceMacros = 1; /* replacing macros */ int ReplaceMacros = 1; /* replacing macros */
@ -105,6 +108,8 @@ GetToken(ptok)
char buf[(IDFSIZE > NUMSIZE ? IDFSIZE : NUMSIZE) + 1]; char buf[(IDFSIZE > NUMSIZE ? IDFSIZE : NUMSIZE) + 1];
register int ch, nch; register int ch, nch;
token_nmb++;
if (File_Inserted) { if (File_Inserted) {
File_Inserted = 0; File_Inserted = 0;
goto firstline; goto firstline;
@ -219,37 +224,6 @@ firstline:
case '=': case '=':
if (nch == '=') if (nch == '=')
return ptok->tk_symb = EQUAL; return ptok->tk_symb = EQUAL;
/* The following piece of code tries to recognise
old-fashioned assignment operators `=op'
*/
switch (nch) {
case '+':
return ptok->tk_symb = PLUSAB;
case '-':
return ptok->tk_symb = MINAB;
case '*':
return ptok->tk_symb = TIMESAB;
case '/':
return ptok->tk_symb = DIVAB;
case '%':
return ptok->tk_symb = MODAB;
case '>':
case '<':
LoadChar(ch);
if (ch != nch) {
PushBack();
lexerror("illegal operator '=%c%c'",
nch, ch);
}
return ptok->tk_symb =
nch == '<' ? LEFTAB : RIGHTAB;
case '&':
return ptok->tk_symb = ANDAB;
case '^':
return ptok->tk_symb = XORAB;
case '|':
return ptok->tk_symb = ORAB;
}
PushBack(); PushBack();
return ptok->tk_symb = ch; return ptok->tk_symb = ch;
case '>': case '>':

View file

@ -48,6 +48,8 @@ struct token {
#endif NOFLOAT #endif NOFLOAT
extern struct token dot, ahead, aside; extern struct token dot, ahead, aside;
extern int token_nmb; /* number of the ahead token */
extern int tk_nmb_at_last_syn_err; /* token number at last syntax error */
#ifndef NOPP #ifndef NOPP
extern int ReplaceMacros; /* "LLlex.c" */ extern int ReplaceMacros; /* "LLlex.c" */

View file

@ -20,11 +20,13 @@ LLmessage(tk) {
error("end of file expected"); error("end of file expected");
} }
else if (tk) { else if (tk) {
error("%s missing", symbol2str(tk)); error("%s missing before %s", symbol2str(tk), symbol2str(DOT));
insert_token(tk); insert_token(tk);
} }
else else {
error("%s deleted", symbol2str(DOT)); error("%s deleted", symbol2str(DOT));
}
tk_nmb_at_last_syn_err = token_nmb;
} }
insert_token(tk) insert_token(tk)

View file

@ -8,8 +8,9 @@
!File: errout.h !File: errout.h
#define ERROUT STDERR /* file pointer for writing messages */ #define ERROUT STDERR /* file pointer for writing messages */
#define MAXERR_LINE 5 /* maximum number of error messages given #define ERR_SHADOW 5 /* a syntax error overshadows error messages
on the same input line. */ until ERR_SHADOW symbols have been
accepted without syntax error */
!File: idfsize.h !File: idfsize.h

View file

@ -135,9 +135,6 @@ SRC = $(CSRC) $(LCSRC) $(GCSRC)
LINT = /usr/bin/lint LINT = /usr/bin/lint
LINTFLAGS = LINTFLAGS =
MYLINT = ../lpass2/lint
MYLINTFLAGS = -xh
#EXCLEXCLEXCLEXCL #EXCLEXCLEXCLEXCL
.SUFFIXES: .str .h .SUFFIXES: .str .h
@ -188,11 +185,7 @@ clean:
(cd .. ; rm -rf Xsrc) (cd .. ; rm -rf Xsrc)
lint: Cfiles lint: Cfiles
sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make "EMHOME="$(EMHOME) Xlint ; else sh Resolve Xlint ; fi' sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make "EMHOME="$(EMHOME) LINT=$(LINT) Xlint ; else sh Resolve Xlint ; fi'
@rm -f nmclash.o a.out
mylint: Cfiles
sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make "EMHOME="$(EMHOME) Xmylint ; else sh Resolve Xmylint ; fi'
@rm -f nmclash.o a.out @rm -f nmclash.o a.out
longnames: $(SRC) $(HFILES) longnames: $(SRC) $(HFILES)
@ -274,8 +267,6 @@ $(CURRDIR)lnt: $(OBJ) $(CURRDIR)Makefile
Xlint: $(SRC) Xlint: $(SRC)
$(LINT) $(CDEFS) $(LINTFLAGS) $(SRC) $(LINT) $(CDEFS) $(LINTFLAGS) $(SRC)
Xmylint: $(SRC)
$(MYLINT) $(CDEFS) $(MYLINTFLAGS) $(SRC)
#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO #AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
main.o: LLlex.h main.o: LLlex.h

View file

@ -8,8 +8,9 @@
!File: errout.h !File: errout.h
#define ERROUT STDERR /* file pointer for writing messages */ #define ERROUT STDERR /* file pointer for writing messages */
#define MAXERR_LINE 5 /* maximum number of error messages given #define ERR_SHADOW 5 /* a syntax error overshadows error messages
on the same input line. */ until ERR_SHADOW symbols have been
accepted without syntax error */
!File: idfsize.h !File: idfsize.h

View file

@ -77,15 +77,19 @@ ch7bin(expp, oper, expr)
#endif NOROPTION #endif NOROPTION
ch7mon('*', expp); ch7mon('*', expp);
} }
if ((*expp)->ex_type->tp_fund != FUNCTION) { switch ((*expp)->ex_type->tp_fund) {
expr_error(*expp, "call of non-function (%s)", case FUNCTION:
symbol2str((*expp)->ex_type->tp_fund));
/* leave the expression; it may still serve */
free_expression(expr); /* there go the parameters */
}
else
*expp = new_oper((*expp)->ex_type->tp_up, *expp = new_oper((*expp)->ex_type->tp_up,
*expp, '(', expr); *expp, '(', expr);
break;
default: /* uncallable */
expr_error(*expp, "calling an object of type %s",
symbol2str((*expp)->ex_type->tp_fund));
case ERRONEOUS: /* uncallable but no message */
/* leave the expression; it may still serve */
free_expression(expr); /* there go the parameters */
break;
}
(*expp)->ex_flags |= EX_SIDEEFFECTS; (*expp)->ex_flags |= EX_SIDEEFFECTS;
break; break;

View file

@ -196,15 +196,7 @@ initializer(struct idf *idf; int sc;)
if (level == L_FORMAL2) if (level == L_FORMAL2)
warning("illegal initialization of formal parameter (ignored)"); warning("illegal initialization of formal parameter (ignored)");
} }
[ '=' /* used to be optional because of V6 */
'='
|
empty
{warning("old-fashioned initialization, insert =");}
/* This causes trouble at declarator and at
external_definition, q.v.
*/
]
{ {
#ifdef LINT #ifdef LINT
lint_statement(); lint_statement();
@ -247,10 +239,7 @@ declarator(register struct declarator *dc;)
} }
: :
primary_declarator(dc) primary_declarator(dc)
[%while(1) /* int i (M + 2) / 4; [
is a function, not an
old-fashioned initialization.
*/
'(' '('
formal_list(&fm) ? /* semantic check later... */ formal_list(&fm) ? /* semantic check later... */
')' ')'

View file

@ -236,17 +236,19 @@ _error(class, fn, ln, ap)
unsigned int ln; unsigned int ln;
va_list ap; va_list ap;
{ {
/* _error attempts to limit the number of error messages
for a given line to MAXERR_LINE.
*/
#ifndef LINT
static char *last_fn = 0;
static unsigned int last_ln = 0;
static int e_seen = 0;
#endif LINT
char *remark; char *remark;
char *fmt = va_arg(ap, char *); char *fmt = va_arg(ap, char *);
/* check visibility of message */
switch (class) {
case WARNING:
case ERROR:
if (token_nmb < tk_nmb_at_last_syn_err + ERR_SHADOW)
/* warning or error message overshadowed */
return;
break;
}
/* Since name and number are gathered from different places /* Since name and number are gathered from different places
depending on the class, we first collect the relevant depending on the class, we first collect the relevant
values and then decide what to print. values and then decide what to print.
@ -292,25 +294,6 @@ _error(class, fn, ln, ap)
/*NOTREACHED*/; /*NOTREACHED*/;
} }
#ifndef LINT
if (ln == last_ln && fn && last_fn && strcmp(fn, last_fn) == 0) {
/* we've seen this place before */
e_seen++;
if (e_seen == MAXERR_LINE)
fmt = "etc ...";
else
if (e_seen > MAXERR_LINE)
/* and too often, I'd say ! */
return;
}
else {
/* brand new place */
last_fn = fn;
last_ln = ln;
e_seen = 0;
}
#endif LINT
#ifdef LINT #ifdef LINT
if ( /* there is a file name */ if ( /* there is a file name */
fn fn

View file

@ -307,16 +307,6 @@ asgnop(register int *oper;):
'^' '=' {*oper = XORAB;} '^' '=' {*oper = XORAB;}
| |
'|' '=' {*oper = ORAB;} '|' '=' {*oper = ORAB;}
|
[ PLUSAB | MINAB | TIMESAB | DIVAB | MODAB |
LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ]
{
char *symbol2str();
warning("old-fashioned assignment operator, use %s",
symbol2str(DOT));
*oper = DOT;
}
; ;
constant(struct expr **expp;) : constant(struct expr **expp;) :

View file

@ -130,11 +130,7 @@ external_definition
lint_ext_def(Dc.dc_idf, Ds.ds_sc); lint_ext_def(Dc.dc_idf, Ds.ds_sc);
#endif LINT #endif LINT
} }
[%if (Dc.dc_idf->id_def->df_type->tp_fund == FUNCTION) [
/* int i (1) {2, 3}
is a function, not an old-fashioned
initialization.
*/
function(&Ds, &Dc) function(&Ds, &Dc)
| |
non_function(&Ds, &Dc) non_function(&Ds, &Dc)