summaryrefslogtreecommitdiff
path: root/src/parser.y
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.y')
-rw-r--r--src/parser.y795
1 files changed, 385 insertions, 410 deletions
diff --git a/src/parser.y b/src/parser.y
index 70aebba..fd6b164 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -34,6 +34,7 @@
#include <unistd.h>
#endif
+#include "typedefs.h"
#include "module.h"
#include "expression.h"
#include "value.h"
@@ -43,50 +44,39 @@
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
-namespace fs = boost::filesystem;
+ namespace fs = boost::filesystem;
#include "boosty.h"
-int parser_error_pos = -1;
+ int parser_error_pos = -1;
-int parserlex(void);
-void yyerror(char const *s);
+ int parserlex(void);
+ void yyerror(char const *s);
-int lexerget_lineno(void);
-int lexerlex_destroy(void);
-int lexerlex(void);
+ int lexerget_lineno(void);
+ int lexerlex_destroy(void);
+ int lexerlex(void);
-std::vector<Module*> module_stack;
-Module *currmodule;
+ std::vector<Module*> module_stack;
+ Module *currmodule;
-extern void lexerdestroy();
-extern FILE *lexerin;
-extern const char *parser_input_buffer;
-const char *parser_input_buffer;
-std::string parser_source_path;
+ extern void lexerdestroy();
+ extern FILE *lexerin;
+ extern const char *parser_input_buffer;
+ const char *parser_input_buffer;
+ std::string parser_source_path;
-class ArgContainer {
-public:
- std::string argname;
- Expression *argexpr;
-};
-class ArgsContainer {
-public:
- std::vector<std::string> argnames;
- std::vector<Expression*> argexpr;
-};
-
-%}
+ %}
%union {
- char *text;
- double number;
- class Value *value;
- class Expression *expr;
- class ModuleInstantiation *inst;
- std::vector<ModuleInstantiation*> *instvec;
- class IfElseModuleInstantiation *ifelse;
- class ArgContainer *arg;
- class ArgsContainer *args;
+ char *text;
+ double number;
+ class Value *value;
+ class Expression *expr;
+ class ModuleInstantiation *inst;
+ std::vector<ModuleInstantiation*> *instvec;
+ class IfElseModuleInstantiation *ifelse;
+ Assignment *arg;
+ AssignmentList *args;
}
%token TOK_MODULE
@@ -139,427 +129,412 @@ public:
%%
input:
- /* empty */ |
- TOK_USE { currmodule->usedlibs[$1] = NULL; } input |
- statement input ;
+/* empty */ |
+TOK_USE { currmodule->usedlibs[$1] = NULL; } input |
+statement input ;
inner_input:
- /* empty */ |
- statement inner_input ;
+/* empty */ |
+statement inner_input ;
statement:
- ';' |
- '{' inner_input '}' |
- module_instantiation {
- if ($1) {
- currmodule->addChild($1);
- } else {
- delete $1;
- }
- } |
- TOK_ID '=' expr ';' {
- std::list<std::string>::iterator found = std::find(currmodule->assignments_var.begin(), currmodule->assignments_var.end(),$1);
- if (found != currmodule->assignments_var.end()) currmodule->assignments_var.erase(found);
- currmodule->assignments_var.push_back($1);
- currmodule->assignments[$1] = $3;
- } |
- TOK_MODULE TOK_ID '(' arguments_decl optional_commas ')' {
- Module *p = currmodule;
- module_stack.push_back(currmodule);
- currmodule = new Module();
- p->modules[$2] = currmodule;
- currmodule->argnames = $4->argnames;
- currmodule->argexpr = $4->argexpr;
- free($2);
- delete $4;
- } statement {
- currmodule = module_stack.back();
- module_stack.pop_back();
- } |
- TOK_FUNCTION TOK_ID '(' arguments_decl optional_commas ')' '=' expr {
- Function *func = new Function();
- func->argnames = $4->argnames;
- func->argexpr = $4->argexpr;
- func->expr = $8;
- currmodule->functions[$2] = func;
- free($2);
- delete $4;
- } ';' ;
+';' |
+'{' inner_input '}' |
+module_instantiation {
+ if ($1) {
+ currmodule->addChild($1);
+ } else {
+ delete $1;
+ }
+} |
+TOK_ID '=' expr ';' {
+ std::list<std::string>::iterator found = std::find(currmodule->assignments_var.begin(), currmodule->assignments_var.end(),$1);
+ if (found != currmodule->assignments_var.end()) currmodule->assignments_var.erase(found);
+ currmodule->assignments_var.push_back($1);
+ currmodule->assignments[$1] = $3;
+} |
+TOK_MODULE TOK_ID '(' arguments_decl optional_commas ')' {
+ Module *p = currmodule;
+ module_stack.push_back(currmodule);
+ currmodule = new Module();
+ p->modules[$2] = currmodule;
+ currmodule->definition_arguments = *$4;
+ free($2);
+ delete $4;
+} statement {
+ currmodule = module_stack.back();
+ module_stack.pop_back();
+ } |
+ TOK_FUNCTION TOK_ID '(' arguments_decl optional_commas ')' '=' expr {
+ Function *func = new Function();
+ func->definition_arguments = *$4;
+ func->expr = $8;
+ currmodule->functions[$2] = func;
+ free($2);
+ delete $4;
+ } ';' ;
/* Will return a dummy parent node with zero or more children */
children_instantiation:
- module_instantiation {
- $$ = new std::vector<ModuleInstantiation*>;
- if ($1) {
- $$->push_back($1);
- }
- } |
- '{' module_instantiation_list '}' {
- $$ = $2;
- } ;
+module_instantiation {
+ $$ = new std::vector<ModuleInstantiation*>;
+ if ($1) {
+ $$->push_back($1);
+ }
+} |
+'{' module_instantiation_list '}' {
+ $$ = $2;
+} ;
if_statement:
- TOK_IF '(' expr ')' children_instantiation {
- $$ = new IfElseModuleInstantiation();
- $$->argnames.push_back("");
- $$->argexpr.push_back($3);
- $$->setPath(parser_source_path);
-
- if ($$) {
- $$->children = *$5;
- } else {
- for (size_t i = 0; i < $5->size(); i++)
- delete (*$5)[i];
- }
- delete $5;
- } ;
+TOK_IF '(' expr ')' children_instantiation {
+ $$ = new IfElseModuleInstantiation();
+ $$->arguments.push_back(Assignment("", $3));
+ $$->setPath(parser_source_path);
+
+ if ($$) {
+ $$->children = *$5;
+ } else {
+ for (size_t i = 0; i < $5->size(); i++)
+ delete (*$5)[i];
+ }
+ delete $5;
+} ;
ifelse_statement:
- if_statement {
- $$ = $1;
- } |
- if_statement TOK_ELSE children_instantiation {
- $$ = $1;
- if ($$) {
- $$->else_children = *$3;
- } else {
- for (size_t i = 0; i < $3->size(); i++)
- delete (*$3)[i];
- }
- delete $3;
- } ;
+if_statement {
+ $$ = $1;
+} |
+if_statement TOK_ELSE children_instantiation {
+ $$ = $1;
+ if ($$) {
+ $$->else_children = *$3;
+ } else {
+ for (size_t i = 0; i < $3->size(); i++)
+ delete (*$3)[i];
+ }
+ delete $3;
+} ;
module_instantiation:
- '!' module_instantiation {
- $$ = $2;
- if ($$) $$->tag_root = true;
- } |
- '#' module_instantiation {
- $$ = $2;
- if ($$) $$->tag_highlight = true;
- } |
- '%' module_instantiation {
- $$ = $2;
- if ($$) $$->tag_background = true;
- } |
- '*' module_instantiation {
- delete $2;
- $$ = NULL;
- } |
- single_module_instantiation ';' {
- $$ = $1;
- } |
- single_module_instantiation children_instantiation {
- $$ = $1;
- if ($$) {
- $$->children = *$2;
- } else {
- for (size_t i = 0; i < $2->size(); i++)
- delete (*$2)[i];
- }
- delete $2;
- } |
- ifelse_statement {
- $$ = $1;
- } ;
+'!' module_instantiation {
+ $$ = $2;
+ if ($$) $$->tag_root = true;
+} |
+'#' module_instantiation {
+ $$ = $2;
+ if ($$) $$->tag_highlight = true;
+} |
+'%' module_instantiation {
+ $$ = $2;
+ if ($$) $$->tag_background = true;
+} |
+'*' module_instantiation {
+ delete $2;
+ $$ = NULL;
+} |
+single_module_instantiation ';' {
+ $$ = $1;
+} |
+single_module_instantiation children_instantiation {
+ $$ = $1;
+ if ($$) {
+ $$->children = *$2;
+ } else {
+ for (size_t i = 0; i < $2->size(); i++)
+ delete (*$2)[i];
+ }
+ delete $2;
+} |
+ifelse_statement {
+ $$ = $1;
+} ;
module_instantiation_list:
- /* empty */ {
- $$ = new std::vector<ModuleInstantiation*>;
- } |
- module_instantiation_list module_instantiation {
- $$ = $1;
- if ($$) {
- if ($2) $$->push_back($2);
- } else {
- delete $2;
- }
- } ;
+/* empty */ {
+ $$ = new std::vector<ModuleInstantiation*>;
+} |
+module_instantiation_list module_instantiation {
+ $$ = $1;
+ if ($$) {
+ if ($2) $$->push_back($2);
+ } else {
+ delete $2;
+ }
+} ;
single_module_instantiation:
- TOK_ID '(' arguments_call ')' {
- $$ = new ModuleInstantiation($1);
- $$->argnames = $3->argnames;
- $$->argexpr = $3->argexpr;
- $$->setPath(parser_source_path);
- free($1);
- delete $3;
- }
+TOK_ID '(' arguments_call ')' {
+ $$ = new ModuleInstantiation($1);
+ $$->arguments = *$3;
+ $$->setPath(parser_source_path);
+ free($1);
+ delete $3;
+}
expr:
- TOK_TRUE {
- $$ = new Expression(Value(true));
- } |
- TOK_FALSE {
- $$ = new Expression(Value(false));
- } |
- TOK_UNDEF {
- $$ = new Expression(Value::undefined);
- } |
- TOK_ID {
- $$ = new Expression();
- $$->type = "L";
- $$->var_name = $1;
- free($1);
- } |
- expr '.' TOK_ID {
- $$ = new Expression();
- $$->type = "N";
- $$->children.push_back($1);
- $$->var_name = $3;
- free($3);
- } |
- TOK_STRING {
- $$ = new Expression(Value(std::string($1)));
- free($1);
- } |
- TOK_NUMBER {
- $$ = new Expression(Value($1));
- } |
- '[' expr ':' expr ']' {
- Expression *e_one = new Expression(Value(1.0));
- $$ = new Expression();
- $$->type = "R";
- $$->children.push_back($2);
- $$->children.push_back(e_one);
- $$->children.push_back($4);
- } |
- '[' expr ':' expr ':' expr ']' {
- $$ = new Expression();
- $$->type = "R";
- $$->children.push_back($2);
- $$->children.push_back($4);
- $$->children.push_back($6);
- } |
- '[' optional_commas ']' {
- $$ = new Expression(Value(Value::VectorType()));
- } |
- '[' vector_expr optional_commas ']' {
- $$ = $2;
- } |
- expr '*' expr {
- $$ = new Expression();
- $$->type = "*";
- $$->children.push_back($1);
- $$->children.push_back($3);
- } |
- expr '/' expr {
- $$ = new Expression();
- $$->type = "/";
- $$->children.push_back($1);
- $$->children.push_back($3);
- } |
- expr '%' expr {
- $$ = new Expression();
- $$->type = "%";
- $$->children.push_back($1);
- $$->children.push_back($3);
- } |
- expr '+' expr {
- $$ = new Expression();
- $$->type = "+";
- $$->children.push_back($1);
- $$->children.push_back($3);
- } |
- expr '-' expr {
- $$ = new Expression();
- $$->type = "-";
- $$->children.push_back($1);
- $$->children.push_back($3);
- } |
- expr '<' expr {
- $$ = new Expression();
- $$->type = "<";
- $$->children.push_back($1);
- $$->children.push_back($3);
- } |
- expr LE expr {
- $$ = new Expression();
- $$->type = "<=";
- $$->children.push_back($1);
- $$->children.push_back($3);
- } |
- expr EQ expr {
- $$ = new Expression();
- $$->type = "==";
- $$->children.push_back($1);
- $$->children.push_back($3);
- } |
- expr NE expr {
- $$ = new Expression();
- $$->type = "!=";
- $$->children.push_back($1);
- $$->children.push_back($3);
- } |
- expr GE expr {
- $$ = new Expression();
- $$->type = ">=";
- $$->children.push_back($1);
- $$->children.push_back($3);
- } |
- expr '>' expr {
- $$ = new Expression();
- $$->type = ">";
- $$->children.push_back($1);
- $$->children.push_back($3);
- } |
- expr AND expr {
- $$ = new Expression();
- $$->type = "&&";
- $$->children.push_back($1);
- $$->children.push_back($3);
- } |
- expr OR expr {
- $$ = new Expression();
- $$->type = "||";
- $$->children.push_back($1);
- $$->children.push_back($3);
- } |
- '+' expr {
- $$ = $2;
- } |
- '-' expr {
- $$ = new Expression();
- $$->type = "I";
- $$->children.push_back($2);
- } |
- '!' expr {
- $$ = new Expression();
- $$->type = "!";
- $$->children.push_back($2);
- } |
- '(' expr ')' {
- $$ = $2;
- } |
- expr '?' expr ':' expr {
- $$ = new Expression();
- $$->type = "?:";
- $$->children.push_back($1);
- $$->children.push_back($3);
- $$->children.push_back($5);
- } |
- expr '[' expr ']' {
- $$ = new Expression();
- $$->type = "[]";
- $$->children.push_back($1);
- $$->children.push_back($3);
- } |
- TOK_ID '(' arguments_call ')' {
- $$ = new Expression();
- $$->type = "F";
- $$->call_funcname = $1;
- $$->call_argnames = $3->argnames;
- $$->children = $3->argexpr;
- free($1);
- delete $3;
- } ;
+TOK_TRUE {
+ $$ = new Expression(Value(true));
+} |
+TOK_FALSE {
+ $$ = new Expression(Value(false));
+} |
+TOK_UNDEF {
+ $$ = new Expression(Value::undefined);
+} |
+TOK_ID {
+ $$ = new Expression();
+ $$->type = "L";
+ $$->var_name = $1;
+ free($1);
+} |
+expr '.' TOK_ID {
+ $$ = new Expression();
+ $$->type = "N";
+ $$->children.push_back($1);
+ $$->var_name = $3;
+ free($3);
+} |
+TOK_STRING {
+ $$ = new Expression(Value(std::string($1)));
+ free($1);
+} |
+TOK_NUMBER {
+ $$ = new Expression(Value($1));
+} |
+'[' expr ':' expr ']' {
+ Expression *e_one = new Expression(Value(1.0));
+ $$ = new Expression();
+ $$->type = "R";
+ $$->children.push_back($2);
+ $$->children.push_back(e_one);
+ $$->children.push_back($4);
+} |
+'[' expr ':' expr ':' expr ']' {
+ $$ = new Expression();
+ $$->type = "R";
+ $$->children.push_back($2);
+ $$->children.push_back($4);
+ $$->children.push_back($6);
+} |
+'[' optional_commas ']' {
+ $$ = new Expression(Value(Value::VectorType()));
+} |
+'[' vector_expr optional_commas ']' {
+ $$ = $2;
+} |
+expr '*' expr {
+ $$ = new Expression();
+ $$->type = "*";
+ $$->children.push_back($1);
+ $$->children.push_back($3);
+} |
+expr '/' expr {
+ $$ = new Expression();
+ $$->type = "/";
+ $$->children.push_back($1);
+ $$->children.push_back($3);
+} |
+expr '%' expr {
+ $$ = new Expression();
+ $$->type = "%";
+ $$->children.push_back($1);
+ $$->children.push_back($3);
+} |
+expr '+' expr {
+ $$ = new Expression();
+ $$->type = "+";
+ $$->children.push_back($1);
+ $$->children.push_back($3);
+} |
+expr '-' expr {
+ $$ = new Expression();
+ $$->type = "-";
+ $$->children.push_back($1);
+ $$->children.push_back($3);
+} |
+expr '<' expr {
+ $$ = new Expression();
+ $$->type = "<";
+ $$->children.push_back($1);
+ $$->children.push_back($3);
+} |
+expr LE expr {
+ $$ = new Expression();
+ $$->type = "<=";
+ $$->children.push_back($1);
+ $$->children.push_back($3);
+} |
+expr EQ expr {
+ $$ = new Expression();
+ $$->type = "==";
+ $$->children.push_back($1);
+ $$->children.push_back($3);
+} |
+expr NE expr {
+ $$ = new Expression();
+ $$->type = "!=";
+ $$->children.push_back($1);
+ $$->children.push_back($3);
+} |
+expr GE expr {
+ $$ = new Expression();
+ $$->type = ">=";
+ $$->children.push_back($1);
+ $$->children.push_back($3);
+} |
+expr '>' expr {
+ $$ = new Expression();
+ $$->type = ">";
+ $$->children.push_back($1);
+ $$->children.push_back($3);
+} |
+expr AND expr {
+ $$ = new Expression();
+ $$->type = "&&";
+ $$->children.push_back($1);
+ $$->children.push_back($3);
+} |
+expr OR expr {
+ $$ = new Expression();
+ $$->type = "||";
+ $$->children.push_back($1);
+ $$->children.push_back($3);
+} |
+'+' expr {
+ $$ = $2;
+} |
+'-' expr {
+ $$ = new Expression();
+ $$->type = "I";
+ $$->children.push_back($2);
+} |
+'!' expr {
+ $$ = new Expression();
+ $$->type = "!";
+ $$->children.push_back($2);
+} |
+'(' expr ')' {
+ $$ = $2;
+} |
+expr '?' expr ':' expr {
+ $$ = new Expression();
+ $$->type = "?:";
+ $$->children.push_back($1);
+ $$->children.push_back($3);
+ $$->children.push_back($5);
+} |
+expr '[' expr ']' {
+ $$ = new Expression();
+ $$->type = "[]";
+ $$->children.push_back($1);
+ $$->children.push_back($3);
+} |
+TOK_ID '(' arguments_call ')' {
+ $$ = new Expression();
+ $$->type = "F";
+ $$->call_funcname = $1;
+ $$->call_arguments = *$3;
+ free($1);
+ delete $3;
+} ;
optional_commas:
- ',' optional_commas | ;
+',' optional_commas | ;
vector_expr:
- expr {
- $$ = new Expression();
- $$->type = 'V';
- $$->children.push_back($1);
- } |
- vector_expr ',' optional_commas expr {
- $$ = $1;
- $$->children.push_back($4);
- } ;
+expr {
+ $$ = new Expression();
+ $$->type = 'V';
+ $$->children.push_back($1);
+} |
+vector_expr ',' optional_commas expr {
+ $$ = $1;
+ $$->children.push_back($4);
+} ;
arguments_decl:
- /* empty */ {
- $$ = new ArgsContainer();
- } |
- argument_decl {
- $$ = new ArgsContainer();
- $$->argnames.push_back($1->argname);
- $$->argexpr.push_back($1->argexpr);
- delete $1;
- } |
- arguments_decl ',' optional_commas argument_decl {
- $$ = $1;
- $$->argnames.push_back($4->argname);
- $$->argexpr.push_back($4->argexpr);
- delete $4;
- } ;
+/* empty */ {
+ $$ = new AssignmentList();
+} |
+argument_decl {
+ $$ = new AssignmentList();
+ $$->push_back(*$1);
+ delete $1;
+} |
+arguments_decl ',' optional_commas argument_decl {
+ $$ = $1;
+ $$->push_back(*$4);
+ delete $4;
+} ;
argument_decl:
- TOK_ID {
- $$ = new ArgContainer();
- $$->argname = $1;
- $$->argexpr = NULL;
- free($1);
- } |
- TOK_ID '=' expr {
- $$ = new ArgContainer();
- $$->argname = $1;
- $$->argexpr = $3;
- free($1);
- } ;
+TOK_ID {
+ $$ = new Assignment($1, NULL);
+ free($1);
+} |
+TOK_ID '=' expr {
+ $$ = new Assignment($1, $3);
+ free($1);
+} ;
arguments_call:
- /* empty */ {
- $$ = new ArgsContainer();
- } |
- argument_call {
- $$ = new ArgsContainer();
- $$->argnames.push_back($1->argname);
- $$->argexpr.push_back($1->argexpr);
- delete $1;
- } |
- arguments_call ',' optional_commas argument_call {
- $$ = $1;
- $$->argnames.push_back($4->argname);
- $$->argexpr.push_back($4->argexpr);
- delete $4;
- } ;
+/* empty */ {
+ $$ = new AssignmentList();
+} |
+argument_call {
+ $$ = new AssignmentList();
+ $$->push_back(*$1);
+ delete $1;
+} |
+arguments_call ',' optional_commas argument_call {
+ $$ = $1;
+ $$->push_back(*$4);
+ delete $4;
+} ;
argument_call:
- expr {
- $$ = new ArgContainer();
- $$->argexpr = $1;
- } |
- TOK_ID '=' expr {
- $$ = new ArgContainer();
- $$->argname = $1;
- $$->argexpr = $3;
- free($1);
- } ;
+expr {
+ $$ = new Assignment("", $1);
+} |
+TOK_ID '=' expr {
+ $$ = new Assignment($1, $3);
+ free($1);
+} ;
%%
int parserlex(void)
{
- return lexerlex();
+ return lexerlex();
}
void yyerror (char const *s)
{
- // FIXME: We leak memory on parser errors...
- PRINTB("Parser error in line %d: %s\n", lexerget_lineno() % s);
- currmodule = NULL;
+ // FIXME: We leak memory on parser errors...
+ PRINTB("Parser error in line %d: %s\n", lexerget_lineno() % s);
+ currmodule = NULL;
}
Module *parse(const char *text, const char *path, int debug)
{
- lexerin = NULL;
- parser_error_pos = -1;
- parser_input_buffer = text;
- parser_source_path = boosty::absolute(std::string(path)).string();
+ lexerin = NULL;
+ parser_error_pos = -1;
+ parser_input_buffer = text;
+ parser_source_path = boosty::absolute(std::string(path)).string();
- module_stack.clear();
- Module *rootmodule = currmodule = new Module();
- // PRINTB_NOCACHE("New module: %s %p", "root" % rootmodule);
+ module_stack.clear();
+ Module *rootmodule = currmodule = new Module();
+ rootmodule->setModulePath(path);
+ // PRINTB_NOCACHE("New module: %s %p", "root" % rootmodule);
- parserdebug = debug;
- int parserretval = parserparse();
- lexerdestroy();
- lexerlex_destroy();
+ parserdebug = debug;
+ int parserretval = parserparse();
+ lexerdestroy();
+ lexerlex_destroy();
- if (parserretval != 0) return NULL;
+ if (parserretval != 0) return NULL;
- parser_error_pos = -1;
- return rootmodule;
+ parser_error_pos = -1;
+ return rootmodule;
}
contact: Jan Huwald // Impressum