Skip to content

Commit

Permalink
Merge pull request #4094 from WalterBright/lexer-errors
Browse files Browse the repository at this point in the history
refactor so lexer+parser keeps track of errors
  • Loading branch information
9rnsr committed Oct 29, 2014
2 parents 9d1d024 + 2a11bef commit 99bf4ae
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 18 deletions.
7 changes: 5 additions & 2 deletions src/attrib.c
Expand Up @@ -1317,15 +1317,18 @@ void CompileDeclaration::compileIt(Scope *sc)
else
{
se = se->toUTF8(sc);
unsigned errors = global.errors;
Parser p(loc, sc->module, (utf8_t *)se->string, se->len, 0);
p.nextToken();

unsigned errors = global.errors;
decl = p.parseDeclDefs(0);
if (p.token.value != TOKeof)
exp->error("incomplete mixin declaration (%s)", se->toChars());
if (global.errors != errors)
if (p.errors)
{
assert(global.errors != errors);
decl = NULL;
}
}
}
}
Expand Down
7 changes: 5 additions & 2 deletions src/expression.c
Expand Up @@ -6840,13 +6840,16 @@ Expression *CompileExp::semantic(Scope *sc)
return new ErrorExp();
}
se = se->toUTF8(sc);
unsigned errors = global.errors;
Parser p(loc, sc->module, (utf8_t *)se->string, se->len, 0);
p.nextToken();
//printf("p.loc.linnum = %d\n", p.loc.linnum);
unsigned errors = global.errors;
Expression *e = p.parseExpression();
if (global.errors != errors)
if (p.errors)
{
assert(global.errors != errors); // should have caught all these cases
return new ErrorExp();
}
if (p.token.value != TOKeof)
{ error("incomplete mixin expression (%s)", se->toChars());
return new ErrorExp();
Expand Down
5 changes: 5 additions & 0 deletions src/lexer.c
Expand Up @@ -259,6 +259,7 @@ Lexer::Lexer(Module *mod,
this->doDocComment = doDocComment;
this->anyToken = 0;
this->commentToken = commentToken;
this->errors = false;
//initKeywords();

/* If first line starts with '#!', ignore the line
Expand Down Expand Up @@ -319,6 +320,7 @@ void Lexer::error(const char *format, ...)
va_start(ap, format);
::verror(token.loc, format, ap);
va_end(ap);
errors = true;
}

void Lexer::error(Loc loc, const char *format, ...)
Expand All @@ -327,6 +329,7 @@ void Lexer::error(Loc loc, const char *format, ...)
va_start(ap, format);
::verror(loc, format, ap);
va_end(ap);
errors = true;
}

void Lexer::deprecation(const char *format, ...)
Expand All @@ -335,6 +338,8 @@ void Lexer::deprecation(const char *format, ...)
va_start(ap, format);
::vdeprecation(token.loc, format, ap);
va_end(ap);
if (global.params.useDeprecated == 0)
errors = true;
}

TOK Lexer::nextToken()
Expand Down
1 change: 1 addition & 0 deletions src/lexer.h
Expand Up @@ -247,6 +247,7 @@ class Lexer
int doDocComment; // collect doc comment information
int anyToken; // !=0 means seen at least one token
int commentToken; // !=0 means comments are TOKcomment's
bool errors; // errors occurred during lexing or parsing

Lexer(Module *mod,
const utf8_t *base, size_t begoffset, size_t endoffset,
Expand Down
1 change: 1 addition & 0 deletions src/mars.c
Expand Up @@ -348,6 +348,7 @@ void genCmain(Scope *sc)
p.nextToken();
m->members = p.parseModule();
assert(p.token.value == TOKeof);
assert(!p.errors); // shouldn't have failed to parse it

bool v = global.params.verbose;
global.params.verbose = false;
Expand Down
2 changes: 2 additions & 0 deletions src/module.c
Expand Up @@ -516,6 +516,8 @@ void Module::parse()
members = p.parseModule();
md = p.md;
numlines = p.scanloc.linnum;
if (p.errors)
++global.errors;
}

if (srcfile->ref == 0)
Expand Down
24 changes: 12 additions & 12 deletions src/parse.c
Expand Up @@ -1480,7 +1480,7 @@ Dsymbol *Parser::parseCtor(PrefixAttributes *pAttrs)

stc = parsePostfix(stc, &udas);
if (stc & STCstatic)
::error(loc, "postblit cannot be static");
error(loc, "postblit cannot be static");

PostBlitDeclaration *f = new PostBlitDeclaration(loc, Loc(), stc, Id::_postblit);
if (pAttrs)
Expand Down Expand Up @@ -1513,14 +1513,14 @@ Dsymbol *Parser::parseCtor(PrefixAttributes *pAttrs)
if (varargs != 0 || Parameter::dim(parameters) != 0)
{
if (stc & STCstatic)
::error(loc, "constructor cannot be static");
error(loc, "constructor cannot be static");
}
else if (StorageClass ss = stc & (STCshared | STCstatic)) // this()
{
if (ss == STCstatic)
::error(loc, "use 'static this()' to declare a static constructor");
error(loc, "use 'static this()' to declare a static constructor");
else if (ss == (STCshared | STCstatic))
::error(loc, "use 'shared static this()' to declare a shared static constructor");
error(loc, "use 'shared static this()' to declare a shared static constructor");
}

Expression *constraint = tpl ? parseConstraint() : NULL;
Expand Down Expand Up @@ -1571,9 +1571,9 @@ Dsymbol *Parser::parseDtor(PrefixAttributes *pAttrs)
if (StorageClass ss = stc & (STCshared | STCstatic))
{
if (ss == STCstatic)
::error(loc, "use 'static ~this()' to declare a static destructor");
error(loc, "use 'static ~this()' to declare a static destructor");
else if (ss == (STCshared | STCstatic))
::error(loc, "use 'shared static ~this()' to declare a shared static destructor");
error(loc, "use 'shared static ~this()' to declare a shared static destructor");
}

DtorDeclaration *f = new DtorDeclaration(loc, Loc(), stc, Id::dtor);
Expand Down Expand Up @@ -1608,7 +1608,7 @@ Dsymbol *Parser::parseStaticCtor(PrefixAttributes *pAttrs)

stc = parsePostfix(stc & ~STC_TYPECTOR, NULL) | stc;
if (stc & STCshared)
::error(loc, "use 'shared static this()' to declare a shared static constructor");
error(loc, "use 'shared static this()' to declare a shared static constructor");
else if (stc & STCstatic)
appendStorageClass(stc, STCstatic); // complaint for the redundancy
else if (StorageClass modStc = stc & STC_TYPECTOR)
Expand All @@ -1617,7 +1617,7 @@ Dsymbol *Parser::parseStaticCtor(PrefixAttributes *pAttrs)
StorageClassDeclaration::stcToCBuffer(&buf, modStc);
if (buf.data[buf.offset - 1] == ' ')
buf.data[buf.offset - 1] = '\0';
::error(loc, "static constructor cannot be %s", buf.peekString());
error(loc, "static constructor cannot be %s", buf.peekString());
}
stc &= ~(STCstatic | STC_TYPECTOR);

Expand Down Expand Up @@ -1648,7 +1648,7 @@ Dsymbol *Parser::parseStaticDtor(PrefixAttributes *pAttrs)

stc = parsePostfix(stc & ~STC_TYPECTOR, &udas) | stc;
if (stc & STCshared)
::error(loc, "use 'shared static ~this()' to declare a shared static destructor");
error(loc, "use 'shared static ~this()' to declare a shared static destructor");
else if (stc & STCstatic)
appendStorageClass(stc, STCstatic); // complaint for the redundancy
else if (StorageClass modStc = stc & STC_TYPECTOR)
Expand All @@ -1657,7 +1657,7 @@ Dsymbol *Parser::parseStaticDtor(PrefixAttributes *pAttrs)
StorageClassDeclaration::stcToCBuffer(&buf, modStc);
if (buf.data[buf.offset - 1] == ' ')
buf.data[buf.offset - 1] = '\0';
::error(loc, "static destructor cannot be %s", buf.peekString());
error(loc, "static destructor cannot be %s", buf.peekString());
}
stc &= ~(STCstatic | STC_TYPECTOR);

Expand Down Expand Up @@ -1701,7 +1701,7 @@ Dsymbol *Parser::parseSharedStaticCtor(PrefixAttributes *pAttrs)
StorageClassDeclaration::stcToCBuffer(&buf, modStc);
if (buf.data[buf.offset - 1] == ' ')
buf.data[buf.offset - 1] = '\0';
::error(loc, "shared static constructor cannot be %s", buf.peekString());
error(loc, "shared static constructor cannot be %s", buf.peekString());
}
stc &= ~(STCstatic | STC_TYPECTOR);

Expand Down Expand Up @@ -1740,7 +1740,7 @@ Dsymbol *Parser::parseSharedStaticDtor(PrefixAttributes *pAttrs)
StorageClassDeclaration::stcToCBuffer(&buf, modStc);
if (buf.data[buf.offset - 1] == ' ')
buf.data[buf.offset - 1] = '\0';
::error(loc, "shared static destructor cannot be %s", buf.peekString());
error(loc, "shared static destructor cannot be %s", buf.peekString());
}
stc &= ~(STCstatic | STC_TYPECTOR);

Expand Down
7 changes: 5 additions & 2 deletions src/statement.c
Expand Up @@ -933,15 +933,18 @@ Statements *CompileStatement::flatten(Scope *sc)
else
{
se = se->toUTF8(sc);
unsigned errors = global.errors;
Parser p(loc, sc->module, (utf8_t *)se->string, se->len, 0);
p.nextToken();

while (p.token.value != TOKeof)
{
unsigned errors = global.errors;
Statement *s = p.parseStatement(PSsemi | PScurlyscope);
if (!s || global.errors != errors)
if (!s || p.errors)
{
assert(!p.errors || global.errors != errors); // make sure we caught all the cases
goto Lerror;
}
a->push(s);
}
return a;
Expand Down

0 comments on commit 99bf4ae

Please sign in to comment.