problems with grammar using spirit

Hi! I'm new using spirit and I'm having trouble with the parser. I already make this scanner and parser using CocoR but I have had no succes with spirit. Patito2011 is the main grammar but when I read the input file it doen't follows this grammar it goes directly to the Vars grammar. I don't know what is wrong help is appreciated. Patito2011 = tok.plan >> tok.id >> ';' >> -Vars >> Parvada >> tok.end_; Thanks in advance. Heres the code ************************************************ #include <boost/config/warning_disable.hpp> #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/lex_lexertl.hpp> #include <iostream> #include <fstream> #include <string> 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<typename Lexer> struct LangLexer : lex::lexer<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; this->self("WS") = lex::token_def<>("[ \\t\\n]+") | "\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/" ; } lex::token_def<> si, sino, plan, end_, junta, quack, variable, int_, float_, notEqual; lex::token_def<std::string> id, cte_string; lex::token_def<unsigned int> cte_i; lex::token_def<float> cte_f; }; template< typename Iterator, typename Lexer > struct LangGrammar : qi::grammar< Iterator, qi::in_state_skipper<Lexer> > { 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<Iterator, qi::in_state_skipper<Lexer> > 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<float, unsigned int, std::string> > token_type; typedef lex::lexertl::lexer<token_type> lexer_type; typedef LangLexer<lexer_type> LangLexer; typedef LangLexer::iterator_type iterator_type; typedef LangGrammar<iterator_type, LangLexer::lexer_def> 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 ); } ***************************** and here is a sample input file plan adsadsad; variable x,y,z : int; t,a,b,c : float; [ si ( 2 > 1) [ junta("string", "hola"; x = 1; t = 1.23; y = (1 - 2) < (1 + 3); y = (1 - 2) <> (1 + 3); y = (1 - 2) > (1 + 3); quack("quack", 1); quack("quack", "hola"); quack("quack", (1 + 2)); ] sino http://boost.2283326.n4.nabble.com/file/n3775416/patito.txt patito.txt http://boost.2283326.n4.nabble.com/file/n3775416/LexerParser.cpp LexerParser.cpp [ junta("string", "hola"; x = 1; t = 1.23; y = (1 - 2) < (1 * 3); y = (1 - 2) <> (1 / 3); y = (1 - 2) > (1 + 3); quack("quack", 1); quack("quack", "hola"); quack("quack", (1 + 2)); ]; ] end ************************************************** -- View this message in context: http://boost.2283326.n4.nabble.com/problems-with-grammar-using-spirit-tp3775... Sent from the Boost - Dev mailing list archive at Nabble.com.

Hi! I'm new using spirit and I'm having trouble with the parser. I already make this scanner and parser using CocoR but I have had no succes with spirit. Patito2011 is the main grammar but when I read the input file it doen't follows this grammar it goes directly to the Vars grammar. I don't know what is wrong help is appreciated.
Patito2011 = tok.plan >> tok.id >> ';' >> -Vars >> Parvada >> tok.end_;
The reason your parser is failing is that your lexer does not recognize the ':' delimiting the variable declarations. Moreover, I'd suggest you change the way you skip whitespace. It's much more efficient if you do that in the lexer itself (by ignoring whitespace tokens) than to defer to the skipper. I'm attaching a (partially) corrected example which stops matching at the ':'. Regards Hartmut --------------- http://boost-spirit.com

Hi ! Thanks for the quick answer, this solved my problem but now I'm just having a little problem detecting string constants. I have the following regular expression in the lexer cte_string = "\".\""; and this grammar Graznido = tok.quack >> '(' >> (Expresion | tok.cte_string) >> *(',' >> (Expresion | tok.cte_string)) >> ')' >> ';'; it should accept something like this quack("hola", 1); but it fails to recognize it like something valid, it doesn't try to match "hola" with the cte_string, well that's what I think it's happening, because while debugging it tries to match it first with Expresion but fails and then it's like cte_string is not in the grammar. I dont't know what would be the better approach to detect a string constant with the parser. Thanks in advance I attach the code McJaml http://boost.2283326.n4.nabble.com/file/n3777837/Prueba.cpp Prueba.cpp -- View this message in context: http://boost.2283326.n4.nabble.com/problems-with-grammar-using-spirit-tp3775... Sent from the Boost - Dev mailing list archive at Nabble.com.
participants (3)
-
Hartmut Kaiser
-
McJaml
-
TONGARI