Hi! > Le 12 juil. 2016 à 23:12, Victor Khomenko <victor.khome...@newcastle.ac.uk> 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.