%top{ #include "parser.hh" %} %option bison-cc %option bison-locations %option noyywrap %option namespace="compiler" %option lexer="lexer" %option lex="yylex" %option header-file="lexer.hh" %option bison-cc-namespace="compiler" NUMBER [[:digit:]]+ WORD [[:alnum:]]+ LET = DELIM ; NL .|\n SPACE [\t ] %% {NUMBER} { yylval.num = atoi(text()); return compiler::parser::token::NUMBER; } {WORD} { yylval.str = strdup(text()); return compiler::parser::token::STRING; } {DELIM} { return compiler::parser::token::DELIM; } {LET} { return compiler::parser::token::LET; } {SPACE} {} NL {} %%
%skeleton "lalr1.cc" %require "3.2" %language "c++" %defines "parser.hh" %output "parser.cc" %define api.namespace { compiler } %code requires{ #include <sstream> namespace compiler { class lexer; } namespace compiler { class driver; } } %code{ #include "lexer.hh" #undef yylex #define yylex lexer.yylex namespace compiler { class driver { private: compiler::lexer lexer; compiler::parser *parser; public: driver(reflex::Input in) : lexer(in), parser(new compiler::parser(lexer, *this)) { } ~driver() { delete parser; } int parse() { return parser->parse(); } }; } } %locations %parse-param { compiler::lexer &lexer } %parse-param { compiler::driver &driver } %union { int num; char *str; } %token <str> STRING %token <num> NUMBER %token LET %token DELIM %% assignments : assignment | assignment assignments ; assignment : STRING LET NUMBER delims { std::cout << "(setf " << $1 << " " << $3 << ")\n"; } ; delims : DELIM | DELIM delims ; %% int main() { std::stringstream iss; iss << "a = 12;\n"; iss << "b = 32;; c =\n 18;\n"; iss << "b - 32;\n"; std::stringstream oss; reflex::Input i(iss); compiler::driver driver(i); return driver.parse(); } void compiler::parser::error(const location_type& loc, const std::string& msg) { std::cerr << msg << " at " << loc << std::endl; }
CXX= c++ all: compiler OBJS+= parser.o lexer.o LOCALBASE= /usr/local CFLAGS+= -Wall -I${LOCALBASE}/include LDFLAGS+= -L${LOCALBASE}/lib -lreflex compiler: ${OBJS} ${CXX} -o $@ ${OBJS} ${LDFLAGS} lexer.o: lexer.cc parser.cc ${CXX} ${CFLAGS} -c -o $@ $< lexer.cc: lexer.l reflex -o $@ $< parser.o: parser.cc lexer.cc ${CXX} ${CFLAGS} -c -o $@ $< parser.cc: parser.y bison -o $@ $< clean: rm -f lexer.cc lexer.hh rm -f parser.cc parser.hh location.hh position.hh stack.hh rm -f compiler *.o *~
input as
iss << "a = 12;\n"; iss << "b = 32;; c =\n 18;\n"; iss << "b - 32;\n";
$ make bison -o parser.cc parser.y reflex -o lexer.cc lexer.l c++ -Wall -I/usr/local/include -c -o parser.o parser.cc c++ -Wall -I/usr/local/include -c -o lexer.o lexer.cc c++ -o compiler parser.o lexer.o -L/usr/local/lib -lreflex $ ./compiler (setf a 12) (setf b 32) (setf c 18)