%{ #include #include #include %} %debug %skeleton "lalr1.cc" %name-prefix "delphin" %define parser_class_name "TdlParser" %locations %initial-action { @$.begin.filename = @$.end.filename = &grammar.grammarname(); } %parse-param {class Grammar &grammar} %error-verbose %union { std::string *sval; }; %code{ #include "grammar.h" std::string curr_status; } %token END 0 "EOF" %token COMM %token STRING %token REGEX %token ID %token INFLR %token LISP %token KW_DECLARE %token KW_DOMAIN %token KW_INSTANCE %token KW_LISP %token KW_TEMPLATE %token KW_TYPE %token KW_BEGIN %token KW_DEFDOMAIN %token KW_DELDOMAIN %token KW_DELETEPACKAGEP %token KW_END %token KW_ENDBANG %token KW_ERRORP %token KW_EXPANDALLINSTANCES %token KW_INCLUDE %token KW_LEVAL %token KW_SORTS %token KW_STATUS %token LDIFF "" %token ARROW "-->" %token ISEQ ":=" %token ISPLUS ":+" %token LANGLE "<" %token RANGLE ">" %token LBRACKET "[" %token RBRACKET "]" %token LPAREN "(" %token RPAREN ")" %token LBRACE "{" %token RBRACE "}" %token DOLLAR "$" %token CAP "^" %token AT "@" %token AMPERSAND "&" %token QUOTE "'" %token HASH "#" %token EQUALS "=" %token COLON ":" %token COMMA "," %token DOT "." %type att %type attval %type attvallist %type avmadd %type avmdef %type conj %type conjlist %type domain %type dottedatt %type dottedpair %type openconjlist %type term %destructor {delete $$;} %{ #include "grammar.h" #include "tdl-lexer.hpp" #undef yylex #define yylex grammar.lexer()->lex %} %% grammar: ; grammar: grammar COLON statement; grammar: grammar statement; grammar: grammar COLON KW_BEGIN block; grammar: grammar KW_BEGIN block ; statement: KW_DEFDOMAIN domain DOT { delete $2;}; statement: KW_DELDOMAIN domain domainopt DOT {delete $2; }; statement: KW_EXPANDALLINSTANCES DOT; statement: KW_INCLUDE STRING DOT { std::string fn(grammar.grammardir()); fn += "/"; fn += $2->substr(1); fn.erase(fn.find_last_of('"'), 1); if(grammar.lexer()->push_includefile(fn, &yyla.location)) { //std::cerr << "reading " << *$2 << std::endl; } else { grammar.error(yyla.location, std::string("Couldn't include file ") + *$2); YYERROR; } delete $2; }; statement: KW_LEVAL LISP DOT {delete $2;}; statement: KW_ENDBANG DOT; domain: COLON ID {$$ = $2;}; domain: QUOTE ID {$$ = $2;}; domain: STRING; domainopt:; domainopt: COLON KW_ERRORP ID {delete $3;}; domainopt: COLON KW_DELETEPACKAGEP ID {delete $3;} ; block: COLON domainblock; block: COLON instanceblock; block: COLON lispblock; block: COLON templateblock; block: COLON typeblock; domainblock: KW_DOMAIN domain tdllist domainend {delete $2;}; domainend: COLON KW_END COLON KW_DOMAIN domain DOT {delete $5;}; domainend: KW_END COLON KW_DOMAIN domain DOT {delete $4;}; tdllist:; tdllist: tdllist COLON KW_BEGIN block; tdllist: tdllist KW_BEGIN block; tdllist: tdllist COLON statement; tdllist: tdllist statement; instanceblock: KW_INSTANCE COLON KW_STATUS ID {curr_status = std::string(*$4);} DOT deflist instanceend {curr_status = std::string(); delete $4;}; instanceblock: KW_INSTANCE DOT deflist instanceend; instanceend: COLON KW_END COLON KW_INSTANCE DOT; instanceend: KW_END COLON KW_INSTANCE DOT; typeblock: KW_TYPE DOT deflist typeend; typeend: COLON KW_END COLON KW_TYPE DOT; typeend: KW_END COLON KW_TYPE DOT; typedef: ID avmdef DOT { if (curr_status.compare("lex-entry") == 0 || curr_status.compare("generic-lex-entry") == 0) { grammar.set_letype(*$1, *$2); grammar.add_letype(*$2); } else { if (curr_status.compare("lex-rule") == 0) { grammar.add_lexrule(*$1); } } delete $1; delete $2; }; typedef: ID avmadd DOT {delete $1; delete $2;}; typedef: STRING avmdef DOT{ if (curr_status.compare("lex-entry") == 0) { grammar.set_letype(*$1, *$2); grammar.add_letype(*$2); } else { if (curr_status.compare("lex-rule") == 0) { grammar.add_lexrule(*$1); } } delete $1; delete $2; }; typedef: STRING avmadd DOT {delete $1; delete $2;}; lispblock: KW_LISP DOT lisplist lispend; lisplist: /*empty*/ |lisplist LISP {delete $2;} ; lispend: COLON KW_END COLON KW_LISP DOT | KW_END COLON KW_LISP DOT ; templateblock: KW_TEMPLATE DOT templatelist templateend; templateend: COLON KW_END COLON KW_TEMPLATE DOT | KW_END COLON KW_TEMPLATE DOT ; templatelist: /* unimplemented, never used */ /*empty*/ | templatelist ID template DOT {delete $2;} | templatelist COLON KW_BEGIN block | templatelist KW_BEGIN block | templatelist COLON statement | templatelist statement ; template: /* unimplemented, never used */ LPAREN RPAREN | LPAREN paramlist RPAREN; paramlist: /* unimplemented, never used */ param | paramlist COMMA param ; param: /* unimplemented, never used */ DOLLAR ID paramdef {delete $2;}; paramdef: /* unimplemented, never used? */ /*empty*/ | EQUALS conj {delete $2;} ; conj: term |conj AMPERSAND term {$$ = $1; delete $3;} ; avmdef: ISEQ inflrlist conj rule avmopts {$$ = $3;}; avmadd: ISPLUS conj rule avmopts {$$ = $2;}; inflrlist: /*empty*/ |inflrlist INFLR {delete $2;} ; rule: /*unimplemented, not used? */ /*empty*/ |ARROW term {delete $2;} ; avmopts: /*unimplemented, not used? */ /*empty*/ |avmopts COMMA KW_STATUS COLON ID {delete $5;} ; term: ID |QUOTE ID {$$ = new std::string("'"); *$$ += *$2; delete $2;} |STRING |REGEX |HASH ID {$$ = new std::string("#"); *$$ += *$2; delete $2;} |DOLLAR ID {$$ = new std::string("$"); *$$ += *$2; delete $2;} |AT ID template {$$ = new std::string("@"); *$$ += *$2; delete $2;} |LBRACKET RBRACKET {$$ = new std::string("empty feature term");} |LBRACKET attvallist RBRACKET {$$ = $2;} |LDIFF RDIFF {$$ = new std::string("empty diff list");} |LDIFF conjlist RDIFF {$$ = $2;} |LANGLE RANGLE {$$ = new std::string("empty list");} |LANGLE openconjlist dottedpair RANGLE {$$ = $2; *$$ += *$3; delete $3;} ; attvallist: attval |attvallist COMMA attval {$$ = $1; *$$ += ","; *$$ += *$3; delete $3;} ; attval: dottedatt conj {$$ = $1; *$$ += "="; *$$ += *$2; delete $2;}; dottedatt: att |dottedatt DOT att {$$ = $1; *$$ += "."; *$$ += *$3; delete $3;} ; att: ID |DOLLAR ID {$$ = new std::string("$"); *$$ += *$2; delete $2;} ; conjlist: conj |conjlist COMMA conj {$$ = $1; *$$ += ","; *$$ += *$3; delete $3;} ; openconjlist: conj |openconjlist COMMA DOT DOT DOT |openconjlist COMMA conj {$$ = $1; *$$ += ","; *$$ += *$3; delete $3;} ; dottedpair: /*empty*/ {$$ = new std::string();} | DOT conj {$$ = $2;} ; deflist: /*empty*/ |deflist typedef |deflist INFLR {delete $2;} |deflist COLON KW_BEGIN block |deflist KW_BEGIN block |deflist COLON statement |deflist statement ; %% void delphin::TdlParser::error(const TdlParser::location_type &l, const std::string &m) { grammar.error(l, m); }