inital
This commit is contained in:
commit
080d115e17
6 changed files with 202 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
build
|
||||||
24
makefile
Normal file
24
makefile
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
CXX = g++
|
||||||
|
ARGS = -std=c++17
|
||||||
|
BISON = /opt/homebrew/opt/bison/bin/bison
|
||||||
|
FLEX = flex
|
||||||
|
|
||||||
|
TARGET = build/py2rb
|
||||||
|
|
||||||
|
$(TARGET): build/lexer.o build/parser.o build/ParserCtx.o
|
||||||
|
$(CXX) $^ -o $@
|
||||||
|
|
||||||
|
build/lexer.hpp build/lexer.cpp: src/lexer.l build/parser.hpp
|
||||||
|
$(FLEX) --header-file=build/lexer.hpp -o build/lexer.cpp src/lexer.l
|
||||||
|
|
||||||
|
build/parser.hpp build/parser.cpp: src/parser.y
|
||||||
|
$(BISON) -d -v -o build/parser.cpp src/parser.y
|
||||||
|
|
||||||
|
build/lexer.o: build/lexer.cpp
|
||||||
|
$(CXX) -c $(ARGS) $< -o $@
|
||||||
|
|
||||||
|
build/parser.o: build/parser.cpp
|
||||||
|
$(CXX) -c $(ARGS) $< -o $@
|
||||||
|
|
||||||
|
build/ParserCtx.o: src/ParserCtx.cpp
|
||||||
|
$(CXX) -c $(ARGS) $< -o $@
|
||||||
22
src/ParserCtx.cpp
Normal file
22
src/ParserCtx.cpp
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include "ParserCtx.hpp"
|
||||||
|
#include "../build/lexer.hpp"
|
||||||
|
#include "../build/parser.hpp"
|
||||||
|
namespace Elite
|
||||||
|
{
|
||||||
|
|
||||||
|
ParserCtx::ParserCtx()
|
||||||
|
{
|
||||||
|
yylex_init(&lexer);
|
||||||
|
// yyset_in()
|
||||||
|
loc = new yy::location();
|
||||||
|
parser = new yy::Parser(lexer, *loc, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
ParserCtx::~ParserCtx()
|
||||||
|
{
|
||||||
|
yylex_destroy(lexer);
|
||||||
|
delete loc;
|
||||||
|
delete parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Elite
|
||||||
23
src/ParserCtx.hpp
Normal file
23
src/ParserCtx.hpp
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace yy
|
||||||
|
{
|
||||||
|
class Parser;
|
||||||
|
class location;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Elite
|
||||||
|
{
|
||||||
|
|
||||||
|
class ParserCtx
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ParserCtx();
|
||||||
|
~ParserCtx();
|
||||||
|
|
||||||
|
void *lexer;
|
||||||
|
yy::location *loc;
|
||||||
|
yy::Parser *parser;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Elite
|
||||||
46
src/lexer.l
Normal file
46
src/lexer.l
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
|
||||||
|
%option reentrant noyywrap nounput
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include <iostream>
|
||||||
|
#define YY_DECL yy::Parser::symbol_type yylex(yyscan_t yyscanner, yy::location& loc)
|
||||||
|
|
||||||
|
#define YY_USER_ACTION loc.columns(yyleng);
|
||||||
|
#define yyterminate() return yy::Parser::make_END(loc)
|
||||||
|
|
||||||
|
#include "../build/parser.hpp"
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
/* 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);}
|
||||||
|
|
||||||
|
[ \n\r\t\v] {}
|
||||||
|
|
||||||
|
. {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 */
|
||||||
|
/* <<EOF>> {return yy::Parser::make_END(loc);} */
|
||||||
|
/* your rules end */
|
||||||
|
|
||||||
|
%%
|
||||||
86
src/parser.y
Normal file
86
src/parser.y
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
%name-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 */
|
||||||
|
%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
|
||||||
|
|
||||||
|
|
||||||
|
%code requires
|
||||||
|
{
|
||||||
|
/* you may need these header files
|
||||||
|
* add more header file if you need more
|
||||||
|
*/
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
%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
|
||||||
|
* provides a simple but effective pure interface, not relying on global
|
||||||
|
* variables. */
|
||||||
|
%lex-param {void *scanner} {yy::location& loc}
|
||||||
|
%parse-param {void *scanner} {yy::location& loc} { class Elite::ParserCtx& ctx }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
%start program;
|
||||||
|
|
||||||
|
program: FUNCTION;
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
Elite::ParserCtx ctx;
|
||||||
|
return ctx.parser->parse();
|
||||||
|
}
|
||||||
|
|
||||||
|
void yy::Parser::error(const yy::location& l, const std::string& m)
|
||||||
|
{
|
||||||
|
std::cerr << l << ": " << m << std::endl;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue