Commit 432d6fc4 by alokp@chromium.org

Introduced preprocessing token types. This fixes a bug where invalid tokens…

Introduced preprocessing token types. This fixes a bug where invalid tokens inside excluded conditional block may report diagnostics. Now we let the invalid tokens to bubble through the preprocessor so that they have chance to be skipped. Review URL: https://codereview.appspot.com/6356045 git-svn-id: https://angleproject.googlecode.com/svn/trunk@1169 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent d39ec4c1
...@@ -221,7 +221,7 @@ void DirectiveParser::lex(Token* token) ...@@ -221,7 +221,7 @@ void DirectiveParser::lex(Token* token)
{ {
mTokenizer->lex(token); mTokenizer->lex(token);
if (token->type == '#') if (token->type == Token::PP_HASH)
{ {
parseDirective(token); parseDirective(token);
} }
...@@ -242,7 +242,7 @@ void DirectiveParser::lex(Token* token) ...@@ -242,7 +242,7 @@ void DirectiveParser::lex(Token* token)
void DirectiveParser::parseDirective(Token* token) void DirectiveParser::parseDirective(Token* token)
{ {
assert(token->type == '#'); assert(token->type == Token::PP_HASH);
mTokenizer->lex(token); mTokenizer->lex(token);
DirectiveType directive = getDirective(token); DirectiveType directive = getDirective(token);
......
...@@ -6,8 +6,10 @@ ...@@ -6,8 +6,10 @@
#include "Preprocessor.h" #include "Preprocessor.h"
#include <cassert>
#include <sstream> #include <sstream>
#include "Diagnostics.h"
#include "DirectiveParser.h" #include "DirectiveParser.h"
#include "Macro.h" #include "Macro.h"
#include "MacroExpander.h" #include "MacroExpander.h"
...@@ -19,16 +21,18 @@ namespace pp ...@@ -19,16 +21,18 @@ namespace pp
struct PreprocessorImpl struct PreprocessorImpl
{ {
Diagnostics* diagnostics;
MacroSet macroSet; MacroSet macroSet;
Tokenizer tokenizer; Tokenizer tokenizer;
DirectiveParser directiveParser; DirectiveParser directiveParser;
MacroExpander macroExpander; MacroExpander macroExpander;
PreprocessorImpl(Diagnostics* diagnostics, PreprocessorImpl(Diagnostics* diag,
DirectiveHandler* directiveHandler) : DirectiveHandler* directiveHandler) :
tokenizer(diagnostics), diagnostics(diag),
directiveParser(&tokenizer, &macroSet, diagnostics, directiveHandler), tokenizer(diag),
macroExpander(&directiveParser, &macroSet, diagnostics) directiveParser(&tokenizer, &macroSet, diag, directiveHandler),
macroExpander(&directiveParser, &macroSet, diag)
{ {
} }
}; };
...@@ -79,7 +83,31 @@ void Preprocessor::predefineMacro(const char* name, int value) ...@@ -79,7 +83,31 @@ void Preprocessor::predefineMacro(const char* name, int value)
void Preprocessor::lex(Token* token) void Preprocessor::lex(Token* token)
{ {
mImpl->macroExpander.lex(token); bool validToken = false;
while (!validToken)
{
mImpl->macroExpander.lex(token);
switch (token->type)
{
// We should not be returning internal preprocessing tokens.
// Convert preprocessing tokens to compiler tokens or report
// diagnostics.
case Token::PP_HASH:
assert(false);
break;
case Token::PP_NUMBER:
mImpl->diagnostics->report(Diagnostics::INVALID_NUMBER,
token->location, token->value);
break;
case Token::PP_OTHER:
mImpl->diagnostics->report(Diagnostics::INVALID_CHARACTER,
token->location, token->value);
break;
default:
validToken = true;
break;
}
}
} }
} // namespace pp } // namespace pp
......
...@@ -46,7 +46,14 @@ struct Token ...@@ -46,7 +46,14 @@ struct Token
OP_RIGHT_ASSIGN, OP_RIGHT_ASSIGN,
OP_AND_ASSIGN, OP_AND_ASSIGN,
OP_XOR_ASSIGN, OP_XOR_ASSIGN,
OP_OR_ASSIGN OP_OR_ASSIGN,
// Preprocessing token types.
// These types are used by the preprocessor internally.
// Preprocessor clients must not depend or check for them.
PP_HASH,
PP_NUMBER,
PP_OTHER
}; };
enum Flags enum Flags
{ {
......
...@@ -898,14 +898,8 @@ case 7: ...@@ -898,14 +898,8 @@ case 7:
YY_RULE_SETUP YY_RULE_SETUP
{ {
// # is only valid at start of line for preprocessor directives. // # is only valid at start of line for preprocessor directives.
if (yyextra->lineStart) { yylval->assign(1, yytext[0]);
yylval->assign(1, yytext[0]); return yyextra->lineStart ? pp::Token::PP_HASH : pp::Token::PP_OTHER;
return yytext[0];
} else {
yyextra->diagnostics->report(pp::Diagnostics::INVALID_CHARACTER,
pp::SourceLocation(yyfileno, yylineno),
std::string(yytext, yyleng));
}
} }
YY_BREAK YY_BREAK
case 8: case 8:
...@@ -934,9 +928,8 @@ YY_RULE_SETUP ...@@ -934,9 +928,8 @@ YY_RULE_SETUP
case 11: case 11:
YY_RULE_SETUP YY_RULE_SETUP
{ {
yyextra->diagnostics->report(pp::Diagnostics::INVALID_NUMBER, yylval->assign(yytext, yyleng);
pp::SourceLocation(yyfileno, yylineno), return pp::Token::PP_NUMBER;
std::string(yytext, yyleng));
} }
YY_BREAK YY_BREAK
case 12: case 12:
...@@ -1109,9 +1102,8 @@ YY_RULE_SETUP ...@@ -1109,9 +1102,8 @@ YY_RULE_SETUP
case 36: case 36:
YY_RULE_SETUP YY_RULE_SETUP
{ {
yyextra->diagnostics->report(pp::Diagnostics::INVALID_CHARACTER, yylval->assign(1, yytext[0]);
pp::SourceLocation(yyfileno, yylineno), return pp::Token::PP_OTHER;
std::string(yytext, yyleng));
} }
YY_BREAK YY_BREAK
case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(INITIAL):
......
...@@ -100,14 +100,8 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") ...@@ -100,14 +100,8 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
# { # {
// # is only valid at start of line for preprocessor directives. // # is only valid at start of line for preprocessor directives.
if (yyextra->lineStart) { yylval->assign(1, yytext[0]);
yylval->assign(1, yytext[0]); return yyextra->lineStart ? pp::Token::PP_HASH : pp::Token::PP_OTHER;
return yytext[0];
} else {
yyextra->diagnostics->report(pp::Diagnostics::INVALID_CHARACTER,
pp::SourceLocation(yyfileno, yylineno),
std::string(yytext, yyleng));
}
} }
{IDENTIFIER} { {IDENTIFIER} {
...@@ -128,9 +122,8 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") ...@@ -128,9 +122,8 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
/* Anything that starts with a {DIGIT} or .{DIGIT} must be a number. */ /* Anything that starts with a {DIGIT} or .{DIGIT} must be a number. */
/* Rule to catch all invalid integers and floats. */ /* Rule to catch all invalid integers and floats. */
({DIGIT}+[_a-zA-Z0-9.]*)|("."{DIGIT}+[_a-zA-Z0-9.]*) { ({DIGIT}+[_a-zA-Z0-9.]*)|("."{DIGIT}+[_a-zA-Z0-9.]*) {
yyextra->diagnostics->report(pp::Diagnostics::INVALID_NUMBER, yylval->assign(yytext, yyleng);
pp::SourceLocation(yyfileno, yylineno), return pp::Token::PP_NUMBER;
std::string(yytext, yyleng));
} }
"++" { "++" {
...@@ -232,9 +225,8 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") ...@@ -232,9 +225,8 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
} }
. { . {
yyextra->diagnostics->report(pp::Diagnostics::INVALID_CHARACTER, yylval->assign(1, yytext[0]);
pp::SourceLocation(yyfileno, yylineno), return pp::Token::PP_OTHER;
std::string(yytext, yyleng));
} }
<*><<EOF>> { <*><<EOF>> {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment