diff --git a/README.md b/README.md new file mode 100644 index 0000000..94183a3 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# Parser +## Explanation of options: +```cpp +// Bison version +%require "3.0.4" + +// skeleton program to be used as parser +%skeleton "lalr1.cc" + +// tells bison to generate a header file +%defines + +// where the parser will live (in what namespace) +%define api.prefix {yy} + +// the name of parser class +%define api.parser.class {Parser} + +/* it will generate a location class which can be used in your lexer */ +%locations + +/* use the constructor for each token, and make_TOKENNAME functions will be generated */ +%define api.token.constructor + +/* use the variant type for $1~$n and $$ those variables */ +%define api.value.type variant + +%define parse.trace +%define parse.error verbose +``` \ No newline at end of file diff --git a/makefile b/makefile index d04c0e3..f567b25 100644 --- a/makefile +++ b/makefile @@ -5,7 +5,7 @@ FLEX = flex TARGET = build/py2rb -$(TARGET): build/lexer.o build/parser.o build/ParserCtx.o build/main.o +$(TARGET): build/lexer.o build/parser.o build/ParserCtx.o build/main.o build/config.o $(CXX) $^ -o $@ build/lexer.hpp build/lexer.cpp: src/lexer.l build/parser.hpp build @@ -26,6 +26,9 @@ build/ParserCtx.o: src/ParserCtx.cpp build build/main.o: src/main.cpp build $(CXX) -c $(ARGS) $< -o $@ +build/config.o: src/config.cpp build + $(CXX) -c $(ARGS) $< -o $@ + build: mkdir -p build diff --git a/src/config.cpp b/src/config.cpp new file mode 100644 index 0000000..7e313b2 --- /dev/null +++ b/src/config.cpp @@ -0,0 +1,30 @@ +#include "../src/config.hpp" +#include +#include + +Configuration::Configuration(int argc, char **argv) +{ + if (argc <= 1) + { + return; + } + + int opt; + while ((opt = getopt(argc, argv, "i:o:l")) != -1) + { + switch (opt) + { + case 'i': + input_file = optarg; + break; + case 'o': + output_file = optarg; + break; + case 'l': + debug_lexer = true; + break; + default: + } + } + valid = true; +} diff --git a/src/config.hpp b/src/config.hpp new file mode 100644 index 0000000..86d8018 --- /dev/null +++ b/src/config.hpp @@ -0,0 +1,14 @@ +#pragma once +#include +#include + +class Configuration +{ +public: + std::string input_file = ""; + std::string output_file = ""; + bool debug_lexer = false; + + bool valid = false; + Configuration(int argc, char **argv); +}; diff --git a/src/lexer.l b/src/lexer.l index 59bfd76..68f93b0 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -1,4 +1,3 @@ - %option reentrant noyywrap nounput %{ @@ -12,24 +11,12 @@ %} - /* your definitions here */ - - /* your definitions end */ - %% %{ loc.step(); %} - /* your rules here */ - - /* use this structure to pass the Token : - * return yy::parser::make_TokenName(loc) - * if the token has a type you can pass it's value - * as the first argument. as an example we put - * the rule to return token function. - */ function {return yy::Parser::make_FUNCTION(loc);} @@ -37,10 +24,4 @@ function {return yy::Parser::make_FUNCTION(loc);} . {std::cerr << loc << ": " << "token error" << std::endl; exit(1);} - - /* if you didn't define #define yyterminate() at beginnign, you will need - this rule to match the end of file */ - /* <> {return yy::Parser::make_END(loc);} */ - /* your rules end */ - %% diff --git a/src/main.cpp b/src/main.cpp index 260c9e2..97ca6da 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,14 @@ #include "../build/parser.hpp" +#include "../src/config.hpp" int main(int argc, char *argv[]) { + Configuration config(argc, argv); + if (!config.valid) + { + std::cout << "Please provide a valid configuration\n"; + return -1; + } Elite::ParserCtx ctx; return ctx.parser->parse(); } \ No newline at end of file diff --git a/src/parser.y b/src/parser.y index 092e931..b12ec70 100644 --- a/src/parser.y +++ b/src/parser.y @@ -1,49 +1,23 @@ - -/* Require bison minimal version */ %require "3.0.4" - -/* use newer C++ skeleton file */ -%skeleton "lalr1.cc" - -/* write out a header file containing the token defines */ -%defines - -/* namespace to enclose parser in */ -%define api.prefix {yy} - -/* set the parser's class identifier */ -%define api.parser.class {Parser} - -/* it will generate a location class which can be used in your lexer */ +%skeleton "lalr1.cc" +%defines +%define api.prefix {yy} +%define api.parser.class {Parser} %locations - -/* use the constructor for each token, and make_TOKENNAME functions will be generated */ -%define api.token.constructor - -/* use the variant type for $1~$n and $$ those variables */ +%define api.token.constructor %define api.value.type variant - - %define parse.trace %define parse.error verbose %code requires { - /* you may need these header files - * add more header file if you need more - */ #include #include #include #include "../src/ParserCtx.hpp" - - /* define the sturctures using as types for non-terminals */ - - /* end the structures for non-terminal types */ } - %code { yy::Parser::symbol_type yylex(void* yyscanner, yy::location& loc); @@ -51,10 +25,7 @@ yy::Parser::symbol_type yylex(void* yyscanner, yy::location& loc); %token END 0; - - /* specify tokens, type of non-terminals and terminals here */ %token FUNCTION - /* end of token specifications */ /* The driver is passed by reference to the parser and to the scanner. This