Commit 78a35198 by alokp@chromium.org

Added a catch-rule for invalid numbers.

Note that we do not need such a rule for identifiers because they will always be either terminated by a space, a punctuator, or an invalid character. Space and punctuator are both valid cases. The invalid character will be caught by another rule specifically for invalid characters. I will cover this case when I add tests for valid character set. Review URL: https://codereview.appspot.com/5978048 git-svn-id: https://angleproject.googlecode.com/svn/trunk@1047 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent aeba7b89
...@@ -17,6 +17,13 @@ struct Token ...@@ -17,6 +17,13 @@ struct Token
{ {
enum Type enum Type
{ {
// Token IDs for error conditions are negative.
INVALID_CHARACTER = -1,
INVALID_NUMBER = -2,
// Indicates EOF.
LAST = 0,
IDENTIFIER = 258, IDENTIFIER = 258,
CONST_INT, CONST_INT,
......
...@@ -77,6 +77,13 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") ...@@ -77,6 +77,13 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
return pp::Token::CONST_FLOAT; return pp::Token::CONST_FLOAT;
} }
/* Anything that starts with a {DIGIT} or .{DIGIT} must be a number. */
/* Rule to catch all invalid integers and floats. */
({DIGIT}+[_a-zA-Z0-9.]*)|("."{DIGIT}+[_a-zA-Z0-9.]*) {
yylval->assign(yytext, yyleng);
return pp::Token::INVALID_NUMBER;
}
"++" { return pp::Token::OP_INC; } "++" { return pp::Token::OP_INC; }
"--" { return pp::Token::OP_DEC; } "--" { return pp::Token::OP_DEC; }
"<<" { return pp::Token::OP_LEFT; } "<<" { return pp::Token::OP_LEFT; }
...@@ -103,6 +110,11 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") ...@@ -103,6 +110,11 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
[ \t\v\f]+ { return ' '; } [ \t\v\f]+ { return ' '; }
\n { return yytext[0]; } \n { return yytext[0]; }
. {
yylval->push_back(yytext[0]);
return pp::Token::INVALID_CHARACTER;
}
<*><<EOF>> { yyterminate(); } <*><<EOF>> { yyterminate(); }
%% %%
......
...@@ -8,6 +8,33 @@ ...@@ -8,6 +8,33 @@
#include "Preprocessor.h" #include "Preprocessor.h"
#include "Token.h" #include "Token.h"
#if GTEST_HAS_PARAM_TEST
class InvalidNumberTest : public testing::TestWithParam<const char*>
{
};
TEST_P(InvalidNumberTest, InvalidNumberIdentified)
{
const char* str = GetParam();
pp::Token token;
pp::Preprocessor preprocessor;
ASSERT_TRUE(preprocessor.init(1, &str, 0));
EXPECT_EQ(pp::Token::INVALID_NUMBER, preprocessor.lex(&token));
EXPECT_EQ(pp::Token::INVALID_NUMBER, token.type);
EXPECT_STREQ(str, token.value.c_str());
}
INSTANTIATE_TEST_CASE_P(InvalidIntegers, InvalidNumberTest,
testing::Values("1a", "08", "0xG"));
INSTANTIATE_TEST_CASE_P(InvalidFloats, InvalidNumberTest,
testing::Values("1eg", "0.a", "0.1.2", ".0a", ".0.1"));
#endif // GTEST_HAS_PARAM_TEST
#if GTEST_HAS_COMBINE #if GTEST_HAS_COMBINE
typedef std::tr1::tuple<const char*, char> IntegerParams; typedef std::tr1::tuple<const char*, char> IntegerParams;
......
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