bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RFC: api.value.automove


From: Akim Demaille
Subject: RFC: api.value.automove
Date: Wed, 19 Sep 2018 08:56:13 +0200

hi guys,

This is not mature:

- the testsuite fails, because the expected result changes whether
  std::move is supported or not

- the documentation needs more work, in particular, the C++ sections
  should describe this, not just include a reference in the list of
  variables

But I would like to open the discussions now.

- is the name right?  api.value.automove
  I chose something that fit in the current ‘hierarchy’:

     abstract                      
     annotations                   
     api.location.type             
     api.namespace                 
     api.position.type             
     api.prefix                    
     api.pure                      
     api.push-pull                 
     api.token.constructor         
     api.token.prefix              
     api.value.automove            
     api.value.type                
     api.value.union.name          
     extends                       
     final                         
     implements                    
     init_throws                   
     lex_throws                    
     location_type                 
     lr.default-reduction          
     lr.keep-unreachable-state     
     lr.type                       
     package                       
     parse.assert                  
     parse.error                   
     parse.lac                     
     parse.trace                   
     parser_class_name             
     public                        
     strictfp                      
     throws                        

   the names without dots are not ‘correct', and we should not
   introduce new ones.

- should we expose YY_MOVE, which is std::move in C++11+ and nothing
  otherwise, or just expose std::move and claim users should not use
  this feature with pre-11?  It does work with pre-11, of course.

- should we not use YY_MOVE and just use std::move instead?  In which
  case the parser _must_ be compiled in C++11+.

- I will add the warning about repeated use of a value.

- and probably other questions I did not think about yet.

commit bc889a50afb23b2d149183c92d704a5d2653b304
Author: Akim Demaille <address@hidden>
Date:   Tue Sep 18 19:57:32 2018 +0200

    c++: introduce api.value.automove
    
    Based on work by Frank Heckenbach.
    See http://lists.gnu.org/archive/html/bug-bison/2018-04/msg00000.html
    and http://lists.gnu.org/archive/html/bug-bison/2018-09/msg00019.html.
    
    * data/lalr1.cc (b4_rhs_value): Use YY_MOVE api.rhs.automove is set.
    * doc/bison.texi (%define Summary): Document api.rhs.automove.
    * examples/variant-11.yy: Use it.

diff --git a/data/lalr1.cc b/data/lalr1.cc
index 15fd6fb9..7ccb35fb 100644
--- a/data/lalr1.cc
+++ b/data/lalr1.cc
@@ -83,9 +83,14 @@ m4_define([b4_rhs_state],
 # --------------------------------------
 # Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
 # symbols on RHS.
-m4_define([b4_rhs_value],
+m4_define([b4_rhs_value_],
           [b4_symbol_value([b4_rhs_data([$1], [$2]).value], [$3])])
 
+m4_define([b4_rhs_value],
+[b4_percent_define_ifdef([api.value.automove],
+                         [YY_MOVE(b4_rhs_value_($@))],
+                         [b4_rhs_value_($@)])])
+
 
 # b4_rhs_location(RULE-LENGTH, NUM)
 # ---------------------------------
diff --git a/doc/bison.texi b/doc/bison.texi
index 6ab979f1..9f6821cb 100644
--- a/doc/bison.texi
+++ b/doc/bison.texi
@@ -5982,6 +5982,66 @@ introduced in Bison 3.0
 @c api.token.prefix
 
 
address@hidden ================================================== 
api.value.automove
address@hidden Directive {%define api.value.automove}
+
address@hidden @bullet
address@hidden Language(s):
+C++
+
address@hidden Purpose:
+Let occurrences of semantic values of the right-hand sides of a rule be
+implicitly turned in rvalues.  When enabled, a grammar such as:
+
address@hidden
+exp:
+  "number"     @{ $$ = make_number ($1); @}
+| exp "+" exp  @{ $$ = make_binary (add, $1, $3); @}
+| "(" exp ")"  @{ $$ = $2; @}
address@hidden example
+
address@hidden
+is actually compiled as if you had written:
+
address@hidden
+exp:
+  "number"     @{ $$ = make_number (std::move ($1)); @}
+| exp "+" exp  @{ $$ = make_binary (add,
+                                   std::move ($1),
+                                   std::move ($3)); @}
+| "(" exp ")"  @{ $$ = std::move ($2); @}
address@hidden example
+
+Using a value several times with automove enabled is typically an error.
+For instance, instead of:
+
address@hidden
+exp: "twice" exp  @{ $$ = make_binary (add, $2, $2); @}
address@hidden example
+
address@hidden
+write:
+
address@hidden
+exp: "twice" exp @{ auto v = $2; $$ = make_binary (add, v, v); @}
address@hidden example
+
address@hidden
+It is tempting to use @code{std::move} on one of the @code{v}, but the
+argument evaluation order in C++ is unspecified.
+
address@hidden Accepted Values:
+Boolean.
+
address@hidden Default Value:
address@hidden
address@hidden History:
+introduced in Bison 3.2
address@hidden itemize
address@hidden deffn
address@hidden api.value.automove
+
+
 @c ================================================== api.value.type
 @deffn Directive {%define api.value.type} @var{support}
 @deffnx Directive {%define api.value.type} @address@hidden@}
diff --git a/examples/variant-11.yy b/examples/variant-11.yy
index c78bab07..81b0b1b9 100644
--- a/examples/variant-11.yy
+++ b/examples/variant-11.yy
@@ -20,6 +20,7 @@
 %defines
 %define api.token.constructor
 %define api.value.type variant
+%define api.value.automove
 %define parse.assert
 %locations
 
@@ -96,11 +97,11 @@ result:
 
 list:
   %empty     { /* Generates an empty string list */ }
-| list item  { $$ = std::move ($1); $$.emplace_back (std::move ($2)); }
+| list item  { $$ = $1; $$.emplace_back ($2); }
 ;
 
 item:
-  TEXT    { $$ = std::move ($1); }
+  TEXT    { $$ = $1; }
 | NUMBER  { $$ = make_string_uptr (to_string ($1)); }
 ;
 %%
diff --git a/tests/c++.at b/tests/c++.at
index 8b14da12..66c7c82f 100644
--- a/tests/c++.at
+++ b/tests/c++.at
@@ -295,13 +295,13 @@ result:
 
 list:
   item          { $$.push_back ($][1); }
-| list "," item { std::swap ($$, $][1); $$.push_back ($][3); }
-| list error    { std::swap ($$, $][1); }
+| list "," item { $$ = $][1; $$.push_back ($][3); }
+| list error    { $$ = $][1; }
 ;
 
 item:
-  TEXT          { std::swap ($$, $][1); }
-| NUMBER        { if ($][1 == 3) YYERROR; else $$ = to_string ($][1); }
+  TEXT          { $$ = $][1; }
+| NUMBER        { int v = $][1; if (v == 3) YYERROR; else $$ = to_string (v); }
 ;
 %%
 ]AT_TOKEN_CTOR_IF([],
@@ -399,11 +399,13 @@ AT_CLEANUP
 
 AT_TEST([[%skeleton "lalr1.cc"]])
 AT_TEST([[%skeleton "lalr1.cc" %define parse.assert]])
+AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define 
api.value.automove]])
 AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %locations]])
 AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %code {\n#define 
TWO_STAGE_BUILD\n}]])
 AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define 
api.token.constructor]])
 AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define 
api.token.constructor %define api.token.prefix {TOK_}]])
 AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define 
api.token.constructor %define api.token.prefix {TOK_} %locations]])
+AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define 
api.token.constructor %define api.token.prefix {TOK_} %locations %define 
api.value.automove]])
 
 m4_popdef([AT_TEST])
 
diff --git a/tests/calc.at b/tests/calc.at
index a75a1bc6..d37c5664 100644
--- a/tests/calc.at
+++ b/tests/calc.at
@@ -696,6 +696,7 @@ AT_CHECK_CALC_LALR1_CC([%defines %locations %define 
parse.error verbose %debug %
 AT_CHECK_CALC_LALR1_CC([%define parse.error verbose %debug %define api.prefix 
{calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int 
*count}])
 AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %debug 
%define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} 
%parse-param {int *count}])
 
+AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %debug 
%define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} 
%parse-param {int *count} %define api.value.automove])
 
 
 # --------------------------- #




reply via email to

[Prev in Thread] Current Thread [Next in Thread]