[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])
# --------------------------- #
- RFC: api.value.automove,
Akim Demaille <=
- Re: RFC: api.value.automove, Hans Åberg, 2018/09/19
- Re: RFC: api.value.automove, Frank Heckenbach, 2018/09/20
- Re: RFC: api.value.automove, Akim Demaille, 2018/09/21
- Re: RFC: api.value.automove, Frank Heckenbach, 2018/09/21
- [PATCH 0/5] lalr1.cc: automove, Akim Demaille, 2018/09/22
- [PATCH 1/5] tests: prepare a test for automove, Akim Demaille, 2018/09/22
- [PATCH 2/5] tests: c++: use a custom string type, Akim Demaille, 2018/09/22
- [PATCH 3/5] c++: introduce api.value.automove, Akim Demaille, 2018/09/22
- [PATCH 4/5] c++: issue a warning with a value is moved several times, Akim Demaille, 2018/09/22
- [PATCH 5/5] news: c++: move semantics, Akim Demaille, 2018/09/22