mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
We used to define such auxiliary structures outside the class, mainly as a matter of style to keep the definition of yy::parser short and simple. However, now there's a lot more code generated inside the class definition (e.g., all the token constructors), so the readability no longer applies. However, if we move stack (and slice) inside yy::parser, then it should no longer be needed to change the namespace to have multiple parsers: changing the class name should suffice. One common argument against inner classes is that they code bloat. It hardly applies here, since typically different parsers will have different semantic value types, hence different actual stack types. * data/skeletons/lalr1.cc: Invoke b4_stack_define inside yy::parser.
165 lines
3.9 KiB
C++
165 lines
3.9 KiB
C++
# C++ skeleton for Bison
|
|
|
|
# Copyright (C) 2002-2015, 2018 Free Software Foundation, Inc.
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
# b4_stack_file
|
|
# -------------
|
|
# Name of the file containing the stack class, if we want this file.
|
|
b4_defines_if([b4_required_version_if([302], [],
|
|
[m4_define([b4_stack_file], [stack.hh])])])
|
|
|
|
|
|
# b4_stack_define
|
|
# ---------------
|
|
m4_define([b4_stack_define],
|
|
[[ /// A stack with random access from its top.
|
|
template <typename T, typename S = std::vector<T> >
|
|
class stack
|
|
{
|
|
public:
|
|
// Hide our reversed order.
|
|
typedef typename S::reverse_iterator iterator;
|
|
typedef typename S::const_reverse_iterator const_iterator;
|
|
typedef typename S::size_type size_type;
|
|
|
|
stack (size_type n = 200)
|
|
: seq_ (n)
|
|
{}
|
|
|
|
/// Random access.
|
|
///
|
|
/// Index 0 returns the topmost element.
|
|
T&
|
|
operator[] (size_type i)
|
|
{
|
|
return seq_[size () - 1 - i];
|
|
}
|
|
|
|
/// Random access.
|
|
///
|
|
/// Index 0 returns the topmost element.
|
|
T&
|
|
operator[] (int i)
|
|
{
|
|
return operator[] (size_type (i));
|
|
}
|
|
|
|
/// Random access.
|
|
///
|
|
/// Index 0 returns the topmost element.
|
|
const T&
|
|
operator[] (size_type i) const
|
|
{
|
|
return seq_[size () - 1 - i];
|
|
}
|
|
|
|
/// Random access.
|
|
///
|
|
/// Index 0 returns the topmost element.
|
|
const T&
|
|
operator[] (int i) const
|
|
{
|
|
return operator[] (size_type (i));
|
|
}
|
|
|
|
/// Steal the contents of \a t.
|
|
///
|
|
/// Close to move-semantics.
|
|
void
|
|
push (YY_MOVE_REF (T) t)
|
|
{
|
|
seq_.push_back (T ());
|
|
operator[] (0).move (t);
|
|
}
|
|
|
|
/// Pop elements from the stack.
|
|
void
|
|
pop (int n = 1) YY_NOEXCEPT
|
|
{
|
|
for (; 0 < n; --n)
|
|
seq_.pop_back ();
|
|
}
|
|
|
|
/// Pop all elements from the stack.
|
|
void
|
|
clear () YY_NOEXCEPT
|
|
{
|
|
seq_.clear ();
|
|
}
|
|
|
|
/// Number of elements on the stack.
|
|
size_type
|
|
size () const YY_NOEXCEPT
|
|
{
|
|
return seq_.size ();
|
|
}
|
|
|
|
/// Iterator on top of the stack (going downwards).
|
|
const_iterator
|
|
begin () const YY_NOEXCEPT
|
|
{
|
|
return seq_.rbegin ();
|
|
}
|
|
|
|
/// Bottom of the stack.
|
|
const_iterator
|
|
end () const YY_NOEXCEPT
|
|
{
|
|
return seq_.rend ();
|
|
}
|
|
|
|
private:
|
|
stack (const stack&);
|
|
stack& operator= (const stack&);
|
|
/// The wrapped container.
|
|
S seq_;
|
|
};
|
|
|
|
/// Present a slice of the top of a stack.
|
|
template <typename T, typename S = stack<T> >
|
|
class slice
|
|
{
|
|
public:
|
|
slice (const S& stack, int range)
|
|
: stack_ (stack)
|
|
, range_ (range)
|
|
{}
|
|
|
|
const T&
|
|
operator[] (int i) const
|
|
{
|
|
return stack_[range_ - i];
|
|
}
|
|
|
|
private:
|
|
const S& stack_;
|
|
int range_;
|
|
};
|
|
]])
|
|
|
|
m4_ifdef([b4_stack_file],
|
|
[b4_output_begin([b4_dir_prefix], [b4_stack_file])[
|
|
]b4_generated_by[
|
|
// Starting with Bison 3.2, this file is useless: the structure it
|
|
// used to define is now defined with the parser itself.
|
|
//
|
|
// To get rid of this file:
|
|
// 1. add 'require "3.2"' (or newer) to your grammar file
|
|
// 2. remove references to this file from your build system.
|
|
]b4_output_end[
|
|
]])
|