Parse common cases of < and > comparisons

Adding full support for these in expressions seems hard to do without
introducing conflicts into the parser grammar, but in fact all reported
cases have had parentheses around the comparison and we can support that
with a few restrictions on the left side of `<`.

Fixes #80 and #635.  Also https://sourceforge.net/p/swig/bugs/1139/
This commit is contained in:
Olly Betts 2021-09-29 17:51:02 +13:00
commit f2de21eb83
14 changed files with 98 additions and 20 deletions

View file

@ -1675,7 +1675,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
%type <type> type rawtype type_right anon_bitfield_type decltype ;
%type <bases> base_list inherit raw_inherit;
%type <dtype> definetype def_args etype default_delete deleted_definition explicit_default;
%type <dtype> expr exprnum exprcompound valexpr exprmem;
%type <dtype> expr exprnum exprsimple exprcompound valexpr exprmem;
%type <id> ename ;
%type <id> less_valparms_greater;
%type <str> type_qualifier;
@ -6533,7 +6533,8 @@ exprmem : ID ARROW ID {
}
;
valexpr : exprnum {
/* Non-compound expression */
exprsimple : exprnum {
$$ = $1;
}
| exprmem {
@ -6553,7 +6554,6 @@ valexpr : exprnum {
$$.val = NewStringf("sizeof...(%s)",SwigType_str($6,0));
$$.type = T_ULONG;
}
| exprcompound { $$ = $1; }
| wstring {
$$.val = $1;
$$.rawval = NewStringf("L\"%s\"", $$.val);
@ -6588,6 +6588,11 @@ valexpr : exprnum {
$$.final = 0;
}
;
valexpr : exprsimple { $$ = $1; }
| exprcompound { $$ = $1; }
/* grouping */
| LPAREN expr RPAREN %prec CAST {
$$.val = NewStringf("(%s)",$2.val);
@ -6666,7 +6671,7 @@ valexpr : exprnum {
$$ = $2;
$$.val = NewStringf("*%s",$2.val);
}
;
;
exprnum : NUM_INT { $$ = $1; }
| NUM_FLOAT { $$ = $1; }
@ -6734,16 +6739,24 @@ exprcompound : expr PLUS expr {
$$.val = NewStringf("%s!=%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
/* Sadly this causes 2 reduce-reduce conflicts with templates. FIXME resolve these.
| expr GREATERTHAN expr {
$$.val = NewStringf("%s > %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
/* Trying to parse `>` in the general case results in conflicts
* in the parser, but all user-reported cases are actually inside
* parentheses and we can handle that case.
*/
| LPAREN expr GREATERTHAN expr RPAREN {
$$.val = NewStringf("%s > %s", COMPOUND_EXPR_VAL($2), COMPOUND_EXPR_VAL($4));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr LESSTHAN expr {
$$.val = NewStringf("%s < %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
/* Similarly for `<` except trying to handle exprcompound on the
* left side gives a shift/reduce conflict, so also restrict
* handling to non-compound subexpressions there. Again this
* covers all user-reported cases.
*/
| LPAREN exprsimple LESSTHAN expr RPAREN {
$$.val = NewStringf("%s < %s", COMPOUND_EXPR_VAL($2), COMPOUND_EXPR_VAL($4));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
*/
| expr GREATERTHANOREQUALTO expr {
$$.val = NewStringf("%s >= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;