[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Enhancement request: enabling Variant in C parsers
From: |
Akim Demaille |
Subject: |
Re: Enhancement request: enabling Variant in C parsers |
Date: |
Sat, 18 Aug 2018 06:12:50 +0200 |
Hi!
Please, keep the CCs.
> Le 17 août 2018 à 22:43, Victor Khomenko <address@hidden> a écrit :
>
> Hi Akim,
> My main concern is memory management. With Variant the destructors are called
> automatically, but in C parsers I currently have to use %union with pointers
> and explicit "delete". This is not exception-safe and results in ugly code
> littered with "delete" statements. (Using api.value.type is not good enough
> as it makes the types monolithic, so I’d have to select the corresponding
> members manually.)
I don’t understand what you mean here, by monolithic. The parser needs a
single type to store all the possible types, so, yes, it is monolithic.
> I don’t want to go all the way to C++ parsers for the reasons explained in my
> previous email.
So you can’t expect the C++ features to work properly.
You wrote:
> * I (and probably some other people) find some aspects of C++ parsers
> unwieldy, so prefer the good old C parsers in my C++ programs.
You’d have to provide more details. I don’t think there is much to change to
make to move to a C++ parser.
> So I'd like to use Variant to represent %union, but otherwise I want an old
> C-style parser. This will be ok for C++ compilers.
>
> Below is a motivating piece of code - with variants I'd just use object types
> rather than pointers in %union, replace "->" by ".", remove the "delete"
> statements, and use move-assignments instead of pointer assignments.
>
> Regards,
> Victor.
>
>
> [...]
> | exp '?' exp ':' exp {
> if($1->type_c.type!=t_bool){
> report_error(&@1,"Type mismatch
> in '?:': the condition must be Boolean");
> delete $1;
> delete $3;
> delete $5;
> YYERROR;
> }
Your code is not typical. Traditionally you build an AST in the parser, and
process the tree elsewhere. That’s why you have so many deletes imho. Using
the syntax_error exception, you could still raise a syntax error, as if it were
from YYERROR, but from your routine (however, I don’t think type errors should
be handled by the parser).
Cheers!
> else if($3->type_c.type==t_fail ||
> $5->type_c.type==t_fail){
> if(!$1->type_c.is_const){
> report_error(&@1,"The
> condition of '?:' must be constant if the 'then' or 'else' expressions are of
> type fail");
> delete $1;
> delete $3;
> delete $5;
> YYERROR;
> }
> else if($3->type_c.type!=t_bool
> && $5->type_c.type!=t_bool && (!$1->type_c.is_const || !$3->type_c.is_const
> || !$5->type_c.is_const)){
> report_error(&@$,"The
> operands of '?:' must be either Boolean or constant");
> delete $1;
> delete $3;
> delete $5;
> YYERROR;
> }
> else{
> exp_data* failed=$3;
> $$=$5;
>
> if($3->type_c.type!=t_fail){ failed=$5; $$=$3; }
>
> $$->expr=ReachExpIf(move($1->expr),move($3->expr),move($5->expr));
> $$->type_c.is_const &=
> $1->type_c.is_const;
> $$->type_c.is_const &=
> failed->type_c.is_const;
> delete $1;
> delete failed;
> }
> }
> else
> if($3->type_c.type!=$5->type_c.type){
> YYLTYPE address@hidden;
> address@hidden;
> address@hidden;
(Using C++ location, there’s a bunch of code that would easily go away)
> report_error(&buf_loc,"Type
> mismatch in '?:': the 'then' and 'else' expressions must be of the same
> type");
> delete $1;
> delete $3;
> delete $5;
> YYERROR;
> }
> else if($3->type_c.type!=t_bool &&
> $5->type_c.type!=t_bool && (!$1->type_c.is_const || !$3->type_c.is_const ||
> !$5->type_c.is_const)){
> report_error(&@$,"The operands
> of '?:' must be either Boolean or constant");
> delete $1;
> delete $3;
> delete $5;
> YYERROR;
> }
> else{
>
> $3->expr=ReachExpIf(move($1->expr),move($3->expr),move($5->expr));
> $3->type_c.is_const &=
> $1->type_c.is_const;
> $3->type_c.is_const &=
> $5->type_c.is_const;
> delete $1;
> delete $5;
> $$=$3;
> }
> }
>
> [...]
>
>
>
>
>
>
>> -----Original Message-----
>> From: Akim Demaille <address@hidden>
>> Sent: Friday, August 17, 2018 6:56 PM
>> To: Victor Khomenko <address@hidden>
>> Cc: Bison Bugs <address@hidden>
>> Subject: Re: Enhancement request: enabling Variant in C parsers
>>
>> Hi!
>>
>>> Le 12 juil. 2016 à 23:12, Victor Khomenko
>> <address@hidden> a écrit :
>>>
>>> Dear developers,
>>>
>>> It would be nice to enable Variant in C parsers - these obviously have to be
>> compiled with a C++ compiler.
>>>
>>> Motivation:
>>> * I (and probably some other people) find some aspects of C++ parsers
>> unwieldy, so prefer the good old C parsers in my C++ programs.
>>> * Maintaining/refactoring existing C parsers using variants is
>> straightforward, whereas rewriting them as C++ parsers requires much effort.
>>>
>>> Apologies if this was discussed earlier - I didn’t find anything relevant
>>> in the
>> mail archives though.
>>
>> Yes, the answer is quite late… I’m trying to catch up…
>>
>> I do not understand what you mean: the raison d’être of variants is C++, and
>> C++ only. Was that sentence proper English? Lemme try again. Variants were
>> introduce because C++ forbid to put objects into unions (roughly). And
>> variants
>> are objects, so that doesn’t make sense in C.
>>
>> So maybe it’s something else that you like. For instance I do like not to
>> have to
>> use %union and be able to use types directly. You can do that in C, just
>> look at
>> the examples from NEWS for instance:
>>
>>> ** Variable api.value.type
>>>
>>> This new %define variable supersedes the #define macro YYSTYPE. The use
>>> of YYSTYPE is discouraged. In particular, #defining YYSTYPE *and* either
>>> using %union or %defining api.value.type results in undefined behavior.
>>>
>>> Either define api.value.type, or use "%union":
>>>
>>> %union
>>> {
>>> int ival;
>>> char *sval;
>>> }
>>> %token <ival> INT "integer"
>>> %token <sval> STRING "string"
>>> %printer { fprintf (yyo, "%d", $$); } <ival>
>>> %destructor { free ($$); } <sval>
>>>
>>> /* In yylex(). */
>>> yylval.ival = 42; return INT;
>>> yylval.sval = "42"; return STRING;
>>>
>>> The %define variable api.value.type supports both keyword and code values.
>>>
>>> The keyword value 'union' means that the user provides genuine types, not
>>> union member names such as "ival" and "sval" above (WARNING: will fail if
>>> -y/--yacc/%yacc is enabled).
>>>
>>> %define api.value.type union
>>> %token <int> INT "integer"
>>> %token <char *> STRING "string"
>>> %printer { fprintf (yyo, "%d", $$); } <int>
>>> %destructor { free ($$); } <char *>
>>>
>>> /* In yylex(). */
>>> yylval.INT = 42; return INT;
>>> yylval.STRING = "42"; return STRING;
>>>
>>
>> If what you like is symbol constructors, i.e., this:
>>
>>> *** %define api.token.constructor
>>>
>>> When variants are enabled, Bison can generate functions to build the
>>> tokens. This guarantees that the token type (e.g., NUMBER) is consistent
>>> with the semantic value (e.g., int):
>>>
>>> parser::symbol_type yylex ()
>>> {
>>> parser::location_type loc = ...;
>>> ...
>>> return parser::make_TEXT ("Hello, world!", loc);
>>> ...
>>> return parser::make_NUMBER (42, loc);
>>> ...
>>> return parser::make_SEMICOLON (loc);
>>> ...
>>> }
>>
>> then I agree with you: this is an interesting concept that could exist in C
>> too.
>> And in C++ without variants.
- Re: Enhancement request: enabling Variant in C parsers, Akim Demaille, 2018/08/17
- Message not available
- Message not available
- Message not available
- Re: Enhancement request: enabling Variant in C parsers,
Akim Demaille <=
- Message not available
- Message not available
- RE: Enhancement request: enabling Variant in C parsers, Victor Khomenko, 2018/08/18
- Re: Enhancement request: enabling Variant in C parsers, Akim Demaille, 2018/08/18
- Message not available
- Message not available
- Message not available
- Re: Enhancement request: enabling Variant in C parsers, Akim Demaille, 2018/08/19
- Message not available
- Message not available
- RE: Enhancement request: enabling Variant in C parsers, Victor Khomenko, 2018/08/19
- Re: Enhancement request: enabling Variant in C parsers, Akim Demaille, 2018/08/19
- Re: Enhancement request: enabling Variant in C parsers, Rici Lake, 2018/08/19
- Re: Enhancement request: enabling Variant in C parsers, Akim Demaille, 2018/08/19
- Re: Enhancement request: enabling Variant in C parsers, Akim Demaille, 2018/08/23
- Re: Enhancement request: enabling Variant in C parsers, Hans Åberg, 2018/08/21
- Re: Enhancement request: enabling Variant in C parsers, Akim Demaille, 2018/08/23