Procházet zdrojové kódy

got parser to work :)

Nicolas Winkler před 7 roky
rodič
revize
55bd5f7156
9 změnil soubory, kde provedl 297 přidání a 93 odebrání
  1. 9 0
      src/Ast.cpp
  2. 143 16
      src/Ast.h
  3. 25 2
      src/lexer.l
  4. 7 1
      src/main.cpp
  5. binární
      src/main.o
  6. 2 2
      src/makefile
  7. 84 61
      src/parser.y
  8. 16 11
      src/tests/full_tests/simple_arithmetic.qlw
  9. 11 0
      src/tests/full_tests/syntax.qlw

+ 9 - 0
src/Ast.cpp

@@ -0,0 +1,9 @@
+#include "Ast.h"
+
+
+using namespace qlow::ast;
+
+Statement::~Statement(void)
+{
+}
+

+ 143 - 16
src/Ast.h

@@ -22,6 +22,7 @@
 #include <string>
 #include <vector>
 #include <memory>
+#include <utility>
 
 
 namespace qlow
@@ -40,13 +41,20 @@ namespace qlow
         struct MethodDefinition;
 
         struct VariableDeclaration;
+        struct ArgumentDeclaration;
 
-        struct Statement;
+        struct DoEndBlock;
 
+        struct Statement;
         struct Expression;
-        struct Identifier;
+
+        struct FeatureCall;
+        struct AssignmentStatement;
+        struct NewVariableStatement;
+
+        struct Operation;
+        struct UnaryOperation;
         struct BinaryOperation;
-        struct FunctionCall;
     }
 }
 
@@ -55,6 +63,12 @@ namespace qlow
 struct qlow::ast::Class
 {
     std::string name;
+    List<FeatureDeclaration> features;
+    
+    inline Class(const std::string& name, List<FeatureDeclaration>& features) :
+        name(name), features(std::move(features))
+    {
+    }
 };
 
 
@@ -62,41 +76,81 @@ struct qlow::ast::FeatureDeclaration
 {
     std::string name;
     std::string type;
+
+    inline FeatureDeclaration(const std::string& type, const std::string& name) :
+        name(name), type(type)
+    {
+    }
 };
 
 
-struct qlow::ast::FieldDeclaration
+struct qlow::ast::FieldDeclaration : public FeatureDeclaration
 {
-    inline MethodDefinition(const std::string& type, const std::string& name) :
+    inline FieldDeclaration(const std::string& type, const std::string& name) :
         FeatureDeclaration(type, name)
     {
     }
 };
 
 
-struct qlow::ast::MethodDefinition
+struct qlow::ast::MethodDefinition : public FeatureDeclaration
 {
     List<ArgumentDeclaration> arguments;
     std::unique_ptr<DoEndBlock> body;
 
     inline MethodDefinition(const std::string& type, const std::string& name,
-            std::unique_ptr<DoEndBlock>&& body) :
+            std::unique_ptr<DoEndBlock> body) :
         FeatureDeclaration(type, name),
-        body(body)
+        body(std::move(body))
+    {
+    }
+
+
+    inline MethodDefinition(const std::string& type, const std::string& name,
+            List<ArgumentDeclaration>&& arguments, std::unique_ptr<DoEndBlock> body) :
+        FeatureDeclaration(type, name),
+        arguments(std::move(arguments)),
+        body(std::move(body))
     {
     }
 };
 
 
-struct qlow::ast::VariableDeclaration
+struct qlow::ast::VariableDeclaration 
 {
-    std::string name;
     std::string type;
+    std::string name;
+    inline VariableDeclaration(const std::string& type, const std::string& name) :
+        type(type), name(name)
+    {
+    }
+};
+
+
+struct qlow::ast::ArgumentDeclaration :
+    public VariableDeclaration
+{
+    inline ArgumentDeclaration(const std::string& type, const std::string& name) :
+        VariableDeclaration(type, name)
+    {
+    }
+};
+
+
+struct qlow::ast::DoEndBlock
+{
+    List<Statement> statements;
+    
+    inline DoEndBlock(List<Statement>&& statements) :
+        statements(std::move(statements))
+    {
+    }
 };
 
 
 struct qlow::ast::Statement
 {
+    virtual ~Statement(void);
 };
 
 
@@ -105,21 +159,94 @@ struct qlow::ast::Expression
 };
 
 
