From 508f7883308ff3ca204e1017b27dcbeb9b71dd8f Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sat, 11 Feb 2017 14:31:25 +0000 Subject: Finished lexer for the parser --- c_lexer/src/c_lexer.cpp | 10 ++++++--- c_parser/src/c_lexer.flex | 54 ++++++++++++++++++++++++++++++++--------------- c_parser/src/c_parser.y | 37 ++++++++++++++++---------------- 3 files changed, 62 insertions(+), 39 deletions(-) diff --git a/c_lexer/src/c_lexer.cpp b/c_lexer/src/c_lexer.cpp index e01d73f..0e9f021 100644 --- a/c_lexer/src/c_lexer.cpp +++ b/c_lexer/src/c_lexer.cpp @@ -1,7 +1,11 @@ #include "c_lexer.hpp" -std::string toJson(const std::string& classType, const std::string& text, const std::string& strLine, const std::string& srcCol, const std::string& srcLine, const std::string& fName) { - std::string tmp = "{\"Class\":\"" + classType + "\", \"Text\":\"" + text + "\", \"StreamLine\":" + strLine + ", \"SourceFile\":\"" + fName + "\", \"SourceLine\":" + srcLine + ", \"SourceCol\":" + srcCol + "}"; +std::string toJson(const std::string& classType, const std::string& text, + const std::string& strLine, const std::string& srcCol, + const std::string& srcLine, const std::string& fName) { + std::string tmp = "{\"Class\":\"" + classType + "\", \"Text\":\"" + text + + "\", \"StreamLine\":" + strLine + ", \"SourceFile\":\"" + fName + + "\", \"SourceLine\":" + srcLine + ", \"SourceCol\":" + srcCol + "}"; - return tmp; + return tmp; } diff --git a/c_parser/src/c_lexer.flex b/c_parser/src/c_lexer.flex index 670ec2b..833aa32 100644 --- a/c_parser/src/c_lexer.flex +++ b/c_parser/src/c_lexer.flex @@ -8,29 +8,49 @@ extern "C" int fileno(FILE *stream); %} +KEYWORD auto|double|int|struct|break|else|long|switch|case|enum|register|typedef|char|extern|return|union|const|float|short|unsigned|continue|for|signed|void|default|goto|sizeof|volatile|do|if|static|while + +IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* + +OPERATOR [.][.][.]|[<>][<>][=]|[-][-]|[+][+]|[|][|]|[#][#]|[&][&]|[+\-*\/<>=!%^|&][=]|[<][<]|[->][>]|[<>&=+\/\-*(){}\[\]\.,%~!?:|^;] + +FRACTIONALCONSTANT (([0-9]*\.[0-9]+)|([0-9]+\.)) +EXPONENTPART ([eE][+-]?[0-9]+) + +FLOATINGSUFFIX ([flFL]) +INTEGERSUFFIX ([uU][lL]|[lL][uU]|[uUlL]) + +DECIMALCONSTANT ([1-9][0-9]*) +OCTALCONSTANT ([0][0-7]*) +HEXCONSTANT ([0][xX][0-9A-Fa-f]+) + +CHARCONSTANT ('(([\\]['])|([^']))+') + +STRINGLITERAL ["](([\\]["])|([^"]))*["] + +WHITESPACE [ \t\r\n]+ + +PREPROC [#][ ][0-9]+[ ]{STRINGLITERAL}[ 0-9]* + +ALL . + %% -[*] { return T_TIMES; } -[+] { return T_PLUS; } -[/] { return T_DIVIDE; } -[-] { return T_MINUS; } -[(] { return T_LBRACKET; } -[)] { return T_RBRACKET; } +{KEYWORD} { yylval.string = new std::string(yytext); return T_KEYWORD; } + +{IDENTIFIER} { yylval.string = new std::string(yytext); return T_IDENTIFIER; } + +{OPERATOR} { yylval.string = new std::string(yytext); return T_OPERATOR; } -log { return T_LOG; } -exp { return T_EXP; } -sqrt { return T_SQRT; } +({HEXCONSTANT}|{OCTALCONSTANT}|{DECIMALCONSTANT})|{INTEGERSUFFIX}? { yylval.number=strtod(yytext, 0); return T_CONSTANT; } -[-]?[0-9]+([.][0-9]*)? { yylval.number=strtod(yytext, 0); return T_NUMBER; } -[a-z]+ { yylval.string=new std::string(yytext); return T_VARIABLE; } +{WHITESPACE} { ; } -[ \t\r\n]+ {;} +. { fprintf(stderr, "Invalid token\n"); exit(1); } -. { fprintf(stderr, "Invalid token\n"); exit(1); } %% -void yyerror (char const *s) -{ - fprintf (stderr, "Parse error : %s\n", s); - exit(1); +void yyerror(char const *s) { + fprintf (stderr, "Parse error : %s\n", s); + exit(1); } diff --git a/c_parser/src/c_parser.y b/c_parser/src/c_parser.y index a00ab82..56fb961 100644 --- a/c_parser/src/c_parser.y +++ b/c_parser/src/c_parser.y @@ -1,30 +1,30 @@ %code requires{ - #include "ast.hpp" - #include +#include "ast.hpp" - extern const Expression *g_root; // A way of getting the AST out +extern const Expression *g_root; // A way of getting the AST out + +//! This is to fix problems when generating C++ +// We are declaring the functions provided by Flex, so +// that Bison generated code can call them. +int yylex(void); +void yyerror(const char *); - //! This is to fix problems when generating C++ - // We are declaring the functions provided by Flex, so - // that Bison generated code can call them. - int yylex(void); - void yyerror(const char *); } // Represents the value associated with any kind of // AST node. %union{ - const Expression *expr; - double number; - std::string *string; + const Expression *expr; + double number; + std::string *string; } -%token T_TIMES T_PLUS T_DIVIDE T_MINUS T_LBRACKET T_RBRACKET T_LOG T_EXP T_SQRT T_NUMBER T_VARIABLE +%token T_KEYWORD T_IDENTIFIER T_CONSTANT T_OPERATOR %type EXPR TERM FACTOR -%type T_NUMBER -%type T_VARIABLE T_LOG T_EXP T_SQRT FUNCTION_NAME +%type T_CONSTANT +%type T_KEYWORD T_IDENTIFIER T_OPERATOR %start ROOT @@ -60,9 +60,8 @@ FUNCTION_NAME : T_LOG { $$ = new std::string("log"); } const Expression *g_root; // Definition of variable (to match declaration earlier) -const Expression *parseAST() -{ - g_root=0; - yyparse(); - return g_root; +const Expression *parseAST() { + g_root=0; + yyparse(); + return g_root; } -- cgit