Explorar o código

making parser reentrant

Nicolas Winkler %!s(int64=6) %!d(string=hai) anos
pai
achega
9fe78346ee
Modificáronse 4 ficheiros con 47 adicións e 115 borrados
  1. 22 16
      src/lexer.l
  2. 0 88
      src/main.cpp
  3. 2 2
      src/makefile
  4. 23 9
      src/parser.y

+ 22 - 16
src/lexer.l

@@ -19,21 +19,29 @@
 //
 // ===========================================================================*/
 
+%option reentrant bison-bridge bison-locations
+/*%option prefix="qlow_parser_"
+*/
+%option yylineno nounput noinput
+/*%option stack
+*/
+%option 8bit
+%option header-file="lexer.h"
+
 %{
 #include "Ast.h"
 #include "parser.hpp"
 
 
 #define yylval qlow_parser_lval
-#define SET_TOKEN(t) (yylval.token = t)
-#define SET_STRING (yylval.string = new std::string(yytext, yyleng))
+#define SET_TOKEN(t) (yylval_param->token = t)
+#define SET_STRING (yylval_param->string = new std::string(yytext, yyleng))
 
-extern "C" int yywrap()
+extern "C" int yywrap(yyscan_t s)
 {
     return 1; /* do not continue on EOF */
 }
-/*  */
-int commentDepth;
+
 
 size_t offset;
 extern QLOW_PARSER_LTYPE qlow_parser_lloc;
@@ -52,10 +60,6 @@ extern const char* qlow_parser_filename;
 %}
 
 
-%option prefix="qlow_parser_"
-%option yylineno
-%option stack
-
 %x COMMENT
 %x LINE_COMMENT
 %x STRING