-struct qlow::ast::BinaryOperation : public Expression
+struct qlow::ast::FeatureCall : public Expression, public Statement
 {
-    std::unique_ptr<Expression> left;
-    std::string operator_str;
-    std::unique_ptr<Expression> right;
+    std::unique_ptr<Expression> target;
+    std::string name;
+    List<Expression> arguments;
+
+    inline FeatureCall(std::unique_ptr<Expression> target, const std::string& name) :
+        target(std::move(target)), name(name)
+    {
+    }
+
+
+    inline FeatureCall(std::unique_ptr<Expression> target, const std::string& name,
+            List<Expression>&& arguments) :
+        target(std::move(target)), name(name), arguments(std::move(arguments))
+    {
+    }
+};
+
+
+struct qlow::ast::AssignmentStatement : public Statement
+{
+    std::string target;
+    std::unique_ptr<Expression> expr;
+
+    inline AssignmentStatement(const std::string& target, std::unique_ptr<Expression> expr) :
+        target(target), expr(std::move(expr))
+    {
+    }
 };
 
 
-struct qlow::ast::FunctionCall : public Expression
+struct qlow::ast::NewVariableStatement : public Statement
 {
     std::string name;
-    std::vector<std::unique_ptr<Expression>> arguments;
+    std::string type;
+    inline NewVariableStatement(const std::string& name, const std::string& type) :
+       name(name), type(type)
+    {
+    } 
+};
+
+
+struct qlow::ast::Operation : public Expression
+{
+    enum Operator {
+        PLUS, MINUS, ASTERISK, SLASH
+    };
+    Operator op;
+
+    inline Operation(Operator op) :
+        op(op)
+    {
+    }
+};
+
+
+struct qlow::ast::UnaryOperation : public Operation
+{
+    enum Side
+    {
+        PREFIX,
+        SUFFIX,
+    };
+
+    Side side;
+    std::unique_ptr<Expression> expr;
+
+    inline UnaryOperation(std::unique_ptr<Expression> expr, Side side, Operator op) :
+        Operation(op),
+        side(side),
+        expr(std::move(expr))
+    {
+    }
 };
 
 
+struct qlow::ast::BinaryOperation : public Operation
+{
+    std::unique_ptr<Expression> left;
+    std::unique_ptr<Expression> right;
+
+    inline BinaryOperation(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right, Operator op) :
+        Operation(op),
+        left(std::move(left)), right(std::move(right))
+    {
+    }
+};
 
 
 

+ 25 - 2
src/lexer.l

