Move code into folders for convenience

This commit is contained in:
Danila Fedorin 2019-08-06 13:53:46 -07:00
parent 914b93989c
commit 34e967f364
8 changed files with 17 additions and 18 deletions

5
code/compiler/02/compile.sh Executable file
View File

@ -0,0 +1,5 @@
bison -o parser.cpp -d parser.y
flex -o scanner.cpp scanner.l
g++ -c -o scanner.o scanner.cpp
g++ -c -o parser.o parser.cpp
g++ main.cpp parser.o scanner.o

View File

@ -1,5 +1,5 @@
#include "compiler_ast.hpp" #include "ast.hpp"
#include "compiler_parser.hpp" #include "parser.hpp"
void yy::parser::error(const std::string& msg) { void yy::parser::error(const std::string& msg) {
std::cout << "An error occured: " << std::endl; std::cout << "An error occured: " << std::endl;

View File

@ -1,8 +1,8 @@
%{ %{
#include <string> #include <string>
#include <iostream> #include <iostream>
#include "compiler_ast.hpp" #include "ast.hpp"
#include "compiler_parser.hpp" #include "parser.hpp"
std::vector<definition_ptr> program; std::vector<definition_ptr> program;
extern yy::parser::symbol_type yylex(); extern yy::parser::symbol_type yylex();

View File

@ -2,8 +2,8 @@
%{ %{
#include <iostream> #include <iostream>
#include "compiler_ast.hpp" #include "ast.hpp"
#include "compiler_parser.hpp" #include "parser.hpp"
#define YY_DECL yy::parser::symbol_type yylex() #define YY_DECL yy::parser::symbol_type yylex()

View File

@ -201,7 +201,7 @@ So, our two regular expressions will be `[a-z][a-zA-Z]*` for the lowercase varia
this, we create a new file, `scanner.l`, in which we write a mix of regular expressions this, we create a new file, `scanner.l`, in which we write a mix of regular expressions
and C++ code. Here's the whole thing: and C++ code. Here's the whole thing:
{{< rawblock "compiler_scanner.l" >}} {{< rawblock "compiler/01/scanner.l" >}}
A flex file starts with options. I set the `noyywrap` option, which disables a particular A flex file starts with options. I set the `noyywrap` option, which disables a particular
feature of flex that we won't use, and which causes linker errors. Next up, feature of flex that we won't use, and which causes linker errors. Next up,

View File

@ -225,14 +225,14 @@ Just like with tokenizing, there exists a piece of software that will generate a
It's called Bison, and it is frequently used with Flex. Before we get to bison, though, we need to pay a debt we've already It's called Bison, and it is frequently used with Flex. Before we get to bison, though, we need to pay a debt we've already
incurred - the implementation of our AST. Such a tree is language-specific, so Bison doesn't generate it for us. Here's what incurred - the implementation of our AST. Such a tree is language-specific, so Bison doesn't generate it for us. Here's what
I came up with: I came up with:
{{< codeblock "C++" "compiler_ast.hpp" >}} {{< codeblock "C++" "compiler/02/ast.hpp" >}}
We create a base class for an expression tree, which we call `ast`. Then, for each possible syntactic construct in our language We create a base class for an expression tree, which we call `ast`. Then, for each possible syntactic construct in our language
(a number, a variable, a binary operation, a case expression) we create a subclass of `ast`. The `ast_case` subclass (a number, a variable, a binary operation, a case expression) we create a subclass of `ast`. The `ast_case` subclass
is the most complex, since it must contain a list of case expression branches, which are a combination of a `pattern` and is the most complex, since it must contain a list of case expression branches, which are a combination of a `pattern` and
another expression. another expression.
Finally, we get to writing our Bison file, `parser.y`. Here's what I come up with: Finally, we get to writing our Bison file, `parser.y`. Here's what I come up with:
{{< rawblock "compiler_parser.y" >}} {{< rawblock "compiler/02/parser.y" >}}
There's a few things to note here. First of all, the __parser__ is the "source of truth" regarding what tokens exist in our language. There's a few things to note here. First of all, the __parser__ is the "source of truth" regarding what tokens exist in our language.
We have a list of `%token` declarations, each of which corresponds to a regular expression in our scanner. We have a list of `%token` declarations, each of which corresponds to a regular expression in our scanner.
@ -260,7 +260,7 @@ to return `yy::parser::symbol_type`. You can see it in our forward declaration o
Now that we made these changes, it's time to hook up Flex to all this. Here's a new version Now that we made these changes, it's time to hook up Flex to all this. Here's a new version
of the Flex scanner, with all necessary modifications: of the Flex scanner, with all necessary modifications:
{{< rawblock "compiler_scanner_bison.l" >}} {{< rawblock "compiler/02/scanner.l" >}}
The key two ideas are that we overrode the default signature of `yylex` by changing the The key two ideas are that we overrode the default signature of `yylex` by changing the
`YY_DECL` preprocessor variable, and used the `yy::parser::make_<TOKEN>` functions `YY_DECL` preprocessor variable, and used the `yy::parser::make_<TOKEN>` functions
@ -268,16 +268,10 @@ to return the `symbol_type` rather than `int`.
Finally, let's get a main function so that we can at least check for segmentation faults Finally, let's get a main function so that we can at least check for segmentation faults
and other obvious mistakes: and other obvious mistakes:
{{< codeblock "C++" "compiler_main.cpp" >}} {{< codeblock "C++" "compiler/02/main.cpp" >}}
Now, we can compile and run the code: Now, we can compile and run the code:
``` {{< codeblock "Bash" "compiler/02/compile.sh" >}}
flex -o compiler_scanner.cpp compiler_scanner_bison.l
bison -o compiler_parser.cpp -d compiler_parser.y
g++ -c -o scanner.o compiler_scanner.cpp
g++ -c -o parser.o compiler_parser.cpp
g++ compiler_main.cpp parser.o scanner.o
```
We used the `-d` option for Bison to generate the `compiler_parser.hpp` header file, We used the `-d` option for Bison to generate the `compiler_parser.hpp` header file,
which exports our token declarations and token creation functions, allowing which exports our token declarations and token creation functions, allowing
us to use them in Flex. us to use them in Flex.