@@ -68,21 +72,23 @@ UTF8CHAR [\x00-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xe
 
 %%
 
+    int commentDepth = 0;
+
 <COMMENT>"/*"           commentDepth++;
 <COMMENT>"*/"           if ((--commentDepth) == 0) { BEGIN(INITIAL); };
 <COMMENT>\n             offset = 0;
 <COMMENT>.              ; // inside comment, ignore everything
 
-<LINE_COMMENT>\n        offset = 0; yy_pop_state(); //yy_push_state(INITIAL);
+<LINE_COMMENT>\n        offset = 0; yy_pop_state(yyscanner); //yy_push_state(INITIAL);
 <LINE_COMMENT>.         ; // inside comment, ignore everything
 
-<STRING>"\""            yy_pop_state();
+<STRING>"\""            yy_pop_state(yyscanner);
 <STRING>[^\"^\n]*          printf("%s\n", std::string(yytext, yyleng).c_str());
 <STRING>\n              offset = 0; SET_STRING; return UNEXPECTED_SYMBOL; 
 
-"/*"                    yy_push_state(COMMENT); commentDepth = 1;
-"//"                    yy_push_state(LINE_COMMENT);
-"\""                    yy_push_state(STRING);
+"/*"                    yy_push_state(COMMENT, yyscanner); commentDepth = 1;
+"//"                    yy_push_state(LINE_COMMENT, yyscanner);
+"\""                    yy_push_state(STRING, yyscanner);
 
 
 [\t ]                   ; // Space or tab ignored
@@ -90,8 +96,8 @@ UTF8CHAR [\x00-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xe
 \n                      offset = 0; //return SET_TOKEN(NEW_LINE);
 
 "class"                 return SET_TOKEN(CLASS);
-"do"                    yy_push_state(METHOD); return SET_TOKEN(DO);
-<METHOD>"end"           yy_pop_state(); return SET_TOKEN(END);
+"do"                    yy_push_state(METHOD, yyscanner); return SET_TOKEN(DO);
+<METHOD>"end"           yy_pop_state(yyscanner); return SET_TOKEN(END);
 <INITIAL>"end"          return SET_TOKEN(END);
 "if"                    return SET_TOKEN(IF);
 "while"                 return SET_TOKEN(WHILE);

+ 0 - 88
src/main.cpp

@@ -9,100 +9,12 @@
 
 #include "Driver.h"
 
-
-extern std::unique_ptr<std::vector<std::unique_ptr<qlow::ast::Class>>> parsedClasses;
-extern FILE* qlow_parser_in;
-extern int qlow_parser_parse(void);
-
-
 int main(int argc, char** argv)
 {
-    /*int c;
-    while ((c = getopt(argc, argv, "c:")) != -1) {
-        switch (c) {
-            case 'c':
-                printf("c: %s", optarg);
-            break;
-            default:
-                printf("ay: %c\n", c);
-        }
-    }*/
-    
     qlow::Driver driver(argc, argv);
     return driver.run();
 
     return 0;
-    /*
-    {
-    const char* filename = argv[optind];
-    
-    try {
-        ::qlow_parser_in = stdin;
-        
-        ::qlow_parser_in = fopen(filename, "r");
-        if (!::qlow_parser_in)
-            throw (std::string("File not found: ") + filename).c_str();
-        
-        ::qlow_parser_parse();
-        std::cout << parsedClasses->size() << std::endl;
-
-        std::cout << "parsing completed!" << std::endl;
-
-        std::unique_ptr<qlow::sem::GlobalScope> semClasses =
-            qlow::sem::createFromAst(*parsedClasses.get());
-
-        for (auto& [a, b] : semClasses->classes) {
-            std::cout << a << ": " << b->toString() << std::endl;
-        }
-
-        auto main = semClasses->classes.find("Main");
-        qlow::sem::Class* mainClass = nullptr;
-        if (main == semClasses->classes.end()) {
-            throw "No Main class found!";
-        }
-        else {
-            mainClass = main->second.get();
-        }
-        auto mainmain = mainClass->methods.find("main");
-        qlow::sem::Method* mainMethod = nullptr;
-        if (mainmain == mainClass->methods.end()) {
-            //throw "No main method found inside Main class!";
-        }
-        else {
-            mainMethod = mainmain->second.get();
-        }
-        
-        std::cout << "starting code generation!" << std::endl;
-
-        auto mod = qlow::gen::generateModule(semClasses->classes);
-        qlow::gen::generateObjectFile("obj.o", std::move(mod));
-        
-        std::cout << "object exported!" << std::endl;
-    }
-    catch (qlow::sem::SemanticException& se)
-    {
-        std::cerr << se.getMessage() << std::endl;
-    }
-    catch (const std::string& err)
-    {
-        std::cerr << err << std::endl;
-    }
-    catch (const char* err)
-    {
-        std::cerr << err << std::endl;
-    }
-    catch (...)
-    {
-        std::cerr << "an unknown error occurred" << std::endl;
-    }
-    
-    if (::qlow_parser_in != stdin)
-        fclose(::qlow_parser_in);
-    }
-
-    for (auto&& c : *parsedClasses) {
-        delete c.release();
-    }*/
 }
 
 

+ 2 - 2
src/makefile

@@ -5,8 +5,8 @@ CXX := clang++
 
 LLVMCONFIG := llvm-config
 
-INCLUDEDIRS := -I$(shell $(LLVMCONFIG) --includedir):. -I.. -Isem/ -Iast/ -I.
-CXXFLAGS := -std=c++17 $(INCLUDEDIRS) -w # -Wall -Wextra
+INCLUDEDIRS := -I$(shell $(LLVMCONFIG) --includedir) -I.. -Isem/ -Iast/ -I.
+CXXFLAGS := -std=c++17 $(INCLUDEDIRS) -w -ferror-limit=5 # -Wall -Wextra
 
 ifdef STATIC
 LDFLAGS := $(shell $(LLVMCONFIG) --link-static --ldflags --system-libs --libs all) -static -dead-strip -s

+ 23 - 9
src/parser.y

@@ -19,6 +19,16 @@
 //
 // ===========================================================================*/
 
+%code requires {
+#include "Ast.h"
+    using QLOW_PARSER_LTYPE = qlow::CodePosition;
+    union QLOW_PARSER_STYPE;
+    using YYLTYPE = QLOW_PARSER_LTYPE;
+    using YYSTYPE = QLOW_PARSER_STYPE;
+#define QLOW_PARSER_LTYPE_IS_DECLARED
+
+#include "lexer.h"
+}
 
 %{
 
@@ -31,11 +41,15 @@
 
 using namespace qlow::ast;
 
-extern int qlow_parser_lex();
 
-void yy_pop_state(void);
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+using yyscan_t = void*;
+#endif
+//extern int qlow_parser_lex();
+//void yy_pop_state();
 
-int qlow_parser_error(const char* msg)
+int qlow_parser_error(qlow::CodePosition* loc, yyscan_t scan, const char* msg)
 {
     //throw msg;
     //printf("error happened: %s\n", msg);
@@ -64,20 +78,20 @@ do                                                        \
         YYRHSLOC(Rhs, 0).last_column;                     \
     }                                                     \
 while (0)
-
 %}
 
+%lex-param   { yyscan_t scanner }
+%parse-param { yyscan_t scanner }
+
 
 %define api.prefix {qlow_parser_}
 %define parse.error verbose
+%define api.pure full
 // %define parse.lac full
 
 %locations
-%code requires {
-#include "Ast.h"
-typedef qlow::CodePosition QLOW_PARSER_LTYPE;
-#define QLOW_PARSER_LTYPE_IS_DECLARED
-}
+%defines
+
 
 %initial-action
 {