1
When I enter the input tt or tt the program returns me "parse failed". However, to me the grammar seems correct, so I believe it is some peculiarity of the library. Would anyone like to explain the reason for the mistake? Just follow my code.
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <iostream>
#include <string>
#include <complex>
#include <vector>
namespace client
{
namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
enum operators {op_plus, op_minus, op_times};
//Declaration Types
struct declaration;
typedef boost::variant<int, std::string> valueType;
struct dec
{
std::string tipoVarOuCons;
std::string variable;
valueType value;
};
typedef
boost::variant<
boost::recursive_wrapper<declaration>
, dec
>
declarationTree;
struct declaration
{
std::vector<declarationTree> children;
};
//Expression Types
struct expOp;
struct orExp;
struct notExp;
struct eqExp;
using expression = boost::variant< int,std::string,boost::recursive_wrapper<expOp>>;
using boolExpression = boost::variant<std::string, eqExp, boost::recursive_wrapper<orExp>, boost::recursive_wrapper<notExp>>;
struct expOp
{
expression exp1;
std::vector<std::pair<std::string, expression>> exp2;
};
struct eqExp
{
expression exp1;
std::string op;
expression exp2;
};
struct assignment
{
std::string variable;
std::string symbol;
expression exp;
};
struct orExp
{
boolExpression exp1;
std::string symbol;
boolExpression exp2;
};
struct notExp
{
std::string symbol;
boolExpression exp;
};
}
//Declaration Fusion
BOOST_FUSION_ADAPT_STRUCT(
client::dec,
(std::string, tipoVarOuCons)
(std::string, variable)
(client::valueType, value)
)
BOOST_FUSION_ADAPT_STRUCT(
client::declaration,
(std::vector<client::declarationTree>, children)
)
//Expression Fusion
BOOST_FUSION_ADAPT_STRUCT(
client::expOp,exp1, exp2)
BOOST_FUSION_ADAPT_STRUCT(
client::eqExp,exp1,op, exp2)
BOOST_FUSION_ADAPT_STRUCT(
client::assignment,variable,symbol, exp)
//Boolean Fusion
BOOST_FUSION_ADAPT_STRUCT(
client::orExp,exp1,symbol, exp2)
BOOST_FUSION_ADAPT_STRUCT(
client::notExp,symbol, exp)
namespace client
{
template <typename Iterator>
struct ast_parser : qi::grammar<Iterator, boolExpression(), ascii::space_type>
{
ast_parser() : ast_parser::base_type(boolExpressionR)
{
using qi::int_;
using qi::lit;
using qi::double_;
using qi::lexeme;
using ascii::char_;
using qi::string;
string_ %= lexeme[+(char_ - ' ')];
typeR %= string("var") | string("cons");
boolean %= string("tt") | string("ff");
value %= qi::int_ | boolean;
declarationAtom %= typeR >> string_ >> value;
boperator %= string("+") | string("-") | string("*");
simpleExpression %= ( '(' > expressionR > ')' ) | qi::int_ | string_;
expOperator %= simpleExpression >> *(boperator > expressionR);
expressionR %= expOperator;
equalExpression %= expressionR >> string("==") >> expressionR;
orExpression %= boolExpressionR >> string("or") >> boolExpressionR;
notExpression %= string("!") >> boolExpressionR;
boolExpressionR %= boolean | equalExpression | orExpression | notExpression;
assignmentR %= string_ >> string("=") >> expressionR;
//ifCommand %= lit("if") >> boolExpression >> lit("then") >> command >> lit("else") >> command;
//command %= string("nil") | (command >> lit(";") >> command) | assignment | ifCommand | whileCommand;
//declarationR %= declarations | declarationL;
//program %= declarations;
}
qi::rule<Iterator, std::string(), ascii::space_type> string_;
qi::rule<Iterator, std::string(), ascii::space_type> typeR;
qi::rule<Iterator, std::string(), ascii::space_type> boolean;
qi::rule<Iterator, valueType(), ascii::space_type> value;
qi::rule<Iterator, std::string(), ascii::space_type> boperator;
//qi::rule<Iterator, declaration(), ascii::space_type> declarationL;
qi::rule<Iterator, dec(), ascii::space_type> declarationAtom;
qi::rule<Iterator, expression(), ascii::space_type> simpleExpression;
qi::rule<Iterator, expOp(), ascii::space_type> expOperator;
qi::rule<Iterator, expression(), ascii::space_type> expressionR;
qi::rule<Iterator, eqExp(), ascii::space_type> equalExpression;
qi::rule<Iterator, assignment(), ascii::space_type> assignmentR;
qi::rule<Iterator, orExp(), ascii::space_type> orExpression;
qi::rule<Iterator, notExp(), ascii::space_type> notExpression;
qi::rule<Iterator, boolExpression(), ascii::space_type> boolExpressionR;
//qi::rule<Iterator, declaration(), ascii::space_type> declarations;
//qi::rule<Iterator, program(), ascii::space_type> program;
//qi::rule<Iterator, dec(), ascii::space_type> declarationAtom;
};
//]
}
int
main()
{
using boost::spirit::ascii::space;
typedef std::string::const_iterator iterator_type;
typedef client::ast_parser<iterator_type> ast_parser;
ast_parser g; // Our grammar
std::string str;
//client::dec d;
while (getline(std::cin, str))
{
if (str.empty() || str[0] == 'q' || str[0] == 'Q')
break;
std::string::const_iterator iter = str.begin();
std::string::const_iterator end = str.end();
bool r = phrase_parse(iter, end, g, space);
if (r && iter == end)
{
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
// std::cout<<d.tipoVarOuCons;
std::cout << "\n-------------------------\n";
}
else
{
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "-------------------------\n";
}
}
std::cout << "Bye... :-) \n\n";
return 0;
}
EDIT:
The grammar is this:
using qi::int_;
using qi:lit;
using qi::double_;
using qi:lexeme;
using ascii::char_;
using qi::string;
string_ %= lexeme[+(char_ - ' ')];
Typer %= string("var") | string("cons");
Boolean %= string("tt") | string("ff");
value %= qi::int_ | Boolean;
declarationAtom %= Typer >> string_>> value;
boperator %= string("+") | string("-") | string("*");
simpleExpression %= ( '(' > expressionR > ')' ) | qi::int_ | string_;
expOperator %= simpleExpression >> *(boperator > expressionR);
expressionR %= expOperator;
equalExpression %= expressionR >> string("==") >> expressionR;
orExpression %= boolExpressionR >>string("or") >> boolExpressionR;
notExpression %= string("!") >> boolExpressionR;
boolExpressionR %= Boolean | equalExpression | orExpression | notExpression;
assignmentR %= string_>> string("=") >> expressionR;
You can make it more visible, preferably outside the code in another block, which grammar you are using?
– Jefferson Quesado
I put the grammar at the end. I am sorry, I had put a way that I found to make it work, which would put the OR >> boolExpressionR >> boolExpressionR. But it wasn’t what I wanted. With this graph I’m passing tt or ff using boolExpressionR as a start but it’s giving "parse failed".
– Lucas Hippertt