Implementing "NOT" in boost::spirit mini_c - c++

I tried to modify the mini_c example of boost::spirit to match to my existing vocabulary.
I therefore added a operator "NOT that should behave equal as "!":
unary_expr =
primary_expr
| ("NOT" > primary_expr [op(op_not)]) // This does not work
| ('!' > primary_expr [op(op_not)])
| ('-' > primary_expr [op(op_neg)])
| ('+' > primary_expr)
;
I can compile the modified source code, but when i try to execute it it fails to parse. How can i solve this?
EDIT:
As my want to access external variables, i had made another modification in order to build a list of these variables when compiling:
identifier %=
raw[lexeme[alpha >> *(alnum | 'ยง' | '_' | '.' | '-' )]]
;
variable =
identifier [add_var(_1)]
;
Where add_var and identifier are defined as
rule<Iterator, std::string(), white_space> identifier;
function<var_adder> add_var;
If i don't use this modification, "NOT" can be used. With the modification, using "NOT" generates a parsing error.
EDIT 2:
The following conditional expressions do work though:
logical_expr =
relational_expr
>> *( ("AND" > relational_expr [op(op_and)])
| ("OR" > relational_expr [op(op_or)])
)
;

With your change the small test:
int main()
{
return NOT 1;
}
parses successfully and returns 0. So it is not obvious to me what doesn't work for you. Could you provide a failing input example as well, please?

Related

Spirit Qi: Error when replacing sequence with expectation operator

I have a grammar that works perfectly fine and contains the following lines.
element = container | list | pair;
container = name >> '(' >> -(arg % ',') >> ')' >> '{' >> +element > '}';
// trying to put an expectation operator here --------^
list = name >> '(' > (value % ',') > ')' > ';';
pair = name >> ':' > value > ';';
To have meaningful error messages, I want to make sure that container does not backtrack as soon as it hits '{'. But for some reason, if I replace the sequence operator with an expectation operator right after the '{', I get a huge compiler error. Any ideas what the problem might be?
element is a boost::variant; container, list and pair are own structs with BOOST_FUSION_ADAPT_STRUCT applied. Please have a look here for the full source code: https://github.com/fklemme/liberty_tool/blob/master/src/liberty_grammar.hpp#L24
Yes. Because the precedences of operator>> and operator> aren't equal, the resulting synthesized attribute type is different.
In fact, it is no longer automatically compatible with the intended exposed attribute type.
In this case the problem can be quickly neutralized with some disambiguating parentheses around the sub-expression:
container = name >> '(' >> -(arg % ',') >> ')' >> ('{' > +element > '}');

Parsing recursive rules with spirit x3

I would like to parse the following recusive rule which parses simple template classe identifier like foo<bar> foo<bar,baz> foo<bar<baz>> here is the simple grammar:
identifier := A-Z | a-z | _
class_identifier = identifier ?("<" identifier|class_identifier
( "," identifier|class_identifier)*
">")
I tried to write a parser with x3 like this:
auto const identifier = x3::rule<class identifier_id, std::string>{"identifier"}
= +x3::char_("A-Za-z");
x3::rule<class class_identifier, std::string> class_identifier = "class_identifier";
auto const class_identifier_def = identifier //classname
>> -(x3::string("<")
>> (identifier | class_identifier)
>> *(x3::string(",")
>> (identifier | class_identifier))
>> x3::string(">"));
BOOST_SPIRIT_DEFINE(class_identifier)
But this try fails to parse stuff like this foo<bar<baz>> but foo is fine.
Is there some logical error in my grammar or am I using boost spirit wrong since this is a recursive rule?
I have found why this fails to parse. I hade to change this (identifier | class_identifier) to this (class_identifier | identifier) because it also the class_identifier rule also starts with an identifier. thats why it tried to parse everytime with the identifier rule and then fails at the <

Boost::Spirit placeholders and alternative parser

