#define BOOST_SPIRIT_DEBUG #define BOOST_SPIRIT_LEXERTL_DEBUG #include #include #include #include #include #include using namespace boost::spirit; using boost::phoenix::val; inline std::string read_from_file( const char* infile ) { std::ifstream instream( infile ); if( !instream.is_open() ) { std::cerr << "Could not open file: \"" << infile << "\"" << std::endl; exit( -1 ); } instream.unsetf( std::ios::skipws ); return( std::string( std::istreambuf_iterator< char >( instream.rdbuf() ), std::istreambuf_iterator< char >() ) ); } template struct LangLexer : lex::lexer { LangLexer() { id = "[a-zA-Z_][a-zA-Z0-9_]*"; cte_i = "[0-9]+"; cte_f = "([0-9]+)|([0-9]*\\.[0-9]+)"; cte_string = "\".\""; si = "if"; sino = "else"; plan = "plan"; end_ = "end"; junta = "junta"; quack = "quack"; variable = "variable"; int_ = "int"; float_ = "float"; notEqual = "<>"; this->self = lex::token_def<>('(') | ')' | '=' | ';' | '[' | ']' | ',' | '+' | '-' | '<' | '>' ; this->self += plan | si | sino | end_ | junta | quack | variable | int_ | float_ | notEqual; this->self += id | cte_i | cte_string | cte_f; namespace lex = boost::spirit::lex; this->self //("WS") += lex::token_def<>("[ \\t\\n]+") [lex::_pass = lex::pass_flags::pass_ignore] | lex::string("\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/") [lex::_pass = lex::pass_flags::pass_ignore] ; } lex::token_def<> si, sino, plan, end_, junta, quack, variable, int_, float_, notEqual; lex::token_def id, cte_string; lex::token_def cte_i; lex::token_def cte_f; }; template< typename Iterator, typename Lexer > struct LangGrammar : qi::grammar< Iterator/*, qi::in_state_skipper */> { template< typename TokenDef > LangGrammar(TokenDef const& tok ) : LangGrammar::base_type(Patito2011) { Vars = tok.variable >> B >> C >> *( B >> C ); B = tok.id >> *(',' >> tok.id); C = ':' >> Tipo >> ';'; Tipo = tok.int_ | tok.float_; Parvada = '[' >> *Estatuto >> ']'; Estatuto = Copiar | Preguntar | Graznido | Juntar; Copiar = tok.id >> '=' >> Expresion >> ';'; Graznido = tok.quack >> '(' >> (Expresion | tok.cte_string) >> *(',' >> (Expresion | tok.cte_string)) >> ')'; Expresion = Exp >> -(('>' >> Exp) | ('<' >> Exp) | (tok.notEqual >> Exp)); Exp = Termino >> -(('+' >> Exp) | ('-' >> Exp)); Termino = Factor >> -(('*' >> Termino) | ('/' >> Termino)); Var_cte = tok.id | tok.cte_i | tok.cte_f; Factor = ('(' >> Expresion >> ')') | Var_cte | ('+' >> Var_cte | '-' >> Var_cte ); Preguntar = tok.si >> '(' >> Expresion >> Parvada >> -(tok.sino >> Parvada) >> ';'; Juntar = tok.junta >> '(' >> D >> ',' >> D >> ';'; D = Var_cte | tok.cte_string; Patito2011 = tok.plan >> tok.id >> ';' >> -Vars >> Parvada >> tok.end_; Patito2011.name("patito"); Vars.name("vars"); B.name("B"); C.name("C"); D.name("D"); Parvada.name("parvada"); Termino.name("termino"); Factor.name("factor"); Estatuto.name("est"); Copiar.name("copiar"); Graznido.name("graznido"); Juntar.name("juntar"); Preguntar.name("preguntar"); Expresion.name("expresion"); Exp.name("exp"); Var_cte.name("varcte"); Tipo.name("tipo"); debug(Patito2011); debug(Vars); debug(B); debug(C); debug(Tipo); debug(D); debug(Parvada); debug(Juntar); debug(Copiar); debug(Graznido); debug(Expresion); debug(Exp); debug(Preguntar); debug(Estatuto); debug(Var_cte); debug(Factor); debug(Termino); } qi::rule */> Vars, B, C, Tipo, Parvada, Preguntar, Estatuto, Copiar, Expresion, Var_cte, Exp, Termino, Factor, Graznido, Juntar, D, Patito2011;; }; int main( int argc, char** argv ) { typedef std::string::iterator base_iterator_type; typedef lex::lexertl::token< base_iterator_type, boost::mpl::vector > token_type; typedef lex::lexertl::actor_lexer lexer_type; typedef LangLexer LangLexer; typedef LangLexer::iterator_type iterator_type; typedef LangGrammar LangGrammar; LangLexer lexer; LangGrammar grammar(lexer); std::string str(read_from_file(argv[1])); base_iterator_type strBegin = str.begin(); iterator_type tokenItor = lexer.begin(strBegin, str.end()); iterator_type tokenItorEnd = lexer.end(); bool result = qi::/*phrase_*/parse( tokenItor, tokenItorEnd, grammar/*, qi::in_state("WS")[ lexer.self ] */); if( result ) { std::cout << "Parsing successful" << std::endl; } else { std::cout << "Parsing error" << std::endl; } return( 0 ); }