@@ -21,14 +21,15 @@
 
 %{
 #include "Ast.h"
+#include "parser.hpp"
 
-//#define yylval qlow_parser_lval
+
+#define yylval qlow_parser_lval
 #define SET_TOKEN(t) (yylval.token = t)
 #define SET_STRING (yylval.string = new std::string(yytext, yyleng))
 
 extern "C" int yywrap()
 {
-    
     return 1; /* do not continue on EOF */
 }
 
@@ -39,6 +40,28 @@ extern "C" int yywrap()
 
 %%
 
+[\t ]                   ; // Space or tab ignored
+\/\*[.\n]*\*\/          ; // comment
+\n                      ; //return SET_TOKEN(NEW_LINE);
+
+"class"                 return SET_TOKEN(CLASS);
+"do"                    return SET_TOKEN(DO);
+"end"                   return SET_TOKEN(END);
+"if"                    return SET_TOKEN(IF);
+
+":"                     return SET_TOKEN(COLON);
+","                     return SET_TOKEN(COMMA);
+":="                    return SET_TOKEN(ASSIGN);
+"."                     return SET_TOKEN(DOT);
+
+"("                     return SET_TOKEN(ROUND_LEFT);
+")"                     return SET_TOKEN(ROUND_RIGHT);
+
+"+"		        return SET_TOKEN(PLUS);
+"-"		        return SET_TOKEN(MINUS);
+"*"		        return SET_TOKEN(ASTERISK);
+"/"		        return SET_TOKEN(SLASH);
+
 
 [a-zA-Z_][a-zA-Z0-9_]*  SET_STRING; return IDENTIFIER;
 .                       printf("Unknown token!\n"); yyterminate();

+ 7 - 1
src/main.cpp

@@ -1,9 +1,15 @@
+#include <iostream>
 #include "Ast.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()
 {
-
+    qlow_parser_in = stdin;
+    ::qlow_parser_parse();
+    std::cout << parsedClasses->size() << std::endl;
 }
 
 

binární
src/main.o


+ 2 - 2
src/makefile

@@ -1,5 +1,5 @@
 CXX := g++
-CXXFLAGS := -g -Wall
+CXXFLAGS := -g -Wall -std=c++17
 LINKFLAGS :=
 
 YACC := bison
@@ -10,7 +10,7 @@ LEXFLAGS :=
 OBJECTS := $(patsubst %.cpp, %.o, $(wildcard *.cpp */*.cpp)) \
     parser.o lexer.o
 LIBRARIES := 
-EXECUTABLE := glow
+EXECUTABLE := qlow
 
 
 all: $(EXECUTABLE)

+ 84 - 61
src/parser.y

@@ -27,7 +27,8 @@
 #include <iostream>
 #include <cstdio>
 #include "Ast.h"
-using namespace qlow::parser;
+
+using namespace qlow::ast;
 
 extern int qlow_parser_lex();
 
@@ -41,7 +42,7 @@ std::unique_ptr<ClassList> parsedClasses;
 
 %}
 
-%define api.prefix {uetli_parser_}
+%define api.prefix {qlow_parser_}
 
 /*
 %skeleton "lalr1.cc" // generate C++ parser
@@ -52,12 +53,30 @@ std::unique_ptr<ClassList> parsedClasses;
 //%name-prefix "uetli_parser_"
 */
 %union {
-    std::vector<std::unique_ptr<uetli::parser::Class>>* classes;
-    ClassDefinition* classDefinition;
-    FeatureDeclaration* featureDeclaration;
-    std::vector<std::unique_ptr<uetli::parser::FeatureDeclaration>>* featureList;
+    std::vector<std::unique_ptr<qlow::ast::Class>>* classes;
+    qlow::ast::Class* classDefinition;
+    qlow::ast::FeatureDeclaration* featureDeclaration;
+    std::vector<std::unique_ptr<qlow::ast::FeatureDeclaration>>* featureList;
+    std::vector<std::unique_ptr<qlow::ast::ArgumentDeclaration>>* argumentList;
+    std::vector<std::unique_ptr<qlow::ast::Statement>>* statements;
+    std::vector<std::unique_ptr<qlow::ast::Expression>>* expressionList;
+    qlow::ast::ArgumentDeclaration* argumentDeclaration;
+    qlow::ast::DoEndBlock* doEndBlock;    
+    qlow::ast::Statement* statement;
+    qlow::ast::Expression* expression;
+    qlow::ast::Operation::Operator op;
+
+    qlow::ast::MethodDefinition* methodDefinition;
+
+    qlow::ast::FeatureCall* featureCall;
+    qlow::ast::AssignmentStatement* assignmentStatement;
+    qlow::ast::NewVariableStatement* newVariableStatement;
+
+    qlow::ast::UnaryOperation* unaryOperation;
+    qlow::ast::BinaryOperation* binaryOperation;
 
     const char* cString;
+    std::string* string;
     int token;
 };
 
@@ -70,27 +89,29 @@ std::unique_ptr<ClassList> parsedClasses;
 
 %type <classes> classes
 %type <classDefinition> classDefinition
-%type <featureDeclaration> featureDeclaration fieldDeclaration methodDeclaration
+%type <featureDeclaration> featureDeclaration fieldDeclaration methodDefinition
 %type <featureList> featureList
+%type <argumentList> argumentList
+%type <statements> statements
+%type <expressionList> expressionList
+%type <argumentDeclaration> argumentDeclaration
+%type <doEndBlock> doEndBlock
+%type <statement> statement
+%type <expression> expression operationExpression paranthesesExpression
+%type <op> operator
+%type <featureCall> featureCall
+%type <assignmentStatement> assignmentStatement 
+%type <newVariableStatement> newVariableStatement
+%type <unaryOperation> unaryOperation
+%type <binaryOperation> binaryOperation
 
 %left ASTERISK SLASH
 %left PLUS MINUS
 
-%start compilationUnit
+%start classes
 
 %%
 
-
-compilationUnit:
-    /* empty */ {
-        parsedClasses = std::make_unique<ClassList>();
-    }
-    |
-    compilationUnit classes {
-        parsedClasses = $2;
-    };
-
-
 /* possible newline characters
 pnl:
     {
@@ -102,20 +123,19 @@ pnl:
 
 /* list of class definitions */
 classes:
-    classDefinition {
-        $$ = new std::vector<std::unique_ptr<ClassDefinition>>();
-        $$->push_back($1);
+    /* empty */ {
+       parsedClasses = std::make_unique<ClassList>();
     }
     |
     classes classDefinition {
-        $$->push_back($3);
+        parsedClasses->push_back(std::move(std::unique_ptr<Class>($2)));
     };
 
 
 classDefinition:
     CLASS IDENTIFIER featureList END {
-        $$ = new ClassDefinition(*$2, *$3);
-        delete $2; $2 = 0; $3 = 0;
+        $$ = new Class(*$2, *$3);
+        delete $2; delete $3; $2 = 0; $3 = 0;
     };
 
 
@@ -126,7 +146,7 @@ featureList:
     |
     featureList featureDeclaration {
         $$ = $1;
-        $$->push_back($2);
+        $$->push_back(std::move(std::unique_ptr<FeatureDeclaration>($2)));
     };
 
 
@@ -135,7 +155,7 @@ featureDeclaration:
         $$ = $1;
     }
     |
-    methodDeclaration {
+    methodDefinition {
         $$ = $1;
     };
 
@@ -149,36 +169,36 @@ fieldDeclaration:
 
 methodDefinition:
     IDENTIFIER COLON IDENTIFIER doEndBlock {
-        $$ = new MethodDefinition(*$3, *$1, $4);
+        $$ = new MethodDefinition(*$3, *$1, std::move(std::unique_ptr<DoEndBlock>($4)));
         delete $3; delete $1; $1 = $3 = 0;
     }
     |
     IDENTIFIER doEndBlock {
-        $$ = new MethodDefinition("", *$1, $2);
+        $$ = new MethodDefinition("", *$1, std::move(std::unique_ptr<DoEndBlock>($2)));
         delete $1; $1 = 0;
     }
     |
     IDENTIFIER
         ROUND_LEFT argumentList ROUND_RIGHT COLON IDENTIFIER doEndBlock {
-        $$ = new MethodDefinition(*$6, *$1, $7);
-        delete $6; delete $1; $1 = $6 = 0;
+        $$ = new MethodDefinition(*$6, *$1, std::move(*$3), std::move(std::unique_ptr<DoEndBlock>($7)));
+        delete $6; delete $1; delete $3; $1 = $6 = nullptr; $3 = nullptr;
     }
     |
     IDENTIFIER ROUND_LEFT argumentList ROUND_RIGHT doEndBlock {
-        $$ = new MethodDefinition("", *$1, $5);
-        delete $1; $1 = 0;
+        $$ = new MethodDefinition("", *$1, std::move(*$3), std::move(std::unique_ptr<DoEndBlock>($5)));
+        delete $1; delete $3; $1 = nullptr; $3 = nullptr;
     };
 
 
 argumentList:
     argumentDeclaration {
         $$ = new std::vector<std::unique_ptr<ArgumentDeclaration>>();
-        $$->push_back($1);
+        $$->push_back(std::unique_ptr<ArgumentDeclaration>($1));
     }
     |
     argumentList COMMA argumentDeclaration {
         $$ = $1;
-        $$->push_back($3);
+        $$->push_back(std::unique_ptr<ArgumentDeclaration>($3));
     };
 
 
@@ -191,7 +211,7 @@ argumentDeclaration:
 
 doEndBlock:
     DO statements END {
-        $$ = new DoEndBlock(*$2);
+        $$ = new DoEndBlock(std::move(*$2));
         delete $2; $2 = 0;
     };
 
@@ -203,12 +223,12 @@ statements:
     |
     statements statement {
         $$ = $1;
-        $$->push_back($2);
+        $$->push_back(std::move(std::unique_ptr<Statement>($2)));
     };
 
 
 statement:
-    callOrVariableStatement {
+    featureCall {
         $$ = $1;
     }
     |
@@ -221,24 +241,25 @@ statement:
     };
 
 
-callOrVariableStatement:
+featureCall:
     IDENTIFIER {
-        $$ = new CallOrVariableStatement(0, *$1);
+        $$ = new FeatureCall(nullptr, *$1);
         delete $1; $1 = 0;
     }
     |
     IDENTIFIER ROUND_LEFT expressionList ROUND_RIGHT {
-        $$ = new CallOrVariableStatement(0, *$1, *$3);
+        $$ = new FeatureCall(nullptr, *$1, std::move(*$3));
         delete $1; delete $3; $1 = 0; $3 = 0;
     }
     |
     expression DOT IDENTIFIER {
-        $$ = new CallOrVariableStatement($1, *$3);
+        $$ = new FeatureCall(std::move(std::unique_ptr<Expression>($1)), *$3);
         delete $3; $3 = 0;
     }
     |
     expression DOT IDENTIFIER ROUND_LEFT expressionList ROUND_RIGHT {
-        $$ = new CallOrVariableStatement($1, *$3, *$5);
+        $$ = new FeatureCall(std::move(std::unique_ptr<Expression>($1)), *$3,
+            std::move(*$5));
         delete $3; $3 = 0; delete $5; $5 = 0;
     };
 
@@ -247,17 +268,17 @@ callOrVariableStatement:
 expressionList:
     expression {
         $$ = new std::vector<std::unique_ptr<Expression>>();
-        $$->push_back($1);
+        $$->push_back(std::move(std::unique_ptr<Expression>($1)));
     }
     |
     expressionList COMMA expression {
         $$ = $1;
-        $$->push_back($3);
+        $$->push_back(std::move(std::unique_ptr<Expression>($3)));
     };
 
 
 expression:
-    callOrVariableStatement {
+    featureCall {
         $$ = $1;
     }
     |
@@ -271,41 +292,42 @@ expression:
 
 
 operationExpression:
-    binaryOperationExpression {
+    binaryOperation {
         $$ = $1;
     }
     |
-    unaryOperationExpression {
+    unaryOperation {
         $$ = $1;
     };
 
 
-binaryOperationExpression:
+binaryOperation:
     expression operator expression {
-        $$ = new BinaryOperationExpression($1, $3, $2);
+        $$ = new BinaryOperation(std::unique_ptr<Expression>($1), 
+            std::unique_ptr<Expression>($3), $2);
     };
 
 
-unaryOperationExpression:
+unaryOperation:
     expression operator {
-        $$ = new UnaryOperationExpression($1,
-            UnaryOperationExpression::SUFFIX, $2);
+        $$ = new UnaryOperation(std::unique_ptr<Expression>($1),
+            UnaryOperation::SUFFIX, $2);
     }
     |
     operator expression {
-        $$ = new UnaryOperationExpression($2,
-            UnaryOperationExpression::PREFIX, $1);
+        $$ = new UnaryOperation(std::unique_ptr<Expression>($2),
+            UnaryOperation::PREFIX, $1);
     };
 
 
 operator:
-    PLUS { $$ = "+"; }
+    PLUS { $$ = qlow::ast::Operation::Operator::PLUS; }
     |
-    MINUS { $$ = "-"; }
+    MINUS { $$ = qlow::ast::Operation::Operator::MINUS; }
     |
-    ASTERISK { $$ = "*"; }
+    ASTERISK { $$ = qlow::ast::Operation::Operator::ASTERISK; }
     |
-    SLASH { $$ = "/"; };
+    SLASH { $$ = qlow::ast::Operation::Operator::SLASH; };
 
 
 paranthesesExpression:
@@ -315,8 +337,9 @@ paranthesesExpression:
 
 
 assignmentStatement:
-    callOrVariableStatement ASSIGN expression {
-        $$ = new AssignmentStatement($1, $3);
+    IDENTIFIER ASSIGN expression {
+        $$ = new AssignmentStatement(std::move(*$1), std::unique_ptr<Expression>($3));
+        delete $1; $1 = 0;
     };
 
 

+ 16 - 11
src/tests/full_tests/simple_arithmetic.qlw

@@ -1,18 +1,23 @@
 
-// define our variables
-var a : int
-var b : int
-var c : int
 
-// initialize values
-a = 3
-b = 10
 
-// calculate
-c = a + b
+class Main
+    compute do
+        // define our variables
+        var a : int
+        var b : int
+        var c : int
 
-print(c)
+        // initialize values
+        a = 3
+        b = 10
 
-add(a, b, c)
+        // calculate
+        c = a + b
 
+        print(c)
+
+        add(a, b, c)
+    end
+end
 

+ 11 - 0
src/tests/full_tests/syntax.qlw

@@ -0,0 +1,11 @@
+class Main
+    compute(asda : wewe, e : int32) : int do
+        a := b + c * d
+        a := 3
+        if a do
+        end
+        asdadd(wew)
+        a := werr.sdd
+    end
+end
+