// 1
Mexpression = Mterm >> *(
'+' >> Mterm [qi::_val = phoenix::new_<BinaryNode>(_1, '+', _2)]
| '-' >> Mterm [qi::_val = phoenix::new_<BinaryNode>(_1, '-', _2)]
);
Mterm = Mfactor >> *(
'*' >> Mfactor [qi::_val = phoenix::new_<BinaryNode>(_1, '*', _2)]
| '/' >> Mfactor [qi::_val = phoenix::new_<BinaryNode>(_1, '/', _2)]
);
Mfactor = Unpack
| '+' >> Mfactor [qi::_val = phoenix::new_<UnaryNode>('+', _1)]
| '-' >> Mfactor [qi::_val = phoenix::new_<UnaryNode>('-', _1)]
| '(' >> Mexpression >> ')';`
`Error 2 error C2664: 'BinaryNode::BinaryNode(const BinaryNode &)' : cannot convert argument 3 from 'boost::mpl::void_' to 'anExpression *' c:\boost_1_55_0\boost\spirit\home\phoenix\object\detail\new_eval.hpp 41 1 ConsoleApplication1
Error 1 error C2338: index_is_out_of_bounds c:\boost_1_55_0\boost\spirit\home\support\argument.hpp 103 1 ConsoleApplication1 `
And
c:\boost_1_55_0\boost\spirit\home\support\argument.hpp(166) : see reference to class template instantiation 'boost::spirit::result_of::get_arg<boost::fusion::vector1<Attribute &>,1>' being compiled with
[
Attribute=anExpression *
]
I'm coding a translator for a model language (there are several ebnf with main compositions given as a task.) and stuck somewhere at arithmetical operations.
(see 1 in paste)
here's a model to parse math' exprs,
unpack is somenode, something that can be executed, converted to anExpression *, and given as arg to BinaryNode
there are following rules.
qi::rule<Iterator, anExpression *()> Unpack;
qi::rule<Iterator, anExpression *()> Mexpression, Mterm, Mfactor;
anExpression is an abstract class (Binary and Unary are public anExpression)
while compiling the whole program I have following errors:
fig2
I think that error 2 is the most important thing to fix first.
something like this in build log
fig3
okay, I think that the mistake is in my way of semantic actions. I think there's not Mterm (or Mfactor) in _2 placeholder. there's something I'm doing wrong with this way of using semantics actions and alternative parser ( '|' )
I'll be glad to hear any ideas from you guys =)
Mexpression = Mterm >> *(
'+' >> Mterm [qi::_val = phoenix::new_<BinaryNode>(_1, '+', _2)]
| '-' >> Mterm [qi::_val = phoenix::new_<BinaryNode>(_1, '-', _2)]
);
Can't work indeed. You'd need to temporarily store the result attribute of the lhs Mterm. Luckily you should be able to use the result of the rule itself to do this:
Mexpression = Mterm [qi::_val = qi::_1] >> *(
'+' >> Mterm [qi::_val = phoenix::new_<BinaryNode>(qi::_val, '+', qi::_1)]
| '-' >> Mterm [qi::_val = phoenix::new_<BinaryNode>(qi::_val, '-', qi::_1)]
);
However you may have to accomodate this in the constructor for your BinaryNode type.
This said:
I tend avoid semantic actions. As long as you're imperatively spelling each and every step out in the semantic action, what is the real benefit of using a parser generator like Spirit? It's no longer for Rapid Application Development
especially semantic actions doing dynamic allocations; it's very eay to create leaks in the presence of parser backtracking
That said, this kind of expression combination is about the only point where I think semantic actions can still be considered idiomatic in Spirit. The dynamic allocations most certainly are not.

boost spirit expression grammar issue while creating AST

I'm trying to parse expression grammar (with variables) into an Abstract Syntax Tree (AST) so that later on I could make a use of this AST and calculate values basing on those expressions (they may be a part of a function for example, so there is no need to store those expressions rather than calculate a value right away).
To my surprise, after handling with loops and instructions (which require nested structures in AST as well), I got nothing but seg faults after trying to parse any expression.. After hours of struggling with this I decided to ask here, because I have no idea what is it (maybe something with the grammar)
This statement-loop part works perfectly well. The struct 'loop' gets as a parameter only a number of repetitions - string so far (later on I want to put an expression here):
statement %= loop | inst;
inst %= lexeme[+(char_ - (';'|char_('}')) )] >> ';';
loop = "do(" > lexeme[+(char_ - "){")] // parse a number of loop repetitions
> "){"
> *statement > "}"
;
Structures are like:
typedef boost::variant<
boost::recursive_wrapper<s_loop>
, std::string>
s_statement;
struct s_loop
{
std::string name; // tag name
//s_expression exp; // TODO
std::vector<s_statement> children; // children
};
I use recursive wrapper, so I thought that maybe it is because of "deep" wrapping in case of expression-term-factor, why I can't do it. For loop-statement it goes simply like:
loop --(contains)--> statement (statement may be a loop!)
And in case of expressions it should be finally implemented like:
expression -> term -> factor (factor may be an expression!)
So, to be sure it's because of 'deep' wrapping, I tried with trivial grammar:
expression -> factor (factor may be an expression)
AST structures are copy-paste of above, everything is quite similar and.... it does not work! :(
I am quite sure that it must be something wrong with my grammar.. To be honest, I am not an expert of spirit. Here's the grammar:
expression = factor > * ( (char_('+')|char_('-')) > factor ) ;
factor %= uint_ | my_var | my_dat | my_rec_exp;
// factor %= uint_ | my_var | my_dat; //this WORKS! I've made procedures to traverse an AST
// strings and ints are parsed and stored well inside the expression structure
// factor %= uint_ | my_rec_exp; // even this simple version (of course I adjust a stucture s_expression) doesn't work.. WHY? :( , it's even less complex than loop-statement
my_rec_exp = '(' > expression > ')';
my_var %= char_('!') >> lexeme[+ ( char_ - ( ('+')|char_('-')|char_('*')|char_('/')|char_('(')|char_(')') ) ) ] ;
my_dat %= char_('#') >> lexeme[+ ( char_ - ( ('+')|char_('-')|char_('*')|char_('/')|char_('(')|char_(')') ) ) ] ;
Structures are here:
struct s_expression;
typedef boost::variant<
boost::recursive_wrapper<s_expression>,
// s_expression,
std::string,
unsigned int
>
s_factor;
struct s_term{ // WE DO NOT USE THIS IN THE SIMPLIFIED VERSION
s_factor factor0;
std::vector<std::pair<char, s_factor> >
factors;
};
struct s_expression{
s_factor term0;
std::vector<std::pair<char, s_factor> >
terms;
};
I will say one more time that without recursive expression it works well (parses to en expression containing a set of numers / strings connected with operators + / - ). But if I add expression as a variant of factor it crashes on exec.
Thank you for any advice / suggestion !

check doubled symbols with spirit::qi

I need to check text for doubled symbols. For example "1+1*2" should be ok, but "1**2+3" or "--1+4*3" should not. Consider part of spirit calc example.
expression =
term[_val=_1]
>> *( ('+' >> term[_val+=_1])
| ('-' >> term[_val-=_1])
);
term =
factor[_val=_1]
>> *( ('*' >> factor[_val*=_1])
| ('/' >> factor[_val/=_1])
);
factor =
double_[_val=_1]
| '(' >> expression[_val=_1] >> ')'
| ('-' >> factor[_val=_1])
| ('+' >> factor[_val=_1]);
phrase_parse returns true with the expressions like "1+++1" or "1**-1". I tried to use repeat like this:
term =
factor[_val=_1]
>> *( (repeat(0)[char_('*')] >> factor[_val*=_1])
| ('/' >> factor[_val/=_1])
);
But it doesnt help. What do i miss?
Thanks.
EDIT: Found an answer. One should compare string itrators after phrase_parse, but not phrase_parse output.
Found an answer. One should compare string itrators after phrase_parse, but not phrase_parse output.
In this case, '1+++++1' is parsing correctly since factor is recursively accepting +'s (probably intended to be a unary +/-).
Split that up
factor = ('-' >> value[_val=-_1])
| ('+' >> value[_val= _1])
| value [_val = _1];
value = double_ | '(' >> expression >> ')'