better (more restrained) error reporting
This commit is contained in:
parent
2fb6605800
commit
a817264e90
12 changed files with 46 additions and 112 deletions
|
@ -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
|
||||||
|
|
|
@ -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 '>':
|
||||||
|
|
|
@ -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" */
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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... */
|
||||||
')'
|
')'
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;) :
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue