Commit 4b2a522a by alokp@chromium.org

Punted on bison parser. It was turning out to be more complicated than…

Punted on bison parser. It was turning out to be more complicated than necessary. Manual parsing combined with a flex lexer is easier. git-svn-id: https://angleproject.googlecode.com/svn/trunk@1012 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 01fd431c
...@@ -10,8 +10,7 @@ ...@@ -10,8 +10,7 @@
#include <memory> #include <memory>
#include "common/angleutils.h" #include "common/angleutils.h"
struct YYLTYPE; #include "Token.h"
union YYSTYPE;
namespace pp namespace pp
{ {
...@@ -26,7 +25,7 @@ class Lexer ...@@ -26,7 +25,7 @@ class Lexer
bool init(int count, const char* const string[], const int length[]); bool init(int count, const char* const string[], const int length[]);
int lex(YYSTYPE* lvalp, YYLTYPE* llocp); int lex(Token* token);
private: private:
DISALLOW_COPY_AND_ASSIGN(Lexer); DISALLOW_COPY_AND_ASSIGN(Lexer);
...@@ -38,5 +37,5 @@ class Lexer ...@@ -38,5 +37,5 @@ class Lexer
}; };
} // namespace pp } // namespace pp
#endif // COMPILER_PREPROCESSOR_BUFFER_LEXER_H_ #endif // COMPILER_PREPROCESSOR_LEXER_H_
...@@ -6,50 +6,13 @@ ...@@ -6,50 +6,13 @@
#include "Token.h" #include "Token.h"
#include "token_type.h"
static const int kLocationLineSize = 16; // in bits.
static const int kLocationLineMask = (1 << kLocationLineSize) - 1;
namespace pp namespace pp
{ {
Token::Location Token::encodeLocation(int line, int file)
{
return (file << kLocationLineSize) | (line & kLocationLineMask);
}
void Token::decodeLocation(Location loc, int* line, int* file)
{
if (file) *file = loc >> kLocationLineSize;
if (line) *line = loc & kLocationLineMask;
}
Token::Token(Location location, int type, std::string* value)
: mLocation(location),
mType(type),
mValue(value)
{
}
Token::~Token() {
delete mValue;
}
std::ostream& operator<<(std::ostream& out, const Token& token) std::ostream& operator<<(std::ostream& out, const Token& token)
{ {
switch (token.type()) out << token.value;
{
case INT_CONSTANT:
case FLOAT_CONSTANT:
case IDENTIFIER:
out << *(token.value());
break;
default:
out << static_cast<char>(token.type());
break;
}
return out; return out;
} }
} // namespace pp
} // namespace pp
...@@ -8,41 +8,40 @@ ...@@ -8,41 +8,40 @@
#define COMPILER_PREPROCESSOR_TOKEN_H_ #define COMPILER_PREPROCESSOR_TOKEN_H_
#include <string> #include <string>
#include <vector>
#include "common/angleutils.h"
namespace pp namespace pp
{ {
class Token struct Token
{ {
public: enum Type
typedef int Location; {
static Location encodeLocation(int line, int file); IDENTIFIER = 258,
static void decodeLocation(Location loc, int* line, int* file);
CONST_INT,
// Takes ownership of string. CONST_FLOAT,
Token(Location location, int type, std::string* value);
~Token(); OP_LEFT_SHIFT,
OP_RIGHT_SHIFT,
Location location() const { return mLocation; } OP_LESS_EQUAL,
int type() const { return mType; } OP_GREATER_EQUAL,
const std::string* value() const { return mValue; } OP_EQUAL,
OP_NOT_EQUAL,
private: OP_AND_AND,
DISALLOW_COPY_AND_ASSIGN(Token); OP_OR_OR
};
Location mLocation; struct Location
int mType; {
std::string* mValue; int line;
int string;
};
int type;
Location location;
std::string value;
}; };
typedef std::vector<Token*> TokenVector;
typedef TokenVector::const_iterator TokenIterator;
extern std::ostream& operator<<(std::ostream& out, const Token& token); extern std::ostream& operator<<(std::ostream& out, const Token& token);
} // namepsace pp } // namepsace pp
#endif // COMPILER_PREPROCESSOR_TOKEN_H_ #endif // COMPILER_PREPROCESSOR_TOKEN_H_
...@@ -23,24 +23,21 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. ...@@ -23,24 +23,21 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
} }
%{ %{
#include "compiler/debug.h"
#include "Input.h" #include "Input.h"
#include "Lexer.h" #include "Lexer.h"
#include "Token.h"
#include "token_type.h" typedef std::string YYSTYPE;
typedef pp::Token::Location YYLTYPE;
#define YY_USER_ACTION \
do { \ #define YY_USER_ACTION \
yylloc->first_line = yylineno; \ do { \
yylloc->first_column = yycolumn + 1; \ yylloc->line = yylineno; \
yycolumn += yyleng; \
} while(0); } while(0);
#define YY_INPUT(buf, result, maxSize) \ #define YY_INPUT(buf, result, maxSize) \
result = readInput(buf, maxSize, yyscanner); result = readInput(buf, maxSize, yyscanner);
static int readInput(char* buf, int maxSize, yyscan_t scanner); static int readInput(char* buf, int maxSize, yyscan_t scanner);
static std::string* extractMacroName(const char* str, int len);
%} %}
%option noyywrap nounput never-interactive %option noyywrap nounput never-interactive
...@@ -48,8 +45,6 @@ static std::string* extractMacroName(const char* str, int len); ...@@ -48,8 +45,6 @@ static std::string* extractMacroName(const char* str, int len);
%option prefix="pp" %option prefix="pp"
%option extra-type="pp::Input*" %option extra-type="pp::Input*"
HSPACE [ \t]
HASH ^{HSPACE}*#{HSPACE}*
IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
PUNCTUATOR [][<>(){}.+-/*%^|&~=!:;,?] PUNCTUATOR [][<>(){}.+-/*%^|&~=!:;,?]
...@@ -63,45 +58,23 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") ...@@ -63,45 +58,23 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
%% %%
{HASH} { return HASH; } # {
return yytext[0];
{HASH}define{HSPACE}+{IDENTIFIER}/[ \t\n] {
yylval->sval = extractMacroName(yytext, yyleng);
return HASH_DEFINE_OBJ;
}
{HASH}define{HSPACE}+{IDENTIFIER}/"(" {
yylval->sval = extractMacroName(yytext, yyleng);
return HASH_DEFINE_FUNC;
} }
{HASH}undef{HSPACE}+ { return HASH_UNDEF; }
{HASH}if { return HASH_IF; }
{HASH}ifdef { return HASH_IFDEF; }
{HASH}ifndef { return HASH_IFNDEF; }
{HASH}else { return HASH_ELSE; }
{HASH}elif { return HASH_ELIF; }
{HASH}endif { return HASH_ENDIF; }
"defined" { return DEFINED; }
{HASH}error { return HASH_ERROR; }
{HASH}pragma { return HASH_PRAGMA; }
{HASH}extension { return HASH_EXTENSION; }
{HASH}version { return HASH_VERSION; }
{HASH}line { return HASH_LINE; }
{IDENTIFIER} { {IDENTIFIER} {
yylval->sval = new std::string(yytext, yyleng); yylval->assign(yytext, yyleng);
return IDENTIFIER; return pp::Token::IDENTIFIER;
} }
{DECIMAL_CONSTANT}|{OCTAL_CONSTANT}|{HEXADECIMAL_CONSTANT} { {DECIMAL_CONSTANT}|{OCTAL_CONSTANT}|{HEXADECIMAL_CONSTANT} {
yylval->sval = new std::string(yytext, yyleng); yylval->assign(yytext, yyleng);
return INT_CONSTANT; return pp::Token::CONST_INT;
} }
({DIGIT}+{EXPONENT_PART})|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?) { ({DIGIT}+{EXPONENT_PART})|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?) {
yylval->sval = new std::string(yytext, yyleng); yylval->assign(yytext, yyleng);
return FLOAT_CONSTANT; return pp::Token::CONST_FLOAT;
} }
{PUNCTUATOR} { return yytext[0]; } {PUNCTUATOR} { return yytext[0]; }
...@@ -125,45 +98,17 @@ int readInput(char* buf, int maxSize, yyscan_t scanner) ...@@ -125,45 +98,17 @@ int readInput(char* buf, int maxSize, yyscan_t scanner)
(input->error() == pp::Input::kErrorNone) && (input->error() == pp::Input::kErrorNone) &&
(nread == YY_NULL)) (nread == YY_NULL))
{ {
int line = 0, file = 0;
pp::Token::decodeLocation(yyget_lineno(scanner), &line, &file);
file = input->stringIndex();
yyset_lineno(pp::Token::encodeLocation(line, file), scanner);
nread = input->read(buf, maxSize); nread = input->read(buf, maxSize);
if (input->error() == pp::Input::kErrorUnexpectedEOF)
{
// TODO(alokp): Report error.
}
} }
return nread; return nread;
} }
std::string* extractMacroName(const char* str, int len)
{
// The input string is of the form {HASH}define{HSPACE}+{IDENTIFIER}
// We just need to find the last HSPACE.
ASSERT(str && (len > 8)); // strlen("#define ") == 8;
std::string* name = NULL;
for (int i = len - 1; i >= 0; --i)
{
if ((str[i] == ' ') || (str[i] == '\t'))
{
name = new std::string(str + i + 1, len - i - 1);
break;
}
}
ASSERT(name);
return name;
}
namespace pp { namespace pp {
int Lexer::lex(YYSTYPE* lvalp, YYLTYPE* llocp) int Lexer::lex(Token* token)
{ {
return yylex(lvalp, llocp, mHandle); token->type = yylex(&token->value, &token->location, mHandle);
return token->type;
} }
bool Lexer::initLexer() bool Lexer::initLexer()
......
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