Pārlūkot izejas kodu

improved parser

Nicolas Winkler 6 gadi atpakaļ
vecāks
revīzija
ab46fea171
5 mainītis faili ar 36 papildinājumiem un 25 dzēšanām
  1. 2 1
      src/ast/Ast.h
  2. 3 4
      src/ast/Parser.cpp
  3. 11 6
      src/ast/Parser.h
  4. 1 0
      src/ast/lexer.l
  5. 19 14
      src/ast/syntax.y

+ 2 - 1
src/ast/Ast.h

@@ -100,7 +100,8 @@ class qlow::ast::Ast
 {
     OwningList<AstObject> objects;
 public:
-    inline const OwningList<AstObject>& getObjects(void) const { return objects; }
+    inline const OwningList<AstObject>& getObjects(void) const  { return objects; }
+    inline       OwningList<AstObject>& getObjects(void)        { return objects; }
 };
 
 

+ 3 - 4
src/ast/Parser.cpp

@@ -3,13 +3,12 @@
 #include "lexer.h"
 using qlow::ast::Parser;
 
-std::unique_ptr<std::vector<std::unique_ptr<qlow::ast::AstObject>>> Parser::parse(void)
+qlow::ast::Ast Parser::parse(void)
 {
-    std::unique_ptr<std::vector<std::unique_ptr<qlow::ast::AstObject>>> result =
-        std::make_unique<std::vector<std::unique_ptr<qlow::ast::AstObject>>>();
+    qlow::ast::Ast result;
     yyscan_t scanner;
     qlow_parser_lex_init(&scanner);
-    auto ret = qlow_parser_parse(scanner, *result);
+    auto error = qlow_parser_parse(scanner, result, *this);
     qlow_parser_lex_destroy(scanner);
     return result;
 }

+ 11 - 6
src/ast/Parser.h

@@ -1,7 +1,8 @@
-#ifndef QLOW_PARSER_H
-#define QLOW_PARSER_H
+#ifndef QLOW_AST_PARSER_H
+#define QLOW_AST_PARSER_H
 
 #include <cstdio>
+#include <string>
 #include "Ast.h"
 
 namespace qlow
@@ -15,11 +16,15 @@ namespace qlow
 class qlow::ast::Parser
 {
     FILE* stream;
+    std::string filename;
 public:
-    inline Parser(FILE* stream) :
-        stream{ stream } {}
+    inline Parser(FILE* stream, std::string filename) :
+        stream{ stream }, filename{ std::move(filename) } {}
     
-    std::unique_ptr<std::vector<std::unique_ptr<qlow::ast::AstObject>>> parse(void);
+    Ast parse(void);
+
+    inline const std::string& getFilename(void) const { return filename; }
 };
 
-#endif // QLOW_PARSER_H
+#endif // QLOW_AST_PARSER_H
+

+ 1 - 0
src/ast/lexer.l

@@ -28,6 +28,7 @@
 %option header-file="lexer.h"
 
 %{
+#include "Parser.h"
 #include "syntax.hpp"
 
 

+ 19 - 14
src/ast/syntax.y

@@ -41,19 +41,18 @@ typedef void* yyscan_t;
 #include <vector>
 #include <iostream>
 #include <cstdio>
-#include "Ast.h"
+#include "Parser.h"
 #include "ErrorReporting.h"
 #include "syntax.hpp"
 #include "lexer.h"
 
 using namespace qlow::ast;
 
-
 //extern int qlow_parser_lex();
 //void yy_pop_state();
 
 int qlow_parser_error(qlow::CodePosition* loc, yyscan_t scan,
-    std::vector<std::unique_ptr<qlow::ast::AstObject>>& results, const char* msg)
+    Ast& ast, const Parser& parser, const char* msg)
 {
     //throw msg;
     //printf("error happened: %s\n", msg);
@@ -61,8 +60,6 @@ int qlow_parser_error(qlow::CodePosition* loc, yyscan_t scan,
     return 0;
 }
 
-std::unique_ptr<std::vector<std::unique_ptr<qlow::ast::AstObject>>> parsedClasses;
-const char* qlow_parser_filename = "";
 
 # define YYLLOC_DEFAULT(Cur, Rhs, N)                      \
 do                                                        \
@@ -86,7 +83,8 @@ while (0)
 
 %lex-param   { yyscan_t scanner }
 %parse-param { yyscan_t scanner }
-%parse-param { std::vector<std::unique_ptr<qlow::ast::AstObject>>& results }
+%parse-param { qlow::ast::Ast& ast }
+%parse-param { const qlow::ast::Parser& parser }
 
 
 %define api.prefix {qlow_parser_}
@@ -100,13 +98,15 @@ while (0)
 
 %initial-action
 {
-    @$.filename = qlow_parser_filename;
+    // NOTE: the filename only lives as long as the parser.
+    // Do not use after deletion of the parser.
+    @$.filename = parser.getFilename().c_str();
 };
 
 //%define api.location.type {qlow::CodePosition}
 
 %union {
-    std::vector<std::unique_ptr<qlow::ast::AstObject>>* topLevel;
+    qlow::ast::Ast* topLevel;
     qlow::ast::Class* classDefinition;
     
     qlow::ast::Type* type;
@@ -208,35 +208,40 @@ while (0)
 /* list of class definitions */
 topLevel:
     /* empty */ {
-       $$ = &results;
+       $$ = &ast;
     }
     |
     topLevel classDefinition {
-        $$->push_back(std::move(std::unique_ptr<qlow::ast::Class>($2)));
+        $$ = $1;
+        $$->getObjects().push_back(std::move(std::unique_ptr<qlow::ast::Class>($2)));
         $2 = nullptr;
     }
     |
     topLevel methodDefinition {
-        $$->push_back(std::move(std::unique_ptr<qlow::ast::MethodDefinition>($2)));
+        $$ = $1;
+        $$->getObjects().push_back(std::move(std::unique_ptr<qlow::ast::MethodDefinition>($2)));
         $2 = nullptr;
     }
     |
     topLevel externMethodDeclaration {
-        $$->push_back(std::move(std::unique_ptr<qlow::ast::MethodDefinition>($2)));
+        $$ = $1;
+        $$->getObjects().push_back(std::move(std::unique_ptr<qlow::ast::MethodDefinition>($2)));
         $2 = nullptr;
     }
     |
     topLevel error methodDefinition {
+        $$ = $1;
         reportError(qlow::SyntaxError(@2));
         yyerrok;
-        $$->push_back(std::move(std::unique_ptr<qlow::ast::MethodDefinition>($3)));
+        $$->getObjects().push_back(std::move(std::unique_ptr<qlow::ast::MethodDefinition>($3)));
         $3 = nullptr;
     }
     |
     topLevel error classDefinition {
         reportError(qlow::SyntaxError(@2));
         yyerrok;
-        $$->push_back(std::move(std::unique_ptr<qlow::ast::Class>($3)));
+        $$ = $1;
+        $$->getObjects().push_back(std::move(std::unique_ptr<qlow::ast::Class>($3)));
         $3 = nullptr;
     };