From 900976d2d74e0de57858b265c2ef0d17a29e921a Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Sun, 30 Jul 2006 06:39:27 +0000 Subject: Found out all of the c++ stuff in bison broke in 2.2, now we have to pick a version, there is no way around it nicely. --- src/build.l | 77 +++++++++++++++++++++++++++++++++++++++++++++--- src/build.y | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/builder.cpp | 34 +++++++++++++++++++++ src/builder.h | 36 +++++++++++++++++++++++ src/main.cpp | 9 ++++++ 5 files changed, 243 insertions(+), 4 deletions(-) create mode 100644 src/builder.cpp create mode 100644 src/builder.h (limited to 'src') diff --git a/src/build.l b/src/build.l index 6daaa94..6a80f45 100644 --- a/src/build.l +++ b/src/build.l @@ -1,4 +1,20 @@ - int lineNum = 1; +%{ +# include +# include "builder.h" +# include "build.tab.h" +# include "stringrep.h" + +std::string strbuf; +%} + +%x strsq +%x strdq +%x comment +%option noyywrap nounput batch debug + +%{ +# define YY_USER_ACTION yylloc->columns (yyleng); +%} %% [,:=] return yytext[0]; @@ -23,9 +39,62 @@ "produces" return TOK_PRODUCES; "command" return TOK_COMMAND; +"..."\n /* elipsis line continuation */ \n+ return TOX_EOL; -[ \t\r]* +[ \t\r]* /* whitespace */ + +\/\/.* /* single line comment */ +"#".* /* single line comment */ + +[^ \t\r\n\'\"]+ { + yylval.strval = stringdup( yytext ); + return STRING; +} + +\" { + BEGIN( strdq ); + strbuf = ""; +} +\' { + BEGIN( strsq ); + strbuf = ""; +} + +[^\\\n\"]+ { + strbuf += yytext; +} + +[^\\\n\']+ { + strbuf += yytext; +} + +\\n strbuf += "\n"; +\\t strbuf += "\t"; +\\r strbuf += "\r"; +\\b strbuf += "\b"; +\\f strbuf += "\f"; + +\" { + BEGIN( INITIAL ); + yylval->strval = stringdup( strbuf.c_str() ); + return STRING; +} + +\' { + BEGIN( INITIAL ); + yylval->strval = stringdup( strbuf.c_str() ); + return STRING; +} + + +void Builder::scanBegin() +{ + if( !(yyin = fopen( file.c_str(), "r" )) ) + error( std::string("cannot open ") + file ); +} -\/\/.* -"#".* +void Builder::scanEnd() +{ + fclose( yyin ); +} diff --git a/src/build.y b/src/build.y index e69de29..600b923 100644 --- a/src/build.y +++ b/src/build.y @@ -0,0 +1,91 @@ +%skeleton "lalr1.cc" +%define "parser_class_name" "BuildParser" +%defines +%{ +# include +# include "builder.h" +# include "build.tab.h" +%} + +%parse-param { Builder &bld } +%lex-param { Builder &bld } + +%locations +%initial-action +{ + @$.begin.filename = @$.end.filename = &bld.file; +} + +%debug +%error-verbose +%union { + char *strval; +} + +%token STRING "string literal" + +%token TOK_ADDSET "+=" +%token TOK_DEFAULT "keyword 'default'" +%token TOK_ACTION "keyword 'action'" +%token TOK_CREATE "keyword 'create'" +%token TOK_FILE "keyword 'file'" +%token TOK_FROM "keyword 'from'" +%token TOK_FILES "keyword 'files'" +%token TOK_IN "keyword 'in'" +%token TOK_USING "keyword 'using'" +%token TOK_RULE "keyword 'rule'" +%token TOK_REQUIRES "keyword 'requires'" +%token TOK_FOR "keyword 'for'" +%token TOK_SET "keyword 'set'" +%token TOK_MATCHES "keyword 'matches'" +%token TOK_ALL "keyword 'all'" +%token TOK_ONE "keyword 'one'" +%token TOK_PERFORM "keyword 'perform'" +%token TOK_PRODUCES "keyword 'produces'" +%token TOK_COMMAND "keyword 'command'" +%token TOK_EOL "end of line" + +%destructor { delete[] $$; } STRING + +%% + +input: + | input line + ; + +line: stuff TOK_EOL { printf("\n"); } + ; + +stuff: + | stuff token + ; + +token: TOK_ADDSET { printf("+= "); } + | TOK_DEFAULT { printf("default "); } + | TOK_ACTION { printf("action "); } + | TOK_CREATE { printf("create "); } + | TOK_FILE { printf("file "); } + | TOK_FROM { printf("from "); } + | TOK_FILES { printf("files "); } + | TOK_IN { printf("in "); } + | TOK_USING { printf("using "); } + | TOK_RULE { printf("rule "); } + | TOK_REQUIRES { printf("requires "); } + | TOK_FOR { printf("for "); } + | TOK_SET { printf("set "); } + | TOK_MATCHES { printf("matches "); } + | TOK_ALL { printf("all "); } + | TOK_ONE { printf("one "); } + | TOK_PERFORM { printf("perform "); } + | TOK_PRODUCES { printf("produces "); } + | TOK_COMMAND { printf("command "); } + ; + +%% + +void yy::BuildParser::error( const yy::BuildParser::location_type &l, + const std::string &m ) +{ + bld.error( l, m ); +} + diff --git a/src/builder.cpp b/src/builder.cpp new file mode 100644 index 0000000..8c72fef --- /dev/null +++ b/src/builder.cpp @@ -0,0 +1,34 @@ +#include + +#include "builder.h" +#include "build.tab.h" + +Builder::Builder() +{ +} + +Builder::~Builder() +{ +} + +void Builder::load( const char *sFN ) +{ + file = sFN; + + scanBegin(); + yy::BuildParser parser( *this ); + parser.set_debug_level( false ); + parser.parse(); + scanEnd(); +} + +void Builder::error( const yy::location &l, const std::string &m ) +{ + std::cerr << l << ": " << m << std::endl; +} + +void Builder::error( const std::string &m ) +{ + std::cerr << m << std::endl; +} + diff --git a/src/builder.h b/src/builder.h new file mode 100644 index 0000000..e379608 --- /dev/null +++ b/src/builder.h @@ -0,0 +1,36 @@ +#ifndef BUILDER_H +#define BUILDER_H + +#include + +union YYSTYPE; + +namespace yy +{ + class location; + class BuildParser; +} +class Builder; + +#define YY_DECL int yylex( YYSTYPE *yylval_param, yy::location *yylloc, Builder &bld ) +YY_DECL; + +class Builder +{ +public: + Builder(); + virtual ~Builder(); + + void load( const char *sFN ); + + void error( const yy::location &l, const std::string &m ); + void error( const std::string &m ); + + std::string file; + +private: + void scanBegin(); + void scanEnd(); +}; + +#endif diff --git a/src/main.cpp b/src/main.cpp index e69de29..7e130bc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -0,0 +1,9 @@ +#include "builder.h" + +int main() +{ + Builder bld; + + bld.load("congo"); +} + -- cgit v1.2.3