Re: YYEOF shouldn't be defined with bison -y

2018-08-17 Thread Akim Demaille
Hi!

I’m coming long after the discussion, sorry.

> Le 5 déc. 2017 à 02:32, Dimitrios Apostolou  a écrit :
> 
> On Mon, 04 Dec 2017 21:24:40 +0100,
> Kaz Kylheku wrote:
>> 
>> On 03.12.2017 18:34, Dimitrios Apostolou wrote:
>>> Hello list,
>>> 
>>> I am configuring the build using AC_PROG_YACC, which invokes bison with "-y"
>>> option.  But bison-generated parser compiled successfully, and YYEOF
>>> extension
>>> in the parser remained undetected.
>>> 
>>> Generating the parser with "byacc" on the other hand creates a file that
>>> does
>>> not compile because of undefined symbol YYEOF.
>> 
>> What is your error report?
>> 
>> Are you saying that you cannot boostrap a build of Bison using Byacc?
> 
> My error report has nothing to do with bootstrapping Bison, sorry for not
> being clear.
> 
> I am generating a parser as part of a different project, and that project is
> configured with AC_PROG_YACC. As such, it invokes Bison with "-y" option, and
> I would expect that Bison tries hard to fail when the parser uses non-portable
> features, such as YYEOF.
> 
> This is not the case however, and the project was released, and this was
> discovered after longtime that somebody built it with byacc instead of
> Bison. With that version of byacc, the generated parser C code failed to build
> with "undefined symbol YYEOF".
> 
> I would expect that "bison -y" undefines YYEOF, so that the software that uses
> YYEOF fails to build.

There’s something which is not fully clear here: unless _you_ used YYEOF
somewhere in your code, there’s no reason for the parser not to be
compilable with byacc.

So I expect that you did use YYEOF.  In which case, the question is rather:
where was it used, to what purpose, and how would you have expected to
write it independently of YYEOF?


Re: Enhancement request: enabling Variant in C parsers

2018-08-17 Thread Akim Demaille
Hi!

Please, keep the CCs.

> Le 17 août 2018 à 22:43, Victor Khomenko  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 buf_loc=@3;
>   buf_loc.last_line=@5.last_line;
>   
> buf_loc.last_column=@5.last_column;

(Using C++ location, there’s a bunch of code that would easily go away)

>   report_error(&buf_loc,"Type 
> mi

Re: Bug Report Bison 3.0.4: parser crash when throwing syntax_error in C++ parser with locations from mid-rule actions

2018-08-17 Thread Akim Demaille
Hi Denis!

> Le 25 mars 2016 à 19:37, Denis T  a écrit :
> 
> Hi,
> 
> I've found out that Bison 3.0.4 parser crashes when you attempt to throw 
> syntax_error from any mid-rule action of C++ parser, which uses location 
> tracking. Here's a simple example:
> 
> %code provides {
> int yylex(yy::parser::semantic_type* type, const yy::parser::location_type* 
> loc);
> }
> 
> %require "3.0.4"
> %language "C++"
> %skeleton "lalr1.cc"
> %locations
> %define api.value.type {int}
> 
> %%
> 
> start:
>'1' '2' '3' { throw syntax_error(@1, "Test"); } '4' '5' '6' { $$ = 0; }
> ;
> 
> %%
> 
> void yy::parser::error(const yy::parser::location_type& loc, const 
> std::string& message)
> {
>std::cout << message << std::endl;
> }
> 
> int yylex(yy::parser::semantic_type* type, const yy::parser::location_type* 
> loc)
> {
>static int start = '0';
>return ++start;
> }
> 
> int main()
> {
>yy::parser().parse();
> }
> 
> 
> The crash occurs in yyerrorlab, when trying to do something with locations, 
> in the following autogenerated line:
> yyerror_range[1].location = yystack_[yylen - 1].location; // <- crash, as 
> yylen = 0 here

Good catch.  For the record, Bison 3.0.5 has a fix for this.

I’m ashamed to report that 3.0.5 was released recently (May 27th 2018), but the 
fix was sitting in git long before.

commit 476c1cca5945eeef3493cfc6ef06ed6d0972d787
Author: Akim Demaille 
Date:   Tue Aug 11 13:48:57 2015 +0200

lalr1, yacc: use the default location as initial error location

Currently lalr1.cc makes an out-of-bound access when trying to read @1
in rules with an empty rhs (i.e., when there is no @1) that raises an
error (YYERROR).

glr.c already gracefully handles this by using @$ as initial location
for the errors.  Let's do that in yacc.c and lalr1.cc.

* data/lalr1.cc, data/yacc.c: Use @$ to initialize the error location.
* tests/actions.at: Check that case.


> Fortunately, there's an easy workaround for this bug: it's possible to move 
> mid-rule action to another rule, and the issue doesn't reproduce anymore:
> start:
>one_two_three '4' '5' '6' { $$ = 0; }
> ;
> 
> one_two_three:
>'1' '2' '3' { throw syntax_error(@1, "Test"); }
> ;
> 
> 
> And a small another bug: it's currently not possible to use syntax_error 
> class from outside grammar file, as it has inline constructor defined 
> (c++.m4), which makes this class non-constructible from other cpp files, at 
> least in Visual Studio 2015. Removing « inline" keyword solves this issue.

That was also addressed in 3.0.5.

Thanks a lot!


Re: Enhancement request: enabling Variant in C parsers

2018-08-17 Thread Akim Demaille
Hi!

> Le 12 juil. 2016 à 23:12, Victor Khomenko  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  INT "integer"
> %token  STRING "string"
> %printer { fprintf (yyo, "%d", $$); } 
> %destructor { free ($$); } 
> 
> /* 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 "integer"
> %token  STRING "string"
> %printer { fprintf (yyo, "%d", $$); } 
> %destructor { free ($$); } 
> 
> /* 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.


Problem with new version of bison's code

2018-08-17 Thread JA . Tursunov
Hello developers of the project "bison"! The task following: There is OS 
Tsentos and sets the Kannel (SMS gateway: https://www.kannel.org/). When 
you install (yum groupinstall "Development tools") "Development tools" 
installed bison version 3.0.4 (bison.x86_64 3.0.4-1.el7 @base). When 
compiling the Kannel, an error occurs: 

In file included from wmlscript/wslexer.c:72:0:
y.tab.h:264:5: error: conflicting types for ‘ws_yy_parse’
In file included from wmlscript/wslexer.c:70:0:
wmlscript/wsint.h:296:5: note: previous declaration of ‘ws_yy_parse’ was 
here
 int ws_yy_parse(void *context);
 ^
make: *** [wmlscript/wslexer.o] Error 1

and all sources
(
http://kannel.6189.n7.nabble.com/Make-ERROR-in-Revision-5141-amp-with-Stable-Release-1-4-4-td31254.html
https://www.kannel.org/pipermail/users/2014-August/021422.html
http://kannel.6189.n7.nabble.com/ANNOUNCE-Kannel-1-4-4-stable-release-available-td30415.html
)
refer to the fact that if you install version 2.5 instead of 3.0.4, then 
the problem is solved. I don't want to use bother this way because the 
installation will have to be repeated many times.  And the question 
arises, how can this problem be solved! Thanks in advance



Sincerely,
Tursunov Jamshid Asadullaevich
The Engineer of the Department of Monitoring and Administration
T: 0 436 227-7698 | M: +998 93 521-7698 | E: ja.tursu...@ngmk.uz
Navoi Mining & Metallurgical Combinat (NMMC)
Address: Str. 27 Navoi, Navoi, Uzbekistan, 210100