// A Bison parser, made by GNU Bison 3.0.2.

// Skeleton implementation for Bison LALR(1) parsers in C++

// Copyright (C) 2002-2013 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/>.

// As a special exception, you may create a larger work that contains
// part or all of the Bison parser skeleton and distribute that work
// under terms of your choice, so long as that work isn't itself a
// parser generator using the skeleton or a modified version thereof
// as a parser skeleton.  Alternatively, if you modify or redistribute
// the parser skeleton itself, you may (at your option) remove this
// special exception, which will cause the skeleton and the resulting
// Bison output files to be licensed under the GNU General Public
// License without this special exception.

// This special exception was added by the Free Software Foundation in
// version 2.2 of Bison.

// Take the name prefix into account.
#define yylex   hoayylex

// First part of user declarations.

#line 39 "parseaut.cc" // lalr1.cc:399

# ifndef YY_NULLPTR
#  if defined __cplusplus && 201103L <= __cplusplus
#   define YY_NULLPTR nullptr
#  else
#   define YY_NULLPTR 0
#  endif
# endif

#include "parseaut.hh"

// User implementation prologue.

#line 53 "parseaut.cc" // lalr1.cc:407
// Unqualified %code blocks.
#line 197 "parseaut.yy" // lalr1.cc:408

#include <sstream>

  /* parseaut.hh and parsedecl.hh include each other recursively.
   We must ensure that YYSTYPE is declared (by the above %union)
   before parsedecl.hh uses it. */
#include <spot/parseaut/parsedecl.hh>

  static void fill_guards(result_& res);

#line 66 "parseaut.cc" // lalr1.cc:408


#ifndef YY_
# if defined YYENABLE_NLS && YYENABLE_NLS
#  if ENABLE_NLS
#   include <libintl.h> // FIXME: INFRINGES ON USER NAME SPACE.
#   define YY_(msgid) dgettext ("bison-runtime", msgid)
#  endif
# endif
# ifndef YY_
#  define YY_(msgid) msgid
# endif
#endif

#define YYRHSLOC(Rhs, K) ((Rhs)[K].location)
/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
   If N is 0, then set CURRENT to the empty location which ends
   the previous symbol: RHS[0] (always defined).  */

# ifndef YYLLOC_DEFAULT
#  define YYLLOC_DEFAULT(Current, Rhs, N)                               \
    do                                                                  \
      if (N)                                                            \
        {                                                               \
          (Current).begin  = YYRHSLOC (Rhs, 1).begin;                   \
          (Current).end    = YYRHSLOC (Rhs, N).end;                     \
        }                                                               \
      else                                                              \
        {                                                               \
          (Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end;      \
        }                                                               \
    while (/*CONSTCOND*/ false)
# endif


// Suppress unused-variable warnings by "using" E.
#define YYUSE(E) ((void) (E))

// Enable debugging if requested.
#if YYDEBUG

// A pseudo ostream that takes yydebug_ into account.
# define YYCDEBUG if (yydebug_) (*yycdebug_)

# define YY_SYMBOL_PRINT(Title, Symbol)         \
  do {                                          \
    if (yydebug_)                               \
    {                                           \
      *yycdebug_ << Title << ' ';               \
      yy_print_ (*yycdebug_, Symbol);           \
      *yycdebug_ << std::endl;                  \
    }                                           \
  } while (false)

# define YY_REDUCE_PRINT(Rule)          \
  do {                                  \
    if (yydebug_)                       \
      yy_reduce_print_ (Rule);          \
  } while (false)

# define YY_STACK_PRINT()               \
  do {                                  \
    if (yydebug_)                       \
      yystack_print_ ();                \
  } while (false)

#else // !YYDEBUG

# define YYCDEBUG if (false) std::cerr
# define YY_SYMBOL_PRINT(Title, Symbol)  YYUSE(Symbol)
# define YY_REDUCE_PRINT(Rule)           static_cast<void>(0)
# define YY_STACK_PRINT()                static_cast<void>(0)

#endif // !YYDEBUG

#define yyerrok         (yyerrstatus_ = 0)
#define yyclearin       (yyempty = true)

#define YYACCEPT        goto yyacceptlab
#define YYABORT         goto yyabortlab
#define YYERROR         goto yyerrorlab
#define YYRECOVERING()  (!!yyerrstatus_)


namespace hoayy {
#line 152 "parseaut.cc" // lalr1.cc:474

  /* Return YYSTR after stripping away unnecessary quotes and
     backslashes, so that it's suitable for yyerror.  The heuristic is
     that double-quoting is unnecessary unless the string contains an
     apostrophe, a comma, or backslash (other than backslash-backslash).
     YYSTR is taken from yytname.  */
  std::string
  parser::yytnamerr_ (const char *yystr)
  {
    if (*yystr == '"')
      {
        std::string yyr = "";
        char const *yyp = yystr;

        for (;;)
          switch (*++yyp)
            {
            case '\'':
            case ',':
              goto do_not_strip_quotes;

            case '\\':
              if (*++yyp != '\\')
                goto do_not_strip_quotes;
              // Fall through.
            default:
              yyr += *yyp;
              break;

            case '"':
              return yyr;
            }
      do_not_strip_quotes: ;
      }

    return yystr;
  }


  /// Build a parser object.
  parser::parser (result_& res_yyarg, spot::location initial_loc_yyarg)
    :
#if YYDEBUG
      yydebug_ (false),
      yycdebug_ (&std::cerr),
#endif
      res (res_yyarg),
      initial_loc (initial_loc_yyarg)
  {}

  parser::~parser ()
  {}


  /*---------------.
  | Symbol types.  |
  `---------------*/

  inline
  parser::syntax_error::syntax_error (const location_type& l, const std::string& m)
    : std::runtime_error (m)
    , location (l)
  {}

  // basic_symbol.
  template <typename Base>
  inline
  parser::basic_symbol<Base>::basic_symbol ()
    : value ()
  {}

  template <typename Base>
  inline
  parser::basic_symbol<Base>::basic_symbol (const basic_symbol& other)
    : Base (other)
    , value ()
    , location (other.location)
  {
    value = other.value;
  }


  template <typename Base>
  inline
  parser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const semantic_type& v, const location_type& l)
    : Base (t)
    , value (v)
    , location (l)
  {}


  /// Constructor for valueless symbols.
  template <typename Base>
  inline
  parser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const location_type& l)
    : Base (t)
    , value ()
    , location (l)
  {}

  template <typename Base>
  inline
  parser::basic_symbol<Base>::~basic_symbol ()
  {
  }

  template <typename Base>
  inline
  void
  parser::basic_symbol<Base>::move (basic_symbol& s)
  {
    super_type::move(s);
    value = s.value;
    location = s.location;
  }

  // by_type.
  inline
  parser::by_type::by_type ()
     : type (empty)
  {}

  inline
  parser::by_type::by_type (const by_type& other)
    : type (other.type)
  {}

  inline
  parser::by_type::by_type (token_type t)
    : type (yytranslate_ (t))
  {}

  inline
  void
  parser::by_type::move (by_type& that)
  {
    type = that.type;
    that.type = empty;
  }

  inline
  int
  parser::by_type::type_get () const
  {
    return type;
  }


  // by_state.
  inline
  parser::by_state::by_state ()
    : state (empty)
  {}

  inline
  parser::by_state::by_state (const by_state& other)
    : state (other.state)
  {}

  inline
  void
  parser::by_state::move (by_state& that)
  {
    state = that.state;
    that.state = empty;
  }

  inline
  parser::by_state::by_state (state_type s)
    : state (s)
  {}

  inline
  parser::symbol_number_type
  parser::by_state::type_get () const
  {
    return state == empty ? 0 : yystos_[state];
  }

  inline
  parser::stack_symbol_type::stack_symbol_type ()
  {}


  inline
  parser::stack_symbol_type::stack_symbol_type (state_type s, symbol_type& that)
    : super_type (s, that.location)
  {
    value = that.value;
    // that is emptied.
    that.type = empty;
  }

  inline
  parser::stack_symbol_type&
  parser::stack_symbol_type::operator= (const stack_symbol_type& that)
  {
    state = that.state;
    value = that.value;
    location = that.location;
    return *this;
  }


  template <typename Base>
  inline
  void
  parser::yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const
  {
    if (yymsg)
      YY_SYMBOL_PRINT (yymsg, yysym);

    // User destructor.
    switch (yysym.type_get ())
    {
            case 18: // "identifier"

#line 285 "parseaut.yy" // lalr1.cc:599
        { delete (yysym.value.str); }
#line 372 "parseaut.cc" // lalr1.cc:599
        break;

      case 19: // "header name"

#line 285 "parseaut.yy" // lalr1.cc:599
        { delete (yysym.value.str); }
#line 379 "parseaut.cc" // lalr1.cc:599
        break;

      case 20: // "alias name"

#line 285 "parseaut.yy" // lalr1.cc:599
        { delete (yysym.value.str); }
#line 386 "parseaut.cc" // lalr1.cc:599
        break;

      case 21: // "string"

#line 285 "parseaut.yy" // lalr1.cc:599
        { delete (yysym.value.str); }
#line 393 "parseaut.cc" // lalr1.cc:599
        break;

      case 44: // "boolean formula"

#line 285 "parseaut.yy" // lalr1.cc:599
        { delete (yysym.value.str); }
#line 400 "parseaut.cc" // lalr1.cc:599
        break;

      case 69: // string_opt

#line 285 "parseaut.yy" // lalr1.cc:599
        { delete (yysym.value.str); }
#line 407 "parseaut.cc" // lalr1.cc:599
        break;

      case 89: // state-conj-2

#line 289 "parseaut.yy" // lalr1.cc:599
        { delete (yysym.value.states); }
#line 414 "parseaut.cc" // lalr1.cc:599
        break;

      case 90: // init-state-conj-2

#line 289 "parseaut.yy" // lalr1.cc:599
        { delete (yysym.value.states); }
#line 421 "parseaut.cc" // lalr1.cc:599
        break;

      case 91: // label-expr

#line 286 "parseaut.yy" // lalr1.cc:599
        { bdd_delref((yysym.value.b)); }
#line 428 "parseaut.cc" // lalr1.cc:599
        break;

      case 93: // acceptance-cond

#line 288 "parseaut.yy" // lalr1.cc:599
        { delete (yysym.value.code); }
#line 435 "parseaut.cc" // lalr1.cc:599
        break;

      case 111: // state-conj-checked

#line 289 "parseaut.yy" // lalr1.cc:599
        { delete (yysym.value.states); }
#line 442 "parseaut.cc" // lalr1.cc:599
        break;

      case 128: // nc-one-ident

#line 285 "parseaut.yy" // lalr1.cc:599
        { delete (yysym.value.str); }
#line 449 "parseaut.cc" // lalr1.cc:599
        break;

      case 129: // nc-ident-list

#line 285 "parseaut.yy" // lalr1.cc:599
        { delete (yysym.value.str); }
#line 456 "parseaut.cc" // lalr1.cc:599
        break;

      case 130: // nc-transition-block

#line 304 "parseaut.yy" // lalr1.cc:599
        {
  for (auto i = (yysym.value.list)->begin(); i != (yysym.value.list)->end(); ++i)
  {
    bdd_delref(i->first);
    delete i->second;
  }
  delete (yysym.value.list);
  }
#line 470 "parseaut.cc" // lalr1.cc:599
        break;

      case 132: // nc-transitions

#line 304 "parseaut.yy" // lalr1.cc:599
        {
  for (auto i = (yysym.value.list)->begin(); i != (yysym.value.list)->end(); ++i)
  {
    bdd_delref(i->first);
    delete i->second;
  }
  delete (yysym.value.list);
  }
#line 484 "parseaut.cc" // lalr1.cc:599
        break;

      case 133: // nc-formula-or-ident

#line 285 "parseaut.yy" // lalr1.cc:599
        { delete (yysym.value.str); }
#line 491 "parseaut.cc" // lalr1.cc:599
        break;

      case 134: // nc-formula

#line 286 "parseaut.yy" // lalr1.cc:599
        { bdd_delref((yysym.value.b)); }
#line 498 "parseaut.cc" // lalr1.cc:599
        break;

      case 135: // nc-opt-dest

#line 285 "parseaut.yy" // lalr1.cc:599
        { delete (yysym.value.str); }
#line 505 "parseaut.cc" // lalr1.cc:599
        break;

      case 136: // nc-src-dest

#line 287 "parseaut.yy" // lalr1.cc:599
        { bdd_delref((yysym.value.p)->first); delete (yysym.value.p)->second; delete (yysym.value.p); }
#line 512 "parseaut.cc" // lalr1.cc:599
        break;

      case 137: // nc-transition

#line 287 "parseaut.yy" // lalr1.cc:599
        { bdd_delref((yysym.value.p)->first); delete (yysym.value.p)->second; delete (yysym.value.p); }
#line 519 "parseaut.cc" // lalr1.cc:599
        break;


      default:
        break;
    }
  }

#if YYDEBUG
  template <typename Base>
  void
  parser::yy_print_ (std::ostream& yyo,
                                     const basic_symbol<Base>& yysym) const
  {
    std::ostream& yyoutput = yyo;
    YYUSE (yyoutput);
    symbol_number_type yytype = yysym.type_get ();
    yyo << (yytype < yyntokens_ ? "token" : "nterm")
        << ' ' << yytname_[yytype] << " ("
        << yysym.location << ": ";
    switch (yytype)
    {
            case 18: // "identifier"

#line 312 "parseaut.yy" // lalr1.cc:617
        {
    if ((yysym.value.str))
      debug_stream() << *(yysym.value.str);
    else
      debug_stream() << "\"\""; }
#line 550 "parseaut.cc" // lalr1.cc:617
        break;

      case 19: // "header name"

#line 312 "parseaut.yy" // lalr1.cc:617
        {
    if ((yysym.value.str))
      debug_stream() << *(yysym.value.str);
    else
      debug_stream() << "\"\""; }
#line 561 "parseaut.cc" // lalr1.cc:617
        break;

      case 20: // "alias name"

#line 312 "parseaut.yy" // lalr1.cc:617
        {
    if ((yysym.value.str))
      debug_stream() << *(yysym.value.str);
    else
      debug_stream() << "\"\""; }
#line 572 "parseaut.cc" // lalr1.cc:617
        break;

      case 21: // "string"

#line 312 "parseaut.yy" // lalr1.cc:617
        {
    if ((yysym.value.str))
      debug_stream() << *(yysym.value.str);
    else
      debug_stream() << "\"\""; }
#line 583 "parseaut.cc" // lalr1.cc:617
        break;

      case 22: // "integer"

#line 317 "parseaut.yy" // lalr1.cc:617
        { debug_stream() << (yysym.value.num); }
#line 590 "parseaut.cc" // lalr1.cc:617
        break;

      case 44: // "boolean formula"

#line 312 "parseaut.yy" // lalr1.cc:617
        {
    if ((yysym.value.str))
      debug_stream() << *(yysym.value.str);
    else
      debug_stream() << "\"\""; }
#line 601 "parseaut.cc" // lalr1.cc:617
        break;

      case 47: // "LBTT header"

#line 317 "parseaut.yy" // lalr1.cc:617
        { debug_stream() << (yysym.value.num); }
#line 608 "parseaut.cc" // lalr1.cc:617
        break;

      case 48: // "state acceptance"

#line 317 "parseaut.yy" // lalr1.cc:617
        { debug_stream() << (yysym.value.num); }
#line 615 "parseaut.cc" // lalr1.cc:617
        break;

      case 49: // "acceptance sets for empty automaton"

#line 317 "parseaut.yy" // lalr1.cc:617
        { debug_stream() << (yysym.value.num); }
#line 622 "parseaut.cc" // lalr1.cc:617
        break;

      case 50: // "acceptance set"

#line 317 "parseaut.yy" // lalr1.cc:617
        { debug_stream() << (yysym.value.num); }
#line 629 "parseaut.cc" // lalr1.cc:617
        break;

      case 51: // "state number"

#line 317 "parseaut.yy" // lalr1.cc:617
        { debug_stream() << (yysym.value.num); }
#line 636 "parseaut.cc" // lalr1.cc:617
        break;

      case 52: // "destination number"

#line 317 "parseaut.yy" // lalr1.cc:617
        { debug_stream() << (yysym.value.num); }
#line 643 "parseaut.cc" // lalr1.cc:617
        break;

      case 69: // string_opt

#line 312 "parseaut.yy" // lalr1.cc:617
        {
    if ((yysym.value.str))
      debug_stream() << *(yysym.value.str);
    else
      debug_stream() << "\"\""; }
#line 654 "parseaut.cc" // lalr1.cc:617
        break;

      case 89: // state-conj-2

#line 290 "parseaut.yy" // lalr1.cc:617
        {
  auto& os = debug_stream();
  os << '{';
  bool notfirst = false;
  for (auto i: *(yysym.value.states))
  {
    if (notfirst)
      os << ", ";
    else
      notfirst = true;
    os << i;
  }
  os << '}';
}
#line 674 "parseaut.cc" // lalr1.cc:617
        break;

      case 90: // init-state-conj-2

#line 290 "parseaut.yy" // lalr1.cc:617
        {
  auto& os = debug_stream();
  os << '{';
  bool notfirst = false;
  for (auto i: *(yysym.value.states))
  {
    if (notfirst)
      os << ", ";
    else
      notfirst = true;
    os << i;
  }
  os << '}';
}
#line 694 "parseaut.cc" // lalr1.cc:617
        break;

      case 92: // acc-set

#line 317 "parseaut.yy" // lalr1.cc:617
        { debug_stream() << (yysym.value.num); }
#line 701 "parseaut.cc" // lalr1.cc:617
        break;

      case 95: // state-num

#line 317 "parseaut.yy" // lalr1.cc:617
        { debug_stream() << (yysym.value.num); }
#line 708 "parseaut.cc" // lalr1.cc:617
        break;

      case 96: // checked-state-num

#line 317 "parseaut.yy" // lalr1.cc:617
        { debug_stream() << (yysym.value.num); }
#line 715 "parseaut.cc" // lalr1.cc:617
        break;

      case 111: // state-conj-checked

#line 290 "parseaut.yy" // lalr1.cc:617
        {
  auto& os = debug_stream();
  os << '{';
  bool notfirst = false;
  for (auto i: *(yysym.value.states))
  {
    if (notfirst)
      os << ", ";
    else
      notfirst = true;
    os << i;
  }
  os << '}';
}
#line 735 "parseaut.cc" // lalr1.cc:617
        break;

      case 120: // sign

#line 317 "parseaut.yy" // lalr1.cc:617
        { debug_stream() << (yysym.value.num); }
#line 742 "parseaut.cc" // lalr1.cc:617
        break;

      case 128: // nc-one-ident

#line 312 "parseaut.yy" // lalr1.cc:617
        {
    if ((yysym.value.str))
      debug_stream() << *(yysym.value.str);
    else
      debug_stream() << "\"\""; }
#line 753 "parseaut.cc" // lalr1.cc:617
        break;

      case 129: // nc-ident-list

#line 312 "parseaut.yy" // lalr1.cc:617
        {
    if ((yysym.value.str))
      debug_stream() << *(yysym.value.str);
    else
      debug_stream() << "\"\""; }
#line 764 "parseaut.cc" // lalr1.cc:617
        break;

      case 133: // nc-formula-or-ident

#line 312 "parseaut.yy" // lalr1.cc:617
        {
    if ((yysym.value.str))
      debug_stream() << *(yysym.value.str);
    else
      debug_stream() << "\"\""; }
#line 775 "parseaut.cc" // lalr1.cc:617
        break;

      case 135: // nc-opt-dest

#line 312 "parseaut.yy" // lalr1.cc:617
        {
    if ((yysym.value.str))
      debug_stream() << *(yysym.value.str);
    else
      debug_stream() << "\"\""; }
#line 786 "parseaut.cc" // lalr1.cc:617
        break;


      default:
        break;
    }
    yyo << ')';
  }
#endif

  inline
  void
  parser::yypush_ (const char* m, state_type s, symbol_type& sym)
  {
    stack_symbol_type t (s, sym);
    yypush_ (m, t);
  }

  inline
  void
  parser::yypush_ (const char* m, stack_symbol_type& s)
  {
    if (m)
      YY_SYMBOL_PRINT (m, s);
    yystack_.push (s);
  }

  inline
  void
  parser::yypop_ (unsigned int n)
  {
    yystack_.pop (n);
  }

#if YYDEBUG
  std::ostream&
  parser::debug_stream () const
  {
    return *yycdebug_;
  }

  void
  parser::set_debug_stream (std::ostream& o)
  {
    yycdebug_ = &o;
  }


  parser::debug_level_type
  parser::debug_level () const
  {
    return yydebug_;
  }

  void
  parser::set_debug_level (debug_level_type l)
  {
    yydebug_ = l;
  }
#endif // YYDEBUG

  inline parser::state_type
  parser::yy_lr_goto_state_ (state_type yystate, int yysym)
  {
    int yyr = yypgoto_[yysym - yyntokens_] + yystate;
    if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
      return yytable_[yyr];
    else
      return yydefgoto_[yysym - yyntokens_];
  }

  inline bool
  parser::yy_pact_value_is_default_ (int yyvalue)
  {
    return yyvalue == yypact_ninf_;
  }

  inline bool
  parser::yy_table_value_is_error_ (int yyvalue)
  {
    return yyvalue == yytable_ninf_;
  }

  int
  parser::parse ()
  {
    /// Whether yyla contains a lookahead.
    bool yyempty = true;

    // State.
    int yyn;
    /// Length of the RHS of the rule being reduced.
    int yylen = 0;

    // Error handling.
    int yynerrs_ = 0;
    int yyerrstatus_ = 0;

    /// The lookahead symbol.
    symbol_type yyla;

    /// The locations where the error started and ended.
    stack_symbol_type yyerror_range[3];

    /// The return value of parse ().
    int yyresult;

    // FIXME: This shoud be completely indented.  It is not yet to
    // avoid gratuitous conflicts when merging into the master branch.
    try
      {
    YYCDEBUG << "Starting parse" << std::endl;


    // User initialization code.
    #line 182 "parseaut.yy" // lalr1.cc:725
{ yyla.location = res.h->loc = initial_loc; }

#line 905 "parseaut.cc" // lalr1.cc:725

    /* Initialize the stack.  The initial state will be set in
       yynewstate, since the latter expects the semantical and the
       location values to have been already stored, initialize these
       stacks with a primary value.  */
    yystack_.clear ();
    yypush_ (YY_NULLPTR, 0, yyla);

    // A new symbol was pushed on the stack.
  yynewstate:
    YYCDEBUG << "Entering state " << yystack_[0].state << std::endl;

    // Accept?
    if (yystack_[0].state == yyfinal_)
      goto yyacceptlab;

    goto yybackup;

    // Backup.
  yybackup:

    // Try to take a decision without lookahead.
    yyn = yypact_[yystack_[0].state];
    if (yy_pact_value_is_default_ (yyn))
      goto yydefault;

    // Read a lookahead token.
    if (yyempty)
      {
        YYCDEBUG << "Reading a token: ";
        try
          {
            yyla.type = yytranslate_ (yylex (&yyla.value, &yyla.location, PARSE_ERROR_LIST));
          }
        catch (const syntax_error& yyexc)
          {
            error (yyexc);
            goto yyerrlab1;
          }
        yyempty = false;
      }
    YY_SYMBOL_PRINT ("Next token is", yyla);

    /* If the proper action on seeing token YYLA.TYPE is to reduce or
       to detect an error, take that action.  */
    yyn += yyla.type_get ();
    if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type_get ())
      goto yydefault;

    // Reduce or error.
    yyn = yytable_[yyn];
    if (yyn <= 0)
      {
        if (yy_table_value_is_error_ (yyn))
          goto yyerrlab;
        yyn = -yyn;
        goto yyreduce;
      }

    // Discard the token being shifted.
    yyempty = true;

    // Count tokens shifted since error; after three, turn off error status.
    if (yyerrstatus_)
      --yyerrstatus_;

    // Shift the lookahead token.
    yypush_ ("Shifting", yyn, yyla);
    goto yynewstate;

  /*-----------------------------------------------------------.
  | yydefault -- do the default action for the current state.  |
  `-----------------------------------------------------------*/
  yydefault:
    yyn = yydefact_[yystack_[0].state];
    if (yyn == 0)
      goto yyerrlab;
    goto yyreduce;

  /*-----------------------------.
  | yyreduce -- Do a reduction.  |
  `-----------------------------*/
  yyreduce:
    yylen = yyr2_[yyn];
    {
      stack_symbol_type yylhs;
      yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, yyr1_[yyn]);
      /* If YYLEN is nonzero, implement the default value of the
         action: '$$ = $1'.  Otherwise, use the top of the stack.

         Otherwise, the following line sets YYLHS.VALUE to garbage.
         This behavior is undocumented and Bison users should not rely
         upon it.  */
      if (yylen)
        yylhs.value = yystack_[yylen - 1].value;
      else
        yylhs.value = yystack_[0].value;

      // Compute the default @$.
      {
        slice<stack_symbol_type, stack_type> slice (yystack_, yylen);
        YYLLOC_DEFAULT (yylhs.location, slice, yylen);
      }

      // Perform the reduction.
      YY_REDUCE_PRINT (yyn);
      try
        {
          switch (yyn)
            {
  case 2:
#line 320 "parseaut.yy" // lalr1.cc:847
    { res.h->loc = yylhs.location; YYACCEPT; }
#line 1019 "parseaut.cc" // lalr1.cc:847
    break;

  case 3:
#line 321 "parseaut.yy" // lalr1.cc:847
    { YYABORT; }
#line 1025 "parseaut.cc" // lalr1.cc:847
    break;

  case 4:
#line 322 "parseaut.yy" // lalr1.cc:847
    { YYABORT; }
#line 1031 "parseaut.cc" // lalr1.cc:847
    break;

  case 5:
#line 324 "parseaut.yy" // lalr1.cc:847
    {
       error(yystack_[1].location, "leading garbage was ignored");
       res.h->loc = yystack_[0].location;
       YYACCEPT;
     }
#line 1041 "parseaut.cc" // lalr1.cc:847
    break;

  case 6:
#line 330 "parseaut.yy" // lalr1.cc:847
    { res.h->type = spot::parsed_aut_type::HOA; }
#line 1047 "parseaut.cc" // lalr1.cc:847
    break;

  case 7:
#line 331 "parseaut.yy" // lalr1.cc:847
    { res.h->type = spot::parsed_aut_type::NeverClaim; }
#line 1053 "parseaut.cc" // lalr1.cc:847
    break;

  case 8:
#line 332 "parseaut.yy" // lalr1.cc:847
    { res.h->type = spot::parsed_aut_type::LBTT; }
#line 1059 "parseaut.cc" // lalr1.cc:847
    break;

  case 12:
#line 342 "parseaut.yy" // lalr1.cc:847
    { (yylhs.value.str) = nullptr; }
#line 1065 "parseaut.cc" // lalr1.cc:847
    break;

  case 13:
#line 343 "parseaut.yy" // lalr1.cc:847
    { (yylhs.value.str) = (yystack_[0].value.str); }
#line 1071 "parseaut.cc" // lalr1.cc:847
    break;

  case 16:
#line 347 "parseaut.yy" // lalr1.cc:847
    {
	  // Preallocate the states if we know their number.
	  if (res.states >= 0)
	    {
	      unsigned states = res.states;
	      for (auto& p : res.start)
                for (unsigned s: p.second)
                  if ((unsigned) res.states <= s)
                    {
                      error(p.first, "initial state number is larger "
                            "than state count...");
                      error(res.states_loc, "... declared here.");
                      states = std::max(states, s + 1);
                    }
	      if (res.opts.want_kripke)
		res.h->ks->new_states(states, bddfalse);
	      else
		res.h->aut->new_states(states);
	      res.info_states.resize(states);
	    }
	  if (res.accset < 0)
	    {
	      error(yylhs.location, "missing 'Acceptance:' header");
	      res.ignore_acc = true;
	    }
	  // Process properties.
	  {
	    auto explicit_labels = res.prop_is_true("explicit-labels");
	    auto implicit_labels = res.prop_is_true("implicit-labels");

	    if (implicit_labels)
	      {
		if (res.opts.want_kripke)
		  error(implicit_labels.loc,
			"Kripke structure may not use implicit labels");

		if (explicit_labels)
		  {
		    error(implicit_labels.loc,
			  "'properties: implicit-labels' is incompatible "
			  "with...");
		    error(explicit_labels.loc,
			  "... 'properties: explicit-labels'.");
		  }
		else
		  {
		    res.label_style = Implicit_Labels;
		  }
	      }

	    auto trans_labels = res.prop_is_true("trans-labels");
	    auto state_labels = res.prop_is_true("state-labels");

	    if (trans_labels)
	      {
		if (res.opts.want_kripke)
		  error(trans_labels.loc,
			"Kripke structures may not use transition labels");

		if (state_labels)
		  {
		    error(trans_labels.loc,
			  "'properties: trans-labels' is incompatible with...");
		    error(state_labels.loc,
			  "... 'properties: state-labels'.");
		  }
		else
		  {
		    if (res.label_style != Implicit_Labels)
		      res.label_style = Trans_Labels;
		  }
	      }
	    else if (state_labels)
	      {
		if (res.label_style != Implicit_Labels)
		  {
		    res.label_style = State_Labels;
		  }
		else
		  {
		    error(state_labels.loc,
			  "'properties: state-labels' is incompatible with...");
		    error(implicit_labels.loc,
			  "... 'properties: implicit-labels'.");
		  }
	      }

	    if (res.opts.want_kripke && res.label_style != State_Labels)
	      error(yylhs.location,
		    "Kripke structures should use 'properties: state-labels'");

	    auto state_acc = res.prop_is_true("state-acc");
	    auto trans_acc = res.prop_is_true("trans-acc");
	    if (trans_acc)
	      {
		if (state_acc)
		  {
		    error(trans_acc.loc,
			  "'properties: trans-acc' is incompatible with...");
		    error(state_acc.loc,
			  "... 'properties: state-acc'.");
		  }
		else
		  {
		    res.acc_style = Trans_Acc;
		  }
	      }
	    else if (state_acc)
	      {
		res.acc_style = State_Acc;
	      }

            auto univ_branch = res.prop_is_true("univ-branch");
	    if (res.opts.want_kripke && univ_branch)
	      error(univ_branch.loc,
		    "Kripke structures may not use 'properties: univ-branch'");
          }
	  {
	    unsigned ss = res.start.size();
	    auto det = res.prop_is_true("deterministic");
	    if (ss > 1)
	      {
		if (det)
		  {
		    error(det.loc,
			  "deterministic automata should have at most "
			  "one initial state");
		  }
		res.deterministic = false;
	      }
	    else
	      {
		// Assume the automaton is deterministic until proven
		// wrong, or unless we are building a Kripke structure.
		res.deterministic = !res.opts.want_kripke;
	      }
	    auto complete = res.prop_is_true("complete");
	    if (ss < 1)
	      {
		if (complete)
		  {
		    error(complete.loc,
			  "complete automata should have at least "
			  "one initial state");
		  }
		res.complete = false;
	      }
	    else
	      {
		// Assume the automaton is complete until proven
		// wrong.
		res.complete = !res.opts.want_kripke;
	      }
	    // if ap_count == 0, then a Kripke structure could be
	    // declared complete, although that probably doesn't
	    // matter.
	    if (res.opts.want_kripke && complete && res.ap_count > 0)
	      error(complete.loc,
		    "Kripke structure may not be complete");
	  }
	  if (res.opts.trust_hoa)
	    {
	      auto& a = res.aut_or_ks;
	      auto& p = res.props;
	      auto e = p.end();
	      auto si = p.find("stutter-invariant");
	      if (si != e)
		{
		  a->prop_stutter_invariant(si->second.val);
		  auto i = p.find("stutter-sensitive");
		  if (i != e && si->second.val == i->second.val)
		    error(i->second.loc,
			  "automaton cannot be both stutter-invariant"
			  "and stutter-sensitive");
		}
	      else
		{
		  auto ss = p.find("stutter-sensitive");
		  if (ss != e)
		    a->prop_stutter_invariant(!ss->second.val);
		}
	      auto iw = p.find("inherently-weak");
	      auto vw = p.find("very-weak");
	      auto w = p.find("weak");
	      auto t = p.find("terminal");
              if (vw != e)
                {
                  a->prop_very_weak(vw->second.val);
                  if (w != e && !w->second.val && vw->second.val)
                    {
		      error(w->second.loc,
                            "'properties: !weak' contradicts...");
		      error(vw->second.loc,
			    "... 'properties: very-weak' given here");
                    }
                  if (iw != e && !iw->second.val && vw->second.val)
                    {
		      error(iw->second.loc,
                            "'properties: !inherently-weak' contradicts...");
		      error(vw->second.loc,
			    "... 'properties: very-weak' given here");
                    }
                }
	      if (iw != e)
		{
		  a->prop_inherently_weak(iw->second.val);
		  if (w != e && !iw->second.val && w->second.val)
		    {
		      error(w->second.loc, "'properties: weak' contradicts...");
		      error(iw->second.loc,
			    "... 'properties: !inherently-weak' given here");
		    }
		  if (t != e && !iw->second.val && t->second.val)
		    {
		      error(t->second.loc,
			    "'properties: terminal' contradicts...");
		      error(iw->second.loc,
			    "... 'properties: !inherently-weak' given here");
		    }
		}
	      if (w != e)
		{
		  a->prop_weak(w->second.val);
		  if (t != e && !w->second.val && t->second.val)
		    {
		      error(t->second.loc,
			    "'properties: terminal' contradicts...");
		      error(w->second.loc,
			    "... 'properties: !weak' given here");
		    }
		}
	      if (t != e)
		a->prop_terminal(t->second.val);
	      auto u = p.find("unambiguous");
	      if (u != e)
		{
		  a->prop_unambiguous(u->second.val);
		  auto d = p.find("deterministic");
		  if (d != e && !u->second.val && d->second.val)
		    {
		      error(d->second.loc,
			    "'properties: deterministic' contradicts...");
		      error(u->second.loc,
			    "... 'properties: !unambiguous' given here");
		    }
		}
	      auto sd = p.find("semi-deterministic");
	      if (sd != e)
		{
		  a->prop_semi_deterministic(sd->second.val);
		  auto d = p.find("deterministic");
		  if (d != e && !sd->second.val && d->second.val)
		    {
		      error(d->second.loc,
			    "'properties: deterministic' contradicts...");
		      error(sd->second.loc,
			    "... 'properties: !semi-deterministic' given here");
		    }
		}
	    }
	}
#line 1337 "parseaut.cc" // lalr1.cc:847
    break;

  case 17:
#line 610 "parseaut.yy" // lalr1.cc:847
    {
	   res.format_version = *(yystack_[0].value.str);
	   res.format_version_loc = yystack_[0].location;
	   delete (yystack_[0].value.str);
	 }
#line 1347 "parseaut.cc" // lalr1.cc:847
    break;

  case 18:
#line 616 "parseaut.yy" // lalr1.cc:847
    { res.h->loc = yystack_[0].location; }
#line 1353 "parseaut.cc" // lalr1.cc:847
    break;

  case 20:
#line 619 "parseaut.yy" // lalr1.cc:847
    {
       if (res.ignore_more_ap)
	 {
	   error(yystack_[1].location, "ignoring this redeclaration of APs...");
	   error(res.ap_loc, "... previously declared here.");
	 }
       else
	 {
	   res.ap_count = (yystack_[0].value.num);
	   res.ap.reserve((yystack_[0].value.num));
	 }
     }
#line 1370 "parseaut.cc" // lalr1.cc:847
    break;

  case 21:
#line 632 "parseaut.yy" // lalr1.cc:847
    {
       if (!res.ignore_more_ap)
	 {
	   res.ap_loc = yystack_[3].location + yystack_[2].location;
	   if ((int) res.ap.size() != res.ap_count)
	     {
	       std::ostringstream out;
	       out << "found " << res.ap.size()
		   << " atomic propositions instead of the "
		   << res.ap_count << " announced";
	       error(yylhs.location, out.str());
	     }
	   res.ignore_more_ap = true;
	 }
     }
#line 1390 "parseaut.cc" // lalr1.cc:847
    break;

  case 24:
#line 650 "parseaut.yy" // lalr1.cc:847
    {
	     if (res.states >= 0)
	       {
		 error(yylhs.location, "redefinition of the number of states...");
		 error(res.states_loc, "... previously defined here.");
	       }
	     else
	       {
		 res.states_loc = yylhs.location;
	       }
	     if (((int) (yystack_[0].value.num)) < 0)
	       {
		 error(yylhs.location, "too many states for this implementation");
		 YYABORT;
	       }
	     res.states = std::max(res.states, (int) (yystack_[0].value.num));
	   }
#line 1412 "parseaut.cc" // lalr1.cc:847
    break;

  case 25:
#line 668 "parseaut.yy" // lalr1.cc:847
    {
               res.start.emplace_back(yylhs.location, *(yystack_[0].value.states));
               delete (yystack_[0].value.states);
	     }
#line 1421 "parseaut.cc" // lalr1.cc:847
    break;

  case 26:
#line 673 "parseaut.yy" // lalr1.cc:847
    {
	       res.start.emplace_back(yylhs.location, std::vector<unsigned>{(yystack_[0].value.num)});
	     }
#line 1429 "parseaut.cc" // lalr1.cc:847
    break;

  case 28:
#line 678 "parseaut.yy" // lalr1.cc:847
    {
	       if (!res.alias.emplace(*(yystack_[1].value.str), bdd_from_int((yystack_[0].value.b))).second)
		 {
		   std::ostringstream o;
		   o << "ignoring redefinition of alias @" << *(yystack_[1].value.str);
		   error(yylhs.location, o.str());
		 }
	       delete (yystack_[1].value.str);
	       bdd_delref((yystack_[0].value.b));
	     }
#line 1444 "parseaut.cc" // lalr1.cc:847
    break;

  case 29:
#line 689 "parseaut.yy" // lalr1.cc:847
    {
		if (res.ignore_more_acc)
		  {
		    error(yystack_[1].location + yystack_[0].location, "ignoring this redefinition of the "
			  "acceptance condition...");
		    error(res.accset_loc, "... previously defined here.");
		  }
		else if ((yystack_[0].value.num) > 8 * sizeof(spot::acc_cond::mark_t::value_t))
		  {
		    error(yystack_[1].location + yystack_[0].location,
			  "this implementation cannot support such a large "
			  "number of acceptance sets");
		    YYABORT;
		  }
		else
		  {
		    res.aut_or_ks->acc().add_sets((yystack_[0].value.num));
		    res.accset = (yystack_[0].value.num);
		    res.accset_loc = yystack_[1].location + yystack_[0].location;
		  }
	     }
#line 1470 "parseaut.cc" // lalr1.cc:847
    break;

  case 30:
#line 711 "parseaut.yy" // lalr1.cc:847
    {
	       res.ignore_more_acc = true;
	       // Not setting the acceptance in case of error will
	       // force it to be true.
	       if (res.opts.want_kripke && (!(yystack_[0].value.code)->is_t() || (yystack_[2].value.num) > 0))
		 error(yystack_[2].location + yystack_[0].location,
		       "the acceptance for Kripke structure must be '0 t'");
	       else
		 res.aut_or_ks->set_acceptance((yystack_[2].value.num), *(yystack_[0].value.code));
	       delete (yystack_[0].value.code);
	     }
#line 1486 "parseaut.cc" // lalr1.cc:847
    break;

  case 31:
#line 723 "parseaut.yy" // lalr1.cc:847
    {
	       delete (yystack_[1].value.str);
	     }
#line 1494 "parseaut.cc" // lalr1.cc:847
    break;

  case 32:
#line 727 "parseaut.yy" // lalr1.cc:847
    {
	       delete (yystack_[1].value.str);
	       delete (yystack_[0].value.str);
	     }
#line 1503 "parseaut.cc" // lalr1.cc:847
    break;

  case 33:
#line 732 "parseaut.yy" // lalr1.cc:847
    {
	       res.aut_or_ks->set_named_prop("automaton-name", (yystack_[0].value.str));
	     }
#line 1511 "parseaut.cc" // lalr1.cc:847
    break;

  case 35:
#line 737 "parseaut.yy" // lalr1.cc:847
    { res.highlight_edges = new std::map<unsigned, unsigned>; }
#line 1517 "parseaut.cc" // lalr1.cc:847
    break;

  case 37:
#line 740 "parseaut.yy" // lalr1.cc:847
    { res.highlight_states = new std::map<unsigned, unsigned>; }
#line 1523 "parseaut.cc" // lalr1.cc:847
    break;

  case 39:
#line 743 "parseaut.yy" // lalr1.cc:847
    {
	       char c = (*(yystack_[1].value.str))[0];
	       if (c >= 'A' && c <= 'Z')
		 error(yylhs.location, "ignoring unsupported header \"" + *(yystack_[1].value.str) + ":\"\n\t"
		       "(but the capital indicates information that should not"
		       " be ignored)");
	       delete (yystack_[1].value.str);
	     }
#line 1536 "parseaut.cc" // lalr1.cc:847
    break;

  case 43:
#line 755 "parseaut.yy" // lalr1.cc:847
    {
	   if (!res.ignore_more_ap)
	     {
	       auto f = res.env->require(*(yystack_[0].value.str));
	       int b = 0;
	       if (f == nullptr)
		 {
		   std::ostringstream out;
		   out << "unknown atomic proposition \"" << *(yystack_[0].value.str) << "\"";
		   error(yystack_[0].location, out.str());
		   b = res.aut_or_ks->register_ap("$unknown$");
		 }
	       else
		 {
		   b = res.aut_or_ks->register_ap(f);
		   if (!res.ap_set.emplace(b).second)
		     {
		       std::ostringstream out;
		       out << "duplicate atomic proposition \"" << *(yystack_[0].value.str) << "\"";
		       error(yystack_[0].location, out.str());
		     }
		 }
	       res.ap.push_back(b);
	     }
	   delete (yystack_[0].value.str);
	 }
#line 1567 "parseaut.cc" // lalr1.cc:847
    break;

  case 47:
#line 785 "parseaut.yy" // lalr1.cc:847
    {
	      delete (yystack_[0].value.str);
	    }
#line 1575 "parseaut.cc" // lalr1.cc:847
    break;

  case 49:
#line 789 "parseaut.yy" // lalr1.cc:847
    {
                bool val = true;
                // no-univ-branch was replaced by !univ-branch in HOA 1.1
                if (*(yystack_[0].value.str) == "no-univ-branch")
                  {
                    *(yystack_[0].value.str) = "univ-branch";
                    val = false;
                  }
		auto pos = res.props.emplace(*(yystack_[0].value.str), result_::prop_info{yystack_[0].location, val});
		if (pos.first->second.val != val)
		  {
		    std::ostringstream out(std::ios_base::ate);
		    error(yystack_[0].location, std::string("'properties: ")
			  + (val ? "" : "!") + *(yystack_[0].value.str) + "' contradicts...");
		    error(pos.first->second.loc,
			  std::string("... 'properties: ")
                          + (val ? "!" : "") + *(yystack_[0].value.str)
			  + "' previously given here.");
		  }
		delete (yystack_[0].value.str);
	      }
#line 1601 "parseaut.cc" // lalr1.cc:847
    break;

  case 50:
#line 811 "parseaut.yy" // lalr1.cc:847
    {
		auto loc = yystack_[1].location + yystack_[0].location;
		auto pos =
		  res.props.emplace(*(yystack_[0].value.str), result_::prop_info{loc, false});
		if (pos.first->second.val)
		  {
		    std::ostringstream out(std::ios_base::ate);
		    error(loc, std::string("'properties: !")
			  + *(yystack_[0].value.str) + "' contradicts...");
		    error(pos.first->second.loc,
			  std::string("... 'properties: ") + *(yystack_[0].value.str)
			  + "' previously given here.");
		  }
		delete (yystack_[0].value.str);
	      }
#line 1621 "parseaut.cc" // lalr1.cc:847
    break;

  case 52:
#line 828 "parseaut.yy" // lalr1.cc:847
    {
		res.highlight_edges->emplace((yystack_[1].value.num), (yystack_[0].value.num));
	      }
#line 1629 "parseaut.cc" // lalr1.cc:847
    break;

  case 54:
#line 832 "parseaut.yy" // lalr1.cc:847
    {
		res.highlight_states->emplace((yystack_[1].value.num), (yystack_[0].value.num));
	      }
#line 1637 "parseaut.cc" // lalr1.cc:847
    break;

  case 58:
#line 839 "parseaut.yy" // lalr1.cc:847
    {
		 delete (yystack_[0].value.str);
	       }
#line 1645 "parseaut.cc" // lalr1.cc:847
    break;

  case 59:
#line 843 "parseaut.yy" // lalr1.cc:847
    {
		 delete (yystack_[0].value.str);
	       }
#line 1653 "parseaut.cc" // lalr1.cc:847
    break;

  case 60:
#line 848 "parseaut.yy" // lalr1.cc:847
    {
              (yylhs.value.states) = new std::vector<unsigned>{(yystack_[2].value.num), (yystack_[0].value.num)};
            }
#line 1661 "parseaut.cc" // lalr1.cc:847
    break;

  case 61:
#line 852 "parseaut.yy" // lalr1.cc:847
    {
              (yylhs.value.states) = (yystack_[2].value.states);
              (yylhs.value.states)->emplace_back((yystack_[0].value.num));
            }
#line 1670 "parseaut.cc" // lalr1.cc:847
    break;

  case 62:
#line 860 "parseaut.yy" // lalr1.cc:847
    {
              (yylhs.value.states) = new std::vector<unsigned>{(yystack_[2].value.num), (yystack_[0].value.num)};
            }
#line 1678 "parseaut.cc" // lalr1.cc:847
    break;

  case 63:
#line 864 "parseaut.yy" // lalr1.cc:847
    {
              (yylhs.value.states) = (yystack_[2].value.states);
              (yylhs.value.states)->emplace_back((yystack_[0].value.num));
            }
#line 1687 "parseaut.cc" // lalr1.cc:847
    break;

  case 64:
#line 870 "parseaut.yy" // lalr1.cc:847
    {
	      (yylhs.value.b) = bddtrue.id();
	    }
#line 1695 "parseaut.cc" // lalr1.cc:847
    break;

  case 65:
#line 874 "parseaut.yy" // lalr1.cc:847
    {
	      (yylhs.value.b) = bddfalse.id();
	    }
#line 1703 "parseaut.cc" // lalr1.cc:847
    break;

  case 66:
#line 878 "parseaut.yy" // lalr1.cc:847
    {
	      if ((yystack_[0].value.num) >= res.ap.size())
		{
		  error(yystack_[0].location, "AP number is larger than the number of APs...");
		  error(res.ap_loc, "... declared here");
		  (yylhs.value.b) = bddtrue.id();
		}
	      else
		{
		  (yylhs.value.b) = bdd_ithvar(res.ap[(yystack_[0].value.num)]).id();
		  bdd_addref((yylhs.value.b));
		}
	    }
#line 1721 "parseaut.cc" // lalr1.cc:847
    break;

  case 67:
#line 892 "parseaut.yy" // lalr1.cc:847
    {
	      auto i = res.alias.find(*(yystack_[0].value.str));
	      if (i == res.alias.end())
		{
		  error(yylhs.location, "unknown alias @" + *(yystack_[0].value.str));
		  (yylhs.value.b) = 1;
		}
	      else
		{
		  (yylhs.value.b) = i->second.id();
		  bdd_addref((yylhs.value.b));
		}
	      delete (yystack_[0].value.str);
	    }
#line 1740 "parseaut.cc" // lalr1.cc:847
    break;

  case 68:
#line 907 "parseaut.yy" // lalr1.cc:847
    {
              (yylhs.value.b) = bdd_not((yystack_[0].value.b));
              bdd_delref((yystack_[0].value.b));
              bdd_addref((yylhs.value.b));
            }
#line 1750 "parseaut.cc" // lalr1.cc:847
    break;

  case 69:
#line 913 "parseaut.yy" // lalr1.cc:847
    {
              (yylhs.value.b) = bdd_and((yystack_[2].value.b), (yystack_[0].value.b));
              bdd_delref((yystack_[2].value.b));
              bdd_delref((yystack_[0].value.b));
              bdd_addref((yylhs.value.b));
            }
#line 1761 "parseaut.cc" // lalr1.cc:847
    break;

  case 70:
#line 920 "parseaut.yy" // lalr1.cc:847
    {
              (yylhs.value.b) = bdd_or((yystack_[2].value.b), (yystack_[0].value.b));
              bdd_delref((yystack_[2].value.b));
              bdd_delref((yystack_[0].value.b));
              bdd_addref((yylhs.value.b));
            }
#line 1772 "parseaut.cc" // lalr1.cc:847
    break;

  case 71:
#line 927 "parseaut.yy" // lalr1.cc:847
    {
	    (yylhs.value.b) = (yystack_[1].value.b);
	  }
#line 1780 "parseaut.cc" // lalr1.cc:847
    break;

  case 72:
#line 933 "parseaut.yy" // lalr1.cc:847
    {
	      if ((int) (yystack_[0].value.num) >= res.accset)
		{
		  if (!res.ignore_acc)
		    {
		      error(yystack_[0].location, "number is larger than the count "
			    "of acceptance sets...");
		      error(res.accset_loc, "... declared here.");
		    }
		  (yylhs.value.num) = -1U;
		}
	      else
		{
		  (yylhs.value.num) = (yystack_[0].value.num);
		}
	    }
#line 1801 "parseaut.cc" // lalr1.cc:847
    break;

  case 73:
#line 951 "parseaut.yy" // lalr1.cc:847
    {
		   if ((yystack_[1].value.num) != -1U)
		     {
		       res.pos_acc_sets |= res.aut_or_ks->acc().mark((yystack_[1].value.num));
		       if (*(yystack_[3].value.str) == "Inf")
                         {
                           (yylhs.value.code) = new spot::acc_cond::acc_code
                             (res.aut_or_ks->acc().inf({(yystack_[1].value.num)}));
                         }
		       else if (*(yystack_[3].value.str) == "Fin")
                         {
                           (yylhs.value.code) = new spot::acc_cond::acc_code
                             (res.aut_or_ks->acc().fin({(yystack_[1].value.num)}));
                         }
                       else
                         {
                           error(yystack_[3].location, std::string("unknown acceptance '") + *(yystack_[3].value.str)
                                 + "', expected Fin or Inf");
                           (yylhs.value.code) = new spot::acc_cond::acc_code;
                         }
		     }
		   else
		     {
		       (yylhs.value.code) = new spot::acc_cond::acc_code;
		     }
		   delete (yystack_[3].value.str);
		 }
#line 1833 "parseaut.cc" // lalr1.cc:847
    break;

  case 74:
#line 979 "parseaut.yy" // lalr1.cc:847
    {
		   if ((yystack_[1].value.num) != -1U)
		     {
		       res.neg_acc_sets |= res.aut_or_ks->acc().mark((yystack_[1].value.num));
		       if (*(yystack_[4].value.str) == "Inf")
			 (yylhs.value.code) = new spot::acc_cond::acc_code
			   (res.aut_or_ks->acc().inf_neg({(yystack_[1].value.num)}));
		       else
			 (yylhs.value.code) = new spot::acc_cond::acc_code
			   (res.aut_or_ks->acc().fin_neg({(yystack_[1].value.num)}));
		     }
		   else
		     {
		       (yylhs.value.code) = new spot::acc_cond::acc_code;
		     }
		   delete (yystack_[4].value.str);
		 }
#line 1855 "parseaut.cc" // lalr1.cc:847
    break;

  case 75:
#line 997 "parseaut.yy" // lalr1.cc:847
    {
		   (yylhs.value.code) = (yystack_[1].value.code);
		 }
#line 1863 "parseaut.cc" // lalr1.cc:847
    break;

  case 76:
#line 1001 "parseaut.yy" // lalr1.cc:847
    {
		   *(yystack_[0].value.code) &= std::move(*(yystack_[2].value.code));
		   (yylhs.value.code) = (yystack_[0].value.code);
		   delete (yystack_[2].value.code);
		 }
#line 1873 "parseaut.cc" // lalr1.cc:847
    break;

  case 77:
#line 1007 "parseaut.yy" // lalr1.cc:847
    {
		   *(yystack_[0].value.code) |= std::move(*(yystack_[2].value.code));
		   (yylhs.value.code) = (yystack_[0].value.code);
		   delete (yystack_[2].value.code);
		 }
#line 1883 "parseaut.cc" // lalr1.cc:847
    break;

  case 78:
#line 1013 "parseaut.yy" // lalr1.cc:847
    {
		   (yylhs.value.code) = new spot::acc_cond::acc_code;
		 }
#line 1891 "parseaut.cc" // lalr1.cc:847
    break;

  case 79:
#line 1017 "parseaut.yy" // lalr1.cc:847
    {
	         {
		   (yylhs.value.code) = new spot::acc_cond::acc_code
		     (res.aut_or_ks->acc().fin({}));
		 }
	       }
#line 1902 "parseaut.cc" // lalr1.cc:847
    break;

  case 80:
#line 1026 "parseaut.yy" // lalr1.cc:847
    {
	for (auto& p: res.start)
          for (unsigned s: p.second)
            if (s >= res.info_states.size() || !res.info_states[s].declared)
              {
                error(p.first, "initial state " + std::to_string(s) +
                      " has no definition");
                // Pretend that the state is declared so we do not
                // mention it in the next loop.
                if (s < res.info_states.size())
                  res.info_states[s].declared = true;
              }
	unsigned n = res.info_states.size();
	// States with number above res.states have already caused a
	// diagnostic, so let not add another one.
	if (res.states >= 0)
	  n = res.states;
	for (unsigned i = 0; i < n; ++i)
	  {
	    auto& p = res.info_states[i];
	    if (p.used && !p.declared)
	      error(p.used_loc,
		    "state " + std::to_string(i) + " has no definition");
	  }
      }
#line 1932 "parseaut.cc" // lalr1.cc:847
    break;

  case 81:
#line 1053 "parseaut.yy" // lalr1.cc:847
    {
	     if (((int) (yystack_[0].value.num)) < 0)
	       {
		 error(yystack_[0].location, "state number is too large for this implementation");
		 YYABORT;
	       }
	     (yylhs.value.num) = (yystack_[0].value.num);
	   }
#line 1945 "parseaut.cc" // lalr1.cc:847
    break;

  case 82:
#line 1063 "parseaut.yy" // lalr1.cc:847
    {
		     if ((int) (yystack_[0].value.num) >= res.states)
		       {
			 if (res.states >= 0)
			   {
			     error(yystack_[0].location, "state number is larger than state "
				   "count...");
			     error(res.states_loc, "... declared here.");
			   }
			 if (res.opts.want_kripke)
			   {
			     int missing =
			       ((int) (yystack_[0].value.num)) - res.h->ks->num_states() + 1;
			     if (missing >= 0)
			       {
				 res.h->ks->new_states(missing, bddfalse);
				 res.info_states.resize
				   (res.info_states.size() + missing);
			       }
			   }
			 else
			   {
			     int missing =
			       ((int) (yystack_[0].value.num)) - res.h->aut->num_states() + 1;
			     if (missing >= 0)
			       {
				 res.h->aut->new_states(missing);
				 res.info_states.resize
				   (res.info_states.size() + missing);
			       }
			   }
		       }
		     // Remember the first place were a state is the
		     // destination of a transition.
		     if (!res.info_states[(yystack_[0].value.num)].used)
		       {
			 res.info_states[(yystack_[0].value.num)].used = true;
			 res.info_states[(yystack_[0].value.num)].used_loc = yystack_[0].location;
		       }
		     (yylhs.value.num) = (yystack_[0].value.num);
		   }
#line 1991 "parseaut.cc" // lalr1.cc:847
    break;

  case 84:
#line 1106 "parseaut.yy" // lalr1.cc:847
    {
	  if ((res.deterministic || res.complete) && !res.opts.want_kripke)
	    {
	      bdd available = bddtrue;
	      bool det = true;
	      for (auto& t: res.h->aut->out(res.cur_state))
		{
		  if (det && !bdd_implies(t.cond, available))
		    det = false;
		  available -= t.cond;
		}
	      if (res.deterministic && !det)
		{
		  res.deterministic = false;
		  if (auto p = res.prop_is_true("deterministic"))
		    {
		      error(yystack_[0].location, "automaton is not deterministic...");
		      error(p.loc,
			    "... despite 'properties: deterministic'");
		    }
		}
	      if (res.complete && available != bddfalse)
		{
		  res.complete = false;
		  if (auto p = res.prop_is_true("complete"))
		    {
		      error(yystack_[0].location, "automaton is not complete...");
		      error(p.loc, "... despite 'properties: complete'");
		    }
		}
	    }
	}
#line 2028 "parseaut.cc" // lalr1.cc:847
    break;

  case 86:
#line 1140 "parseaut.yy" // lalr1.cc:847
    {
	 if (!res.has_state_label) // Implicit labels
	   {
	     if (res.cur_guard != res.guards.end())
	       error(yylhs.location, "not enough transitions for this state");

	     if (res.label_style == State_Labels)
	       {
		 error(yystack_[0].location, "these transitions have implicit labels but the"
		       " automaton is...");
		 error(res.props["state-labels"].loc, "... declared with "
		       "'properties: state-labels'");
		 // Do not repeat this message.
		 res.label_style = Mixed_Labels;
	       }
	     res.cur_guard = res.guards.begin();
	   }
	 else if (res.opts.want_kripke)
	   {
	     res.h->ks->state_from_number(res.cur_state)->cond(res.state_label);
	   }

       }
#line 2056 "parseaut.cc" // lalr1.cc:847
    break;

  case 87:
#line 1164 "parseaut.yy" // lalr1.cc:847
    {
	 // Assume the worse.  This skips the tests about determinism
	 // we might perform on the state.
	 res.deterministic = spot::trival::maybe();
	 res.complete = false;
       }
#line 2067 "parseaut.cc" // lalr1.cc:847
    break;

  case 88:
#line 1173 "parseaut.yy" // lalr1.cc:847
    {
	    res.cur_state = (yystack_[2].value.num);
	    if (res.info_states[(yystack_[2].value.num)].declared)
	      {
		std::ostringstream o;
		o << "redeclaration of state " << (yystack_[2].value.num);
		error(yystack_[4].location + yystack_[2].location, o.str());
	      }
	    res.info_states[(yystack_[2].value.num)].declared = true;
	    res.acc_state = (yystack_[0].value.mark);
	    if ((yystack_[1].value.str))
	      {
		if (!res.state_names)
		  res.state_names =
		    new std::vector<std::string>(res.states > 0 ?
						 res.states : 0);
		if (res.state_names->size() < (yystack_[2].value.num) + 1)
		  res.state_names->resize((yystack_[2].value.num) + 1);
		(*res.state_names)[(yystack_[2].value.num)] = std::move(*(yystack_[1].value.str));
		delete (yystack_[1].value.str);
	      }
	    if (res.opts.want_kripke && !res.has_state_label)
	      error(yylhs.location, "Kripke structures should have labeled states");
	  }
#line 2096 "parseaut.cc" // lalr1.cc:847
    break;

  case 89:
#line 1198 "parseaut.yy" // lalr1.cc:847
    {
             res.cur_label = bdd_from_int((yystack_[1].value.b));
             bdd_delref((yystack_[1].value.b));
	   }
#line 2105 "parseaut.cc" // lalr1.cc:847
    break;

  case 90:
#line 1203 "parseaut.yy" // lalr1.cc:847
    {
	     error(yylhs.location, "ignoring this invalid label");
	     res.cur_label = bddtrue;
	   }
#line 2114 "parseaut.cc" // lalr1.cc:847
    break;

  case 91:
#line 1207 "parseaut.yy" // lalr1.cc:847
    { res.has_state_label = false; }
#line 2120 "parseaut.cc" // lalr1.cc:847
    break;

  case 92:
#line 1209 "parseaut.yy" // lalr1.cc:847
    {
		 res.has_state_label = true;
		 res.state_label_loc = yystack_[0].location;
		 res.state_label = res.cur_label;
		 if (res.label_style == Trans_Labels
		     || res.label_style == Implicit_Labels)
		   {
		     error(yylhs.location,
			   "state label used although the automaton was...");
		     if (res.label_style == Trans_Labels)
		       error(res.props["trans-labels"].loc,
			     "... declared with 'properties: trans-labels'"
			     " here");
		     else
		       error(res.props["implicit-labels"].loc,
			     "... declared with 'properties: implicit-labels'"
			     " here");
		     // Do not show this error anymore.
		     res.label_style = Mixed_Labels;
		   }
	       }
#line 2146 "parseaut.cc" // lalr1.cc:847
    break;

  case 93:
#line 1231 "parseaut.yy" // lalr1.cc:847
    {
		   if (res.has_state_label)
		     {
		       error(yystack_[0].location, "cannot label this edge because...");
		       error(res.state_label_loc,
			     "... the state is already labeled.");
		       res.cur_label = res.state_label;
		     }
		   if (res.label_style == State_Labels
		       || res.label_style == Implicit_Labels)
		     {
		       error(yylhs.location, "transition label used although the "
			     "automaton was...");
		       if (res.label_style == State_Labels)
			 error(res.props["state-labels"].loc,
			       "... declared with 'properties: state-labels' "
			       "here");
		       else
			 error(res.props["implicit-labels"].loc,
			       "... declared with 'properties: implicit-labels'"
			       " here");
		       // Do not show this error anymore.
		       res.label_style = Mixed_Labels;
		     }
		 }
#line 2176 "parseaut.cc" // lalr1.cc:847
    break;

  case 94:
#line 1258 "parseaut.yy" // lalr1.cc:847
    {
	       (yylhs.value.mark) = (yystack_[1].value.mark);
	       if (res.ignore_acc && !res.ignore_acc_silent)
		 {
		   error(yylhs.location, "ignoring acceptance sets because of "
			 "missing acceptance condition");
		   // Emit this message only once.
		   res.ignore_acc_silent = true;
		 }
	     }
#line 2191 "parseaut.cc" // lalr1.cc:847
    break;

  case 95:
#line 1269 "parseaut.yy" // lalr1.cc:847
    {
	       error(yylhs.location, "ignoring this invalid acceptance set");
	     }
#line 2199 "parseaut.cc" // lalr1.cc:847
    break;

  case 96:
#line 1273 "parseaut.yy" // lalr1.cc:847
    {
	    (yylhs.value.mark) = spot::acc_cond::mark_t(0U);
	  }
#line 2207 "parseaut.cc" // lalr1.cc:847
    break;

  case 97:
#line 1277 "parseaut.yy" // lalr1.cc:847
    {
	    if (res.ignore_acc || (yystack_[0].value.num) == -1U)
	      (yylhs.value.mark) = spot::acc_cond::mark_t(0U);
	    else
	      (yylhs.value.mark) = (yystack_[1].value.mark) | res.aut_or_ks->acc().mark((yystack_[0].value.num));
	  }
#line 2218 "parseaut.cc" // lalr1.cc:847
    break;

  case 98:
#line 1285 "parseaut.yy" // lalr1.cc:847
    {
                 (yylhs.value.mark) = spot::acc_cond::mark_t(0U);
               }
#line 2226 "parseaut.cc" // lalr1.cc:847
    break;

  case 99:
#line 1289 "parseaut.yy" // lalr1.cc:847
    {
		 (yylhs.value.mark) = (yystack_[0].value.mark);
		 if (res.acc_style == Trans_Acc)
		   {
		     error(yylhs.location, "state-based acceptance used despite...");
		     error(res.props["trans-acc"].loc,
			   "... declaration of transition-based acceptance.");
		     res.acc_style = Mixed_Acc;
		   }
	       }
#line 2241 "parseaut.cc" // lalr1.cc:847
    break;

  case 100:
#line 1300 "parseaut.yy" // lalr1.cc:847
    {
                 (yylhs.value.mark) = spot::acc_cond::mark_t(0U);
               }
#line 2249 "parseaut.cc" // lalr1.cc:847
    break;

  case 101:
#line 1304 "parseaut.yy" // lalr1.cc:847
    {
		 (yylhs.value.mark) = (yystack_[0].value.mark);
		 res.trans_acc_seen = true;
		 if (res.acc_style == State_Acc)
		   {
		     error(yylhs.location, "trans-based acceptance used despite...");
		     error(res.props["state-acc"].loc,
			   "... declaration of state-based acceptance.");
		     res.acc_style = Mixed_Acc;
		   }
	       }
#line 2265 "parseaut.cc" // lalr1.cc:847
    break;

  case 107:
#line 1322 "parseaut.yy" // lalr1.cc:847
    {
			      bdd cond = bddtrue;
			      if (!res.has_state_label)
				error(yylhs.location, "missing label for this edge "
				      "(previous edge is labeled)");
			      else
				cond = res.state_label;
			      if (cond != bddfalse)
				{
				  if (res.opts.want_kripke)
				    res.h->ks->new_edge(res.cur_state, (yystack_[1].value.num));
				  else
				    res.h->aut->new_edge(res.cur_state, (yystack_[1].value.num),
							 cond,
							 (yystack_[0].value.mark) | res.acc_state);
				}
			    }
#line 2287 "parseaut.cc" // lalr1.cc:847
    break;

  case 108:
#line 1340 "parseaut.yy" // lalr1.cc:847
    {
		if (res.cur_label != bddfalse)
		  {
		    if (res.opts.want_kripke)
		      res.h->ks->new_edge(res.cur_state, (yystack_[1].value.num));
		    else
		      res.h->aut->new_edge(res.cur_state, (yystack_[1].value.num),
					   res.cur_label, (yystack_[0].value.mark) | res.acc_state);
		  }
	      }
#line 2302 "parseaut.cc" // lalr1.cc:847
    break;

  case 109:
#line 1351 "parseaut.yy" // lalr1.cc:847
    {
                if (res.cur_label != bddfalse)
                  {
                    assert(!res.opts.want_kripke);
                    res.h->aut->new_univ_edge(res.cur_state,
                                              (yystack_[1].value.states)->begin(), (yystack_[1].value.states)->end(),
                                              res.cur_label,
                                              (yystack_[0].value.mark) | res.acc_state);
                  }
                delete (yystack_[1].value.states);
	      }
#line 2318 "parseaut.cc" // lalr1.cc:847
    break;

  case 110:
#line 1364 "parseaut.yy" // lalr1.cc:847
    {
                (yylhs.value.states) = (yystack_[0].value.states);
                if (auto ub = res.prop_is_false("univ-branch"))
                  {
                    error(yystack_[0].location, "universal branch used despite"
                          " previous declaration...");
                    error(ub.loc, "... here");
                  }
              }
#line 2332 "parseaut.cc" // lalr1.cc:847
    break;

  case 114:
#line 1381 "parseaut.yy" // lalr1.cc:847
    {
		  bdd cond;
		  if (res.has_state_label)
		    {
		      cond = res.state_label;
		    }
		  else
		    {
		      if (res.guards.empty())
			fill_guards(res);
		      if (res.cur_guard == res.guards.end())
			{
			  error(yylhs.location, "too many transitions for this state, "
				"ignoring this one");
			  cond = bddfalse;
			}
		      else
			{
			  cond = *res.cur_guard++;
			}
		    }
		  if (cond != bddfalse)
		    {
		      if (res.opts.want_kripke)
			res.h->ks->new_edge(res.cur_state, (yystack_[1].value.num));
		      else
			res.h->aut->new_edge(res.cur_state, (yystack_[1].value.num),
					     cond, (yystack_[0].value.mark) | res.acc_state);
		    }
		}
#line 2367 "parseaut.cc" // lalr1.cc:847
    break;

  case 115:
#line 1412 "parseaut.yy" // lalr1.cc:847
    {
		  bdd cond;
		  if (res.has_state_label)
		    {
		      cond = res.state_label;
		    }
		  else
		    {
		      if (res.guards.empty())
			fill_guards(res);
		      if (res.cur_guard == res.guards.end())
			{
			  error(yylhs.location, "too many transitions for this state, "
				"ignoring this one");
			  cond = bddfalse;
			}
		      else
			{
			  cond = *res.cur_guard++;
			}
		    }
		  if (cond != bddfalse)
		    {
		      assert(!res.opts.want_kripke);
                      res.h->aut->new_univ_edge(res.cur_state,
                                                (yystack_[1].value.states)->begin(), (yystack_[1].value.states)->end(),
                                                cond, (yystack_[0].value.mark) | res.acc_state);
		    }
                  delete (yystack_[1].value.states);
		}
#line 2402 "parseaut.cc" // lalr1.cc:847
    break;

  case 116:
#line 1443 "parseaut.yy" // lalr1.cc:847
    {
			    error(yystack_[1].location, "ignoring this label, because previous"
				  " edge has no label");
                          }
#line 2411 "parseaut.cc" // lalr1.cc:847
    break;

  case 118:
#line 1455 "parseaut.yy" // lalr1.cc:847
    {
	 error(yylhs.location, "failed to parse this as an ltl2dstar automaton");
       }
#line 2419 "parseaut.cc" // lalr1.cc:847
    break;

  case 119:
#line 1460 "parseaut.yy" // lalr1.cc:847
    {
         res.h->type = spot::parsed_aut_type::DRA;
         res.plus = 1;
         res.minus = 0;
	 if (res.opts.want_kripke)
	   {
	     error(yylhs.location,
		   "cannot read a Kripke structure out of a DSTAR automaton");
	     YYABORT;
	   }
       }
#line 2435 "parseaut.cc" // lalr1.cc:847
    break;

  case 120:
#line 1472 "parseaut.yy" // lalr1.cc:847
    {
	 res.h->type = spot::parsed_aut_type::DSA;
         res.plus = 0;
         res.minus = 1;
	 if (res.opts.want_kripke)
	   {
	     error(yylhs.location,
		   "cannot read a Kripke structure out of a DSTAR automaton");
	     YYABORT;
	   }
       }
#line 2451 "parseaut.cc" // lalr1.cc:847
    break;

  case 121:
#line 1485 "parseaut.yy" // lalr1.cc:847
    {
    if (res.states < 0)
      error(yystack_[0].location, "missing state count");
    if (!res.ignore_more_acc)
      error(yystack_[0].location, "missing acceptance-pair count");
    if (res.start.empty())
      error(yystack_[0].location, "missing start-state number");
    if (!res.ignore_more_ap)
      error(yystack_[0].location, "missing atomic propositions definition");

    if (res.states > 0)
      {
	res.h->aut->new_states(res.states);;
	res.info_states.resize(res.states);
      }
    res.acc_style = State_Acc;
    res.deterministic = true;
    // res.h->aut->prop_complete();
    fill_guards(res);
    res.cur_guard = res.guards.end();
  }
#line 2477 "parseaut.cc" // lalr1.cc:847
    break;

  case 124:
#line 1510 "parseaut.yy" // lalr1.cc:847
    {
    if (res.ignore_more_acc)
      {
	error(yystack_[2].location + yystack_[1].location, "ignoring this redefinition of the "
	      "acceptance pairs...");
	error(res.accset_loc, "... previously defined here.");
      }
    else{
      res.accset = (yystack_[0].value.num);
      res.h->aut->set_acceptance(2 * (yystack_[0].value.num),
				 res.h->type == spot::parsed_aut_type::DRA
				 ? spot::acc_cond::acc_code::rabin((yystack_[0].value.num))
				 : spot::acc_cond::acc_code::streett((yystack_[0].value.num)));
      res.accset_loc = yystack_[0].location;
      res.ignore_more_acc = true;
    }
  }
#line 2499 "parseaut.cc" // lalr1.cc:847
    break;

  case 125:
#line 1528 "parseaut.yy" // lalr1.cc:847
    {
    if (res.states < 0)
      {
	res.states = (yystack_[0].value.num);
      }
    else
      {
	error(yylhs.location, "redeclaration of state count");
	if ((unsigned) res.states < (yystack_[0].value.num))
	  res.states = (yystack_[0].value.num);
      }
  }
#line 2516 "parseaut.cc" // lalr1.cc:847
    break;

  case 126:
#line 1541 "parseaut.yy" // lalr1.cc:847
    {
    res.start.emplace_back(yystack_[0].location, std::vector<unsigned>{(yystack_[0].value.num)});
  }
#line 2524 "parseaut.cc" // lalr1.cc:847
    break;

  case 128:
#line 1547 "parseaut.yy" // lalr1.cc:847
    {
    if (res.cur_guard != res.guards.end())
      error(yystack_[2].location, "not enough transitions for previous state");
    if (res.states < 0 || (yystack_[1].value.num) >= (unsigned) res.states)
      {
	std::ostringstream o;
	if (res.states > 0)
	  {
	    o << "state numbers should be in the range [0.."
	      << res.states - 1 << "]";
	  }
	else
	  {
	    o << "no states have been declared";
	  }
	error(yystack_[1].location, o.str());
      }
    else
      {
	res.info_states[(yystack_[1].value.num)].declared = true;

	if ((yystack_[0].value.str))
	  {
	    if (!res.state_names)
	      res.state_names =
		new std::vector<std::string>(res.states > 0 ?
					     res.states : 0);
	    if (res.state_names->size() < (yystack_[1].value.num) + 1)
	      res.state_names->resize((yystack_[1].value.num) + 1);
	    (*res.state_names)[(yystack_[1].value.num)] = std::move(*(yystack_[0].value.str));
	    delete (yystack_[0].value.str);
	  }
      }

    res.cur_guard = res.guards.begin();
    res.dest_map.clear();
    res.cur_state = (yystack_[1].value.num);
  }
#line 2567 "parseaut.cc" // lalr1.cc:847
    break;

  case 129:
#line 1586 "parseaut.yy" // lalr1.cc:847
    { (yylhs.value.num) = res.plus; }
#line 2573 "parseaut.cc" // lalr1.cc:847
    break;

  case 130:
#line 1587 "parseaut.yy" // lalr1.cc:847
    { (yylhs.value.num) = res.minus; }
#line 2579 "parseaut.cc" // lalr1.cc:847
    break;

  case 131:
#line 1591 "parseaut.yy" // lalr1.cc:847
    {
    (yylhs.value.mark) = 0U;
  }
#line 2587 "parseaut.cc" // lalr1.cc:847
    break;

  case 132:
#line 1595 "parseaut.yy" // lalr1.cc:847
    {
    if (res.states < 0 || res.cur_state >= (unsigned) res.states)
      break;
    if (res.accset > 0 && (yystack_[0].value.num) < (unsigned) res.accset)
      {
	(yylhs.value.mark) = (yystack_[2].value.mark);
	(yylhs.value.mark).set((yystack_[0].value.num) * 2 + (yystack_[1].value.num));
      }
    else
      {
	std::ostringstream o;
	if (res.accset > 0)
	  {
	    o << "acceptance pairs should be in the range [0.."
	      << res.accset - 1 << "]";
	  }
	else
	  {
	    o << "no acceptance pairs have been declared";
	  }
	error(yystack_[0].location, o.str());
      }
  }
#line 2615 "parseaut.cc" // lalr1.cc:847
    break;

  case 133:
#line 1619 "parseaut.yy" // lalr1.cc:847
    { (yylhs.value.mark) = (yystack_[0].value.mark); }
#line 2621 "parseaut.cc" // lalr1.cc:847
    break;

  case 135:
#line 1623 "parseaut.yy" // lalr1.cc:847
    {
    std::pair<map_t::iterator, bool> i =
      res.dest_map.emplace((yystack_[0].value.num), *res.cur_guard);
    if (!i.second)
      i.first->second |= *res.cur_guard;
    ++res.cur_guard;
  }
#line 2633 "parseaut.cc" // lalr1.cc:847
    break;

  case 138:
#line 1634 "parseaut.yy" // lalr1.cc:847
    {
    for (auto i: res.dest_map)
      res.h->aut->new_edge(res.cur_state, i.first, i.second, (yystack_[1].value.mark));
  }
#line 2642 "parseaut.cc" // lalr1.cc:847
    break;

  case 139:
#line 1644 "parseaut.yy" // lalr1.cc:847
    {
	 if (res.opts.want_kripke)
	   {
	     error(yylhs.location, "cannot read a Kripke structure out of a never claim.");
	     YYABORT;
	   }
	 res.namer = res.h->aut->create_namer<std::string>();
	 res.h->aut->set_buchi();
	 res.acc_style = State_Acc;
	 res.pos_acc_sets = res.h->aut->acc().all_sets();
       }
#line 2658 "parseaut.cc" // lalr1.cc:847
    break;

  case 140:
#line 1656 "parseaut.yy" // lalr1.cc:847
    {
	 // Add an accept_all state if needed.
	 if (res.accept_all_needed && !res.accept_all_seen)
	   {
	     unsigned n = res.namer->new_state("accept_all");
	     res.h->aut->new_acc_edge(n, n, bddtrue);
	   }
	 // If we aliased existing state, we have some unreachable
	 // states to remove.
	 if (res.aliased_states)
	   res.h->aut->purge_unreachable_states();
	 res.info_states.resize(res.h->aut->num_states());
	 // Pretend that we have declared all states.
	 for (auto& p: res.info_states)
	   p.declared = true;
         res.h->aut->register_aps_from_dict();
       }
#line 2680 "parseaut.cc" // lalr1.cc:847
    break;

  case 145:
#line 1681 "parseaut.yy" // lalr1.cc:847
    {
      auto r = res.labels.insert(std::make_pair(*(yystack_[1].value.str), yystack_[1].location));
      if (!r.second)
	{
	  error(yystack_[1].location, std::string("redefinition of ") + *(yystack_[1].value.str) + "...");
	  error(r.first->second, std::string("... ")  + *(yystack_[1].value.str)
		+ " previously defined here");
	}
      (yylhs.value.str) = (yystack_[1].value.str);
    }
#line 2695 "parseaut.cc" // lalr1.cc:847
    break;

  case 146:
#line 1693 "parseaut.yy" // lalr1.cc:847
    {
      unsigned n = res.namer->new_state(*(yystack_[0].value.str));
      if (res.start.empty())
	{
	  // The first state is initial.
	  res.start.emplace_back(yylhs.location, std::vector<unsigned>{n});
	}
      (yylhs.value.str) = (yystack_[0].value.str);
    }
#line 2709 "parseaut.cc" // lalr1.cc:847
    break;

  case 147:
#line 1703 "parseaut.yy" // lalr1.cc:847
    {
      res.aliased_states |=
	res.namer->alias_state(res.namer->get_state(*(yystack_[1].value.str)), *(yystack_[0].value.str));
      // Keep any identifier that starts with accept.
      if (strncmp("accept", (yystack_[1].value.str)->c_str(), 6))
        {
          delete (yystack_[1].value.str);
          (yylhs.value.str) = (yystack_[0].value.str);
        }
      else
        {
	  delete (yystack_[0].value.str);
	  (yylhs.value.str) = (yystack_[1].value.str);
        }
    }
#line 2729 "parseaut.cc" // lalr1.cc:847
    break;

  case 148:
#line 1721 "parseaut.yy" // lalr1.cc:847
    {
      (yylhs.value.list) = (yystack_[1].value.list);
    }
#line 2737 "parseaut.cc" // lalr1.cc:847
    break;

  case 149:
#line 1725 "parseaut.yy" // lalr1.cc:847
    {
      (yylhs.value.list) = (yystack_[1].value.list);
    }
#line 2745 "parseaut.cc" // lalr1.cc:847
    break;

  case 150:
#line 1731 "parseaut.yy" // lalr1.cc:847
    {
      if (*(yystack_[1].value.str) == "accept_all")
	res.accept_all_seen = true;

      auto acc = !strncmp("accept", (yystack_[1].value.str)->c_str(), 6) ?
	res.h->aut->acc().all_sets() : spot::acc_cond::mark_t(0U);
      res.namer->new_edge(*(yystack_[1].value.str), *(yystack_[1].value.str), bddtrue, acc);
      delete (yystack_[1].value.str);
    }
#line 2759 "parseaut.cc" // lalr1.cc:847
    break;

  case 151:
#line 1740 "parseaut.yy" // lalr1.cc:847
    { delete (yystack_[0].value.str); }
#line 2765 "parseaut.cc" // lalr1.cc:847
    break;

  case 152:
#line 1741 "parseaut.yy" // lalr1.cc:847
    { delete (yystack_[1].value.str); }
#line 2771 "parseaut.cc" // lalr1.cc:847
    break;

  case 153:
#line 1743 "parseaut.yy" // lalr1.cc:847
    {
      auto acc = !strncmp("accept", (yystack_[1].value.str)->c_str(), 6) ?
	res.h->aut->acc().all_sets() : spot::acc_cond::mark_t(0U);
      for (auto& p: *(yystack_[0].value.list))
	{
	  bdd c = bdd_from_int(p.first);
	  bdd_delref(p.first);
	  res.namer->new_edge(*(yystack_[1].value.str), *p.second, c, acc);
	  delete p.second;
	}
      delete (yystack_[1].value.str);
      delete (yystack_[0].value.list);
    }
#line 2789 "parseaut.cc" // lalr1.cc:847
    break;

  case 154:
#line 1758 "parseaut.yy" // lalr1.cc:847
    { (yylhs.value.list) = new std::list<pair>; }
#line 2795 "parseaut.cc" // lalr1.cc:847
    break;

  case 155:
#line 1760 "parseaut.yy" // lalr1.cc:847
    {
      if ((yystack_[0].value.p))
	{
	  (yystack_[1].value.list)->push_back(*(yystack_[0].value.p));
	  delete (yystack_[0].value.p);
	}
      (yylhs.value.list) = (yystack_[1].value.list);
    }
#line 2808 "parseaut.cc" // lalr1.cc:847
    break;

  case 158:
#line 1772 "parseaut.yy" // lalr1.cc:847
    {
       auto i = res.fcache.find(*(yystack_[0].value.str));
       if (i == res.fcache.end())
	 {
	   auto pf = spot::parse_infix_boolean(*(yystack_[0].value.str), *res.env, debug_level(),
					       true);
	   for (auto& j: pf.errors)
	     {
	       // Adjust the diagnostic to the current position.
	       spot::location here = yystack_[0].location;
	       here.end.line = here.begin.line + j.first.end.line - 1;
	       here.end.column = here.begin.column + j.first.end.column - 1;
	       here.begin.line += j.first.begin.line - 1;
	       here.begin.column += j.first.begin.column - 1;
	       res.h->errors.emplace_back(here, j.second);
	     }
           bdd cond = bddfalse;
	   if (pf.f)
	     cond = spot::formula_to_bdd(pf.f,
					 res.h->aut->get_dict(), res.h->aut);
	   (yylhs.value.b) = (res.fcache[*(yystack_[0].value.str)] = cond).id();
	 }
       else
	 {
	   (yylhs.value.b) = i->second.id();
	 }
       bdd_addref((yylhs.value.b));
       delete (yystack_[0].value.str);
     }
#line 2842 "parseaut.cc" // lalr1.cc:847
    break;

  case 159:
#line 1802 "parseaut.yy" // lalr1.cc:847
    {
       (yylhs.value.b) = 0;
     }
#line 2850 "parseaut.cc" // lalr1.cc:847
    break;

  case 160:
#line 1808 "parseaut.yy" // lalr1.cc:847
    {
      (yylhs.value.str) = nullptr;
    }
#line 2858 "parseaut.cc" // lalr1.cc:847
    break;

  case 161:
#line 1812 "parseaut.yy" // lalr1.cc:847
    {
      (yylhs.value.str) = (yystack_[0].value.str);
    }
#line 2866 "parseaut.cc" // lalr1.cc:847
    break;

  case 162:
#line 1816 "parseaut.yy" // lalr1.cc:847
    {
      delete (yystack_[0].value.str);
      (yylhs.value.str) = new std::string("accept_all");
      res.accept_all_needed = true;
    }
#line 2876 "parseaut.cc" // lalr1.cc:847
    break;

  case 163:
#line 1823 "parseaut.yy" // lalr1.cc:847
    {
      // If there is no destination, do ignore the transition.
      // This happens for instance with
      //   if
      //   :: false
      //   fi
      if (!(yystack_[0].value.str))
	{
	  (yylhs.value.p) = nullptr;
	}
      else
	{
	  (yylhs.value.p) = new pair((yystack_[1].value.b), (yystack_[0].value.str));
	  res.namer->new_state(*(yystack_[0].value.str));
	}
    }
#line 2897 "parseaut.cc" // lalr1.cc:847
    break;

  case 164:
#line 1842 "parseaut.yy" // lalr1.cc:847
    {
      (yylhs.value.p) = (yystack_[1].value.p);
    }
#line 2905 "parseaut.cc" // lalr1.cc:847
    break;

  case 165:
#line 1846 "parseaut.yy" // lalr1.cc:847
    {
      (yylhs.value.p) = (yystack_[0].value.p);
    }
#line 2913 "parseaut.cc" // lalr1.cc:847
    break;

  case 166:
#line 1855 "parseaut.yy" // lalr1.cc:847
    {
	auto& acc = res.h->aut->acc();
	unsigned num = acc.num_sets();
	res.h->aut->set_generalized_buchi(num);
	res.pos_acc_sets = acc.all_sets();
	assert(!res.states_map.empty());
	auto n = res.states_map.size();
	if (n != (unsigned) res.states)
	  {
	    std::ostringstream err;
	    err << res.states << " states have been declared, but "
		<< n << " different state numbers have been used";
	    error(yylhs.location, err.str());
	  }
	if (res.states_map.rbegin()->first > (unsigned) res.states)
	  {
	    // We have seen numbers larger that the total number of
	    // states in the automaton.  Usually this happens when the
	    // states are numbered from 1 instead of 0, but the LBTT
	    // documentation actually allow any number to be used.
	    // What we have done is to map all input state numbers 0
	    // <= .. < n to the digraph states with the same number,
	    // and any time we saw a number larger than n, we mapped
	    // it to a new state.  The correspondence is given by
	    // res.states_map.  Now we just need to remove the useless
	    // states we allocated.
	    std::vector<unsigned> rename(res.h->aut->num_states(), -1U);
	    unsigned s = 0;
	    for (auto& i: res.states_map)
	      rename[i.second] = s++;
	    assert(s == (unsigned) res.states);
	    for (auto& i: res.start)
	      i.second.front() = rename[i.second.front()];
	    res.h->aut->get_graph().defrag_states(std::move(rename), s);
	  }
	 res.info_states.resize(res.h->aut->num_states());
	 for (auto& s: res.info_states)
	   s.declared = true;
         res.h->aut->register_aps_from_dict();
      }
#line 2958 "parseaut.cc" // lalr1.cc:847
    break;

  case 167:
#line 1896 "parseaut.yy" // lalr1.cc:847
    {
        res.h->aut->set_generalized_buchi((yystack_[0].value.num));
	res.pos_acc_sets = res.h->aut->acc().all_sets();
      }
#line 2967 "parseaut.cc" // lalr1.cc:847
    break;

  case 168:
#line 1902 "parseaut.yy" // lalr1.cc:847
    {
		    if (res.opts.want_kripke)
		      {
			error(yylhs.location,
			      "cannot read a Kripke structure out of "
			      "an LBTT automaton");
			YYABORT;
		      }
		    res.states = (yystack_[0].value.num);
		    res.states_loc = yystack_[0].location;
		    res.h->aut->new_states((yystack_[0].value.num));
		  }
#line 2984 "parseaut.cc" // lalr1.cc:847
    break;

  case 169:
#line 1915 "parseaut.yy" // lalr1.cc:847
    {
	     res.acc_mapper = new spot::acc_mapper_int(res.h->aut, (yystack_[0].value.num));
	     res.acc_style = State_Acc;
	   }
#line 2993 "parseaut.cc" // lalr1.cc:847
    break;

  case 170:
#line 1920 "parseaut.yy" // lalr1.cc:847
    {
	     res.acc_mapper = new spot::acc_mapper_int(res.h->aut, (yystack_[0].value.num));
	     res.trans_acc_seen = true;
	   }
#line 3002 "parseaut.cc" // lalr1.cc:847
    break;

  case 174:
#line 1929 "parseaut.yy" // lalr1.cc:847
    {
	    if ((yystack_[2].value.num) >= (unsigned) res.states)
	      {
		auto p = res.states_map.emplace((yystack_[2].value.num), 0);
		if (p.second)
		  p.first->second = res.h->aut->new_state();
		res.cur_state = p.first->second;
	      }
	    else
	      {
		res.states_map.emplace((yystack_[2].value.num), (yystack_[2].value.num));
		res.cur_state = (yystack_[2].value.num);
	      }
	    if ((yystack_[1].value.num))
	      res.start.emplace_back(yystack_[2].location + yystack_[1].location,
                                     std::vector<unsigned>{res.cur_state});
	    res.acc_state = (yystack_[0].value.mark);
	  }
#line 3025 "parseaut.cc" // lalr1.cc:847
    break;

  case 175:
#line 1947 "parseaut.yy" // lalr1.cc:847
    { (yylhs.value.mark) = 0U; }
#line 3031 "parseaut.cc" // lalr1.cc:847
    break;

  case 176:
#line 1949 "parseaut.yy" // lalr1.cc:847
    {
	  (yylhs.value.mark)  = (yystack_[1].value.mark);
	  auto p = res.acc_mapper->lookup((yystack_[0].value.num));
	  if (p.first)
	    (yylhs.value.mark) |= p.second;
	  else
	    error(yystack_[0].location, "more acceptance sets used than declared");
	}
#line 3044 "parseaut.cc" // lalr1.cc:847
    break;

  case 177:
#line 1958 "parseaut.yy" // lalr1.cc:847
    {
	    auto pf = spot::parse_prefix_ltl(*(yystack_[0].value.str), *res.env);
	    if (!pf.f || !pf.errors.empty())
	      {
		std::string s = "failed to parse guard: ";
		s += *(yystack_[0].value.str);
		error(yylhs.location, s);
	      }
	    if (!pf.errors.empty())
	      for (auto& j: pf.errors)
		{
		  // Adjust the diagnostic to the current position.
		  spot::location here = yystack_[0].location;
		  here.end.line = here.begin.line + j.first.end.line - 1;
		  here.end.column = here.begin.column + j.first.end.column - 1;
		  here.begin.line += j.first.begin.line - 1;
		  here.begin.column += j.first.begin.column - 1;
		  res.h->errors.emplace_back(here, j.second);
		}
	    if (!pf.f)
	      {
		res.cur_label = bddtrue;
	      }
	    else
	      {
		if (!pf.f.is_boolean())
		  {
		    error(yylhs.location,
			  "non-Boolean transition label (replaced by true)");
		    res.cur_label = bddtrue;
		  }
		else
		  {
		    res.cur_label =
		      formula_to_bdd(pf.f, res.h->aut->get_dict(), res.h->aut);
		  }
	      }
	    delete (yystack_[0].value.str);
	  }
#line 3088 "parseaut.cc" // lalr1.cc:847
    break;

  case 179:
#line 1999 "parseaut.yy" // lalr1.cc:847
    {
		  unsigned dst = (yystack_[2].value.num);
		  if (dst >= (unsigned) res.states)
		    {
		      auto p = res.states_map.emplace(dst, 0);
		      if (p.second)
			p.first->second = res.h->aut->new_state();
		      dst = p.first->second;
		    }
		  else
		    {
		      res.states_map.emplace(dst, dst);
		    }
		  res.h->aut->new_edge(res.cur_state, dst,
				       res.cur_label,
				       res.acc_state | (yystack_[1].value.mark));
		}
#line 3110 "parseaut.cc" // lalr1.cc:847
    break;


#line 3114 "parseaut.cc" // lalr1.cc:847
            default:
              break;
            }
        }
      catch (const syntax_error& yyexc)
        {
          error (yyexc);
          YYERROR;
        }
      YY_SYMBOL_PRINT ("-> $$ =", yylhs);
      yypop_ (yylen);
      yylen = 0;
      YY_STACK_PRINT ();

      // Shift the result of the reduction.
      yypush_ (YY_NULLPTR, yylhs);
    }
    goto yynewstate;

  /*--------------------------------------.
  | yyerrlab -- here on detecting error.  |
  `--------------------------------------*/
  yyerrlab:
    // If not already recovering from an error, report this error.
    if (!yyerrstatus_)
      {
        ++yynerrs_;
        error (yyla.location, yysyntax_error_ (yystack_[0].state,
                                           yyempty ? yyempty_ : yyla.type_get ()));
      }


    yyerror_range[1].location = yyla.location;
    if (yyerrstatus_ == 3)
      {
        /* If just tried and failed to reuse lookahead token after an
           error, discard it.  */

        // Return failure if at end of input.
        if (yyla.type_get () == yyeof_)
          YYABORT;
        else if (!yyempty)
          {
            yy_destroy_ ("Error: discarding", yyla);
            yyempty = true;
          }
      }

    // Else will try to reuse lookahead token after shifting the error token.
    goto yyerrlab1;


  /*---------------------------------------------------.
  | yyerrorlab -- error raised explicitly by YYERROR.  |
  `---------------------------------------------------*/
  yyerrorlab:

    /* Pacify compilers like GCC when the user code never invokes
       YYERROR and the label yyerrorlab therefore never appears in user
       code.  */
    if (false)
      goto yyerrorlab;
    yyerror_range[1].location = yystack_[yylen - 1].location;
    /* Do not reclaim the symbols of the rule whose action triggered
       this YYERROR.  */
    yypop_ (yylen);
    yylen = 0;
    goto yyerrlab1;

  /*-------------------------------------------------------------.
  | yyerrlab1 -- common code for both syntax error and YYERROR.  |
  `-------------------------------------------------------------*/
  yyerrlab1:
    yyerrstatus_ = 3;   // Each real token shifted decrements this.
    {
      stack_symbol_type error_token;
      for (;;)
        {
          yyn = yypact_[yystack_[0].state];
          if (!yy_pact_value_is_default_ (yyn))
            {
              yyn += yyterror_;
              if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_)
                {
                  yyn = yytable_[yyn];
                  if (0 < yyn)
                    break;
                }
            }

          // Pop the current state because it cannot handle the error token.
          if (yystack_.size () == 1)
            YYABORT;

          yyerror_range[1].location = yystack_[0].location;
          yy_destroy_ ("Error: popping", yystack_[0]);
          yypop_ ();
          YY_STACK_PRINT ();
        }

      yyerror_range[2].location = yyla.location;
      YYLLOC_DEFAULT (error_token.location, yyerror_range, 2);

      // Shift the error token.
      error_token.state = yyn;
      yypush_ ("Shifting", error_token);
    }
    goto yynewstate;

    // Accept.
  yyacceptlab:
    yyresult = 0;
    goto yyreturn;

    // Abort.
  yyabortlab:
    yyresult = 1;
    goto yyreturn;

  yyreturn:
    if (!yyempty)
      yy_destroy_ ("Cleanup: discarding lookahead", yyla);

    /* Do not reclaim the symbols of the rule whose action triggered
       this YYABORT or YYACCEPT.  */
    yypop_ (yylen);
    while (1 < yystack_.size ())
      {
        yy_destroy_ ("Cleanup: popping", yystack_[0]);
        yypop_ ();
      }

    return yyresult;
  }
    catch (...)
      {
        YYCDEBUG << "Exception caught: cleaning lookahead and stack"
                 << std::endl;
        // Do not try to display the values of the reclaimed symbols,
        // as their printer might throw an exception.
        if (!yyempty)
          yy_destroy_ (YY_NULLPTR, yyla);

        while (1 < yystack_.size ())
          {
            yy_destroy_ (YY_NULLPTR, yystack_[0]);
            yypop_ ();
          }
        throw;
      }
  }

  void
  parser::error (const syntax_error& yyexc)
  {
    error (yyexc.location, yyexc.what());
  }

  // Generate an error message.
  std::string
  parser::yysyntax_error_ (state_type yystate, symbol_number_type yytoken) const
  {
    std::string yyres;
    // Number of reported tokens (one for the "unexpected", one per
    // "expected").
    size_t yycount = 0;
    // Its maximum.
    enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
    // Arguments of yyformat.
    char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];

    /* There are many possibilities here to consider:
       - If this state is a consistent state with a default action, then
         the only way this function was invoked is if the default action
         is an error action.  In that case, don't check for expected
         tokens because there are none.
       - The only way there can be no lookahead present (in yytoken) is
         if this state is a consistent state with a default action.
         Thus, detecting the absence of a lookahead is sufficient to
         determine that there is no unexpected or expected token to
         report.  In that case, just report a simple "syntax error".
       - Don't assume there isn't a lookahead just because this state is
         a consistent state with a default action.  There might have
         been a previous inconsistent state, consistent state with a
         non-default action, or user semantic action that manipulated
         yyla.  (However, yyla is currently not documented for users.)
       - Of course, the expected token list depends on states to have
         correct lookahead information, and it depends on the parser not
         to perform extra reductions after fetching a lookahead from the
         scanner and before detecting a syntax error.  Thus, state
         merging (from LALR or IELR) and default reductions corrupt the
         expected token list.  However, the list is correct for
         canonical LR with one exception: it will still contain any
         token that will not be accepted due to an error action in a
         later state.
    */
    if (yytoken != yyempty_)
      {
        yyarg[yycount++] = yytname_[yytoken];
        int yyn = yypact_[yystate];
        if (!yy_pact_value_is_default_ (yyn))
          {
            /* Start YYX at -YYN if negative to avoid negative indexes in
               YYCHECK.  In other words, skip the first -YYN actions for
               this state because they are default actions.  */
            int yyxbegin = yyn < 0 ? -yyn : 0;
            // Stay within bounds of both yycheck and yytname.
            int yychecklim = yylast_ - yyn + 1;
            int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
            for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
              if (yycheck_[yyx + yyn] == yyx && yyx != yyterror_
                  && !yy_table_value_is_error_ (yytable_[yyx + yyn]))
                {
                  if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
                    {
                      yycount = 1;
                      break;
                    }
                  else
                    yyarg[yycount++] = yytname_[yyx];
                }
          }
      }

    char const* yyformat = YY_NULLPTR;
    switch (yycount)
      {
#define YYCASE_(N, S)                         \
        case N:                               \
          yyformat = S;                       \
        break
        YYCASE_(0, YY_("syntax error"));
        YYCASE_(1, YY_("syntax error, unexpected %s"));
        YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
        YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
        YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
        YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
#undef YYCASE_
      }

    // Argument number.
    size_t yyi = 0;
    for (char const* yyp = yyformat; *yyp; ++yyp)
      if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount)
        {
          yyres += yytnamerr_ (yyarg[yyi++]);
          ++yyp;
        }
      else
        yyres += *yyp;
    return yyres;
  }


  const short int parser::yypact_ninf_ = -187;

  const signed char parser::yytable_ninf_ = -122;

  const short int
  parser::yypact_[] =
  {
      10,  -187,    44,    14,  -187,  -187,  -187,  -187,    18,  -187,
    -187,    13,  -187,  -187,   107,  -187,  -187,    73,  -187,  -187,
    -187,    22,    76,    39,  -187,  -187,   137,    57,    93,  -187,
    -187,  -187,    90,    86,  -187,  -187,  -187,   121,   145,   114,
    -187,   129,   138,   139,   142,   141,   146,   144,   147,  -187,
    -187,  -187,  -187,  -187,  -187,  -187,  -187,  -187,   148,  -187,
     102,   -32,  -187,    99,  -187,  -187,  -187,   110,  -187,    47,
    -187,  -187,   140,   143,  -187,    34,  -187,  -187,   151,  -187,
      98,  -187,  -187,    17,   149,    80,  -187,   117,  -187,  -187,
     121,  -187,  -187,  -187,  -187,  -187,  -187,     5,  -187,   138,
     150,  -187,    51,  -187,   138,  -187,    47,  -187,   116,    47,
    -187,   138,   138,  -187,  -187,  -187,    34,  -187,  -187,    34,
      66,    -4,    58,  -187,  -187,  -187,   155,   154,   157,  -187,
    -187,  -187,  -187,  -187,  -187,  -187,  -187,   158,   160,   161,
    -187,   127,  -187,  -187,    54,    61,   126,    62,   151,   138,
     138,     2,  -187,  -187,    51,   116,   116,  -187,  -187,  -187,
     138,  -187,  -187,  -187,  -187,   164,  -187,    71,    34,    34,
     131,  -187,  -187,    -4,    83,  -187,  -187,  -187,  -187,   165,
     166,    15,  -187,  -187,  -187,  -187,    -9,  -187,   125,  -187,
    -187,  -187,  -187,   116,  -187,  -187,   130,   -14,  -187,  -187,
    -187,  -187,  -187,  -187,  -187,   162,  -187,    -3,    75,    -4,
      -4,  -187,  -187,  -187,   169,  -187,   167,  -187,  -187,    82,
    -187,  -187,  -187,  -187,  -187,  -187,   170,   152,  -187,   163,
    -187,   151,  -187,  -187,  -187,  -187,   153,  -187,  -187,   159,
    -187,   168,  -187,  -187,    96,   174,     4,   112,  -187,  -187,
    -187,  -187,   175,  -187,   156,   181,   171,  -187,  -187,  -187,
    -187
  };

  const unsigned char
  parser::yydefact_[] =
  {
       0,     3,     0,     0,   119,   120,   139,   168,     0,     2,
       6,     0,    22,     9,     0,     7,     8,     0,   172,     4,
       5,     0,     0,     0,     1,    83,     0,     0,     0,   170,
     169,   167,     0,   171,    11,    17,    19,   141,     0,     0,
      40,     0,     0,     0,     0,     0,     0,     0,     0,    48,
      35,    37,    55,    27,    23,   118,   122,   166,     0,   178,
       0,     0,   146,   151,   142,    10,    87,    91,    84,   102,
      24,    81,    25,    26,    20,     0,    29,    44,    12,    33,
      34,    51,    53,    39,     0,     0,   175,   173,   145,   140,
     144,   150,   154,   154,   152,   147,   153,     0,    92,     0,
     110,    82,   100,    93,     0,    85,   103,   104,   100,    86,
     111,     0,     0,    41,    67,    66,     0,    64,    65,     0,
      28,     0,    31,    13,    32,    49,     0,    36,    38,    59,
      58,    57,    14,    15,    56,   136,   123,     0,     0,     0,
     127,   174,   175,   143,     0,     0,     0,     0,    12,     0,
       0,     0,   101,   114,   100,   100,   100,   106,   105,   115,
       0,   112,   113,    63,    62,    21,    68,     0,     0,     0,
       0,    78,    79,     0,    30,    47,    46,    45,    50,     0,
       0,     0,   125,   126,   124,   176,     0,   148,     0,   155,
     149,    90,    89,    98,    61,    60,     0,     0,   108,   109,
     107,   116,    43,    42,    71,    70,    69,     0,     0,     0,
       0,    52,    54,   137,     0,   117,     0,   177,   179,     0,
      99,    88,    95,    72,    94,    97,     0,     0,    75,    77,
      76,    12,   131,   134,   157,   159,     0,   156,   158,   160,
     165,     0,    73,   128,   133,   138,     0,     0,   163,    74,
     129,   130,     0,   135,     0,     0,     0,   132,   164,   161,
     162
  };

  const short int
  parser::yypgoto_[] =
  {
    -187,  -187,   198,  -187,  -148,    79,  -187,  -187,  -187,  -187,
     118,  -187,  -187,  -187,  -187,  -187,  -187,  -187,  -187,  -187,
    -187,  -187,  -187,  -187,  -187,  -187,   -96,  -186,  -131,  -187,
     -37,   -97,  -187,  -187,  -187,   135,  -187,    95,    12,  -187,
    -187,   -91,  -187,  -187,  -187,   100,   103,  -187,  -105,  -187,
    -187,  -187,  -187,  -187,  -187,  -187,  -187,  -187,  -187,  -187,
    -187,  -187,  -187,   172,  -187,  -187,   119,   120,  -187,  -187,
    -187,   -36,  -187,  -187,  -187,  -187,  -187,  -187,  -187,    69,
    -187,  -187
  };

  const short int
  parser::yydefgoto_[] =
  {
      -1,     8,     9,    10,   124,   134,    11,    36,    12,    22,
      53,   113,    26,    54,   121,    81,    82,   165,   203,   122,
      80,   127,   128,    83,   100,    72,   120,   225,   174,    38,
     101,   102,    39,    68,    69,   103,    99,   104,   152,   197,
     221,   153,   105,   106,   157,   107,   108,   109,   110,   162,
      13,    14,    84,    85,   216,   252,   244,   233,   245,   181,
      15,    23,    61,    62,    63,    96,    64,   144,   238,   239,
     248,   240,   189,    16,    17,    18,    32,    33,    59,   141,
     218,    87
  };

  const short int
  parser::yytable_[] =
  {
     193,   147,   148,   196,   161,    73,   146,   154,   223,   156,
       1,     2,   217,     3,   170,    21,   213,   159,    24,   223,
     166,   227,   234,   167,   -96,   114,    25,   115,    89,   226,
     214,    90,   -18,     4,     5,   129,    34,   116,   130,   131,
     241,   185,   208,     6,    19,   235,   224,     3,   237,   171,
     172,   173,   194,   195,   114,   201,   115,     7,   117,   118,
     119,   215,   -96,   198,   199,   200,   116,     4,     5,    71,
     132,   133,   205,   206,   163,   164,   175,     6,   229,   230,
     176,   136,   150,   243,   137,   138,    43,   117,   118,   119,
     187,     7,   168,   169,    35,    29,   168,   169,    37,   190,
     234,   168,   169,    55,    97,   209,   210,   139,    27,  -121,
     151,   132,   133,   209,   210,    66,   125,    60,   188,    56,
     192,    30,    31,   235,   236,   188,   237,   204,   -80,    67,
     126,   228,    28,    91,    92,    57,    93,    58,    40,    60,
      94,    41,    42,    43,    44,    45,    46,    47,    48,    49,
     -16,    70,   255,    50,    51,   256,    52,   250,   251,    65,
      71,    74,    75,    76,    77,    78,    88,    97,    79,   142,
      86,   111,   123,   178,   112,   151,   179,   185,   135,   180,
     182,   149,   183,   184,   191,   202,   207,   211,   212,   219,
     222,   231,   223,   169,   210,   232,   253,   257,   247,   259,
      20,   177,    98,   140,   160,   220,   158,   155,   242,   143,
     254,   186,   246,   145,     0,   260,   258,     0,     0,     0,
       0,     0,     0,     0,   249,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,    95
  };

  const short int
  parser::yycheck_[] =
  {
     148,    97,    99,     1,   109,    42,     1,   104,    22,   106,
       0,     1,    21,     3,    18,     1,     1,   108,     0,    22,
     116,   207,    18,   119,    22,    20,    13,    22,    60,    32,
      15,    63,    18,    23,    24,    18,    14,    32,    21,    22,
     226,    50,   173,    33,     0,    41,    60,     3,    44,    53,
      54,    55,   149,   150,    20,   160,    22,    47,    53,    54,
      55,    46,    60,   154,   155,   156,    32,    23,    24,    22,
      53,    54,   168,   169,   111,   112,    18,    33,   209,   210,
      22,     1,    31,   231,     4,     5,     6,    53,    54,    55,
      36,    47,    30,    31,    18,    22,    30,    31,    59,    38,
      18,    30,    31,    46,    57,    30,    31,    27,     1,    29,
      59,    53,    54,    30,    31,     1,    18,    18,    64,    26,
      58,    48,    49,    41,    42,    64,    44,    56,    14,    15,
      32,    56,    25,    34,    35,    45,    37,    51,     1,    18,
      41,     4,     5,     6,     7,     8,     9,    10,    11,    12,
      13,    22,    40,    16,    17,    43,    19,    61,    62,    14,
      22,    22,    20,    22,    18,    21,    64,    57,    21,    52,
      22,    31,    21,    18,    31,    59,    22,    50,    29,    22,
      22,    31,    22,    22,    58,    21,    55,    22,    22,    64,
      60,    22,    22,    31,    31,    28,    22,    22,    39,    18,
       2,   122,    67,    85,   109,   193,   106,   104,    56,    90,
     246,   142,    59,    93,    -1,    44,    60,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    56,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    63
  };

  const unsigned char
  parser::yystos_[] =
  {
       0,     0,     1,     3,    23,    24,    33,    47,    66,    67,
      68,    71,    73,   115,   116,   125,   138,   139,   140,     0,
      67,     1,    74,   126,     0,    13,    77,     1,    25,    22,
      48,    49,   141,   142,    14,    18,    72,    59,    94,    97,
       1,     4,     5,     6,     7,     8,     9,    10,    11,    12,
      16,    17,    19,    75,    78,    46,    26,    45,    51,   143,
      18,   127,   128,   129,   131,    14,     1,    15,    98,    99,
      22,    22,    90,    95,    22,    20,    22,    18,    21,    21,
      85,    80,    81,    88,   117,   118,    22,   146,    64,    60,
      63,    34,    35,    37,    41,   128,   130,    57,   100,   101,
      89,    95,    96,   100,   102,   107,   108,   110,   111,   112,
     113,    31,    31,    76,    20,    22,    32,    53,    54,    55,
      91,    79,    84,    21,    69,    18,    32,    86,    87,    18,
      21,    22,    53,    54,    70,    29,     1,     4,     5,    27,
      75,   144,    52,   131,   132,   132,     1,    91,    96,    31,
      31,    59,   103,   106,    96,   111,    96,   109,   110,   106,
     102,   113,   114,    95,    95,    82,    91,    91,    30,    31,
      18,    53,    54,    55,    93,    18,    22,    70,    18,    22,
      22,   124,    22,    22,    22,    50,   144,    36,    64,   137,
      38,    58,    58,    69,    96,    96,     1,   104,   106,   106,
     106,   113,    21,    83,    56,    91,    91,    55,    93,    30,
      31,    22,    22,     1,    15,    46,   119,    21,   145,    64,
     103,   105,    60,    22,    60,    92,    32,    92,    56,    93,
      93,    22,    28,   122,    18,    41,    42,    44,   133,   134,
     136,    92,    56,    69,   121,   123,    59,    39,   135,    56,
      61,    62,   120,    22,   136,    40,    43,    22,    60,    18,
      44
  };

  const unsigned char
  parser::yyr1_[] =
  {
       0,    65,    66,    66,    66,    66,    67,    67,    67,    67,
      68,    68,    69,    69,    70,    70,    71,    72,    74,    73,
      76,    75,    77,    77,    78,    78,    78,    78,    78,    79,
      78,    78,    78,    78,    78,    80,    78,    81,    78,    78,
      78,    82,    82,    83,    84,    84,    84,    84,    85,    85,
      85,    86,    86,    87,    87,    88,    88,    88,    88,    88,
      89,    89,    90,    90,    91,    91,    91,    91,    91,    91,
      91,    91,    92,    93,    93,    93,    93,    93,    93,    93,
      94,    95,    96,    97,    97,    98,    98,    98,    99,   100,
     100,   101,   101,   102,   103,   103,   104,   104,   105,   105,
     106,   106,   107,   107,   108,   108,   108,   109,   110,   110,
     111,   112,   112,   112,   113,   113,   114,   115,   115,   116,
     116,   117,   118,   118,   118,   118,   118,   118,   119,   120,
     120,   121,   121,   122,   123,   123,   124,   124,   124,   126,
     125,   127,   127,   127,   127,   128,   129,   129,   130,   130,
     131,   131,   131,   131,   132,   132,   133,   133,   134,   134,
     135,   135,   135,   136,   137,   137,   138,   138,   139,   140,
     140,   141,   142,   142,   143,   144,   144,   145,   146,   146
  };

  const unsigned char
  parser::yyr2_[] =
  {
       0,     2,     1,     1,     2,     2,     1,     1,     1,     1,
       4,     3,     0,     1,     1,     1,     2,     1,     0,     3,
       0,     4,     0,     2,     2,     2,     2,     1,     3,     0,
       4,     3,     3,     2,     2,     0,     3,     0,     3,     2,
       1,     0,     2,     1,     0,     2,     2,     2,     0,     2,
       3,     0,     3,     0,     3,     0,     2,     2,     2,     2,
       3,     3,     3,     3,     1,     1,     1,     1,     2,     3,
       3,     3,     1,     4,     5,     3,     3,     3,     1,     1,
       1,     1,     1,     0,     2,     2,     2,     1,     5,     3,
       3,     0,     1,     1,     3,     3,     0,     2,     0,     1,
       0,     1,     0,     1,     1,     2,     2,     2,     3,     3,
       1,     1,     2,     2,     2,     2,     2,     7,     3,     1,
       1,     1,     0,     2,     3,     3,     3,     2,     3,     1,
       1,     0,     3,     2,     0,     2,     0,     2,     4,     0,
       5,     0,     1,     3,     2,     2,     1,     2,     3,     3,
       2,     1,     2,     2,     0,     2,     1,     1,     1,     1,
       0,     3,     3,     2,     6,     3,     3,     2,     1,     2,
       2,     1,     0,     3,     3,     0,     2,     1,     0,     4
  };



  // YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
  // First, the terminals, then, starting at \a yyntokens_, nonterminals.
  const char*
  const parser::yytname_[] =
  {
  "\"end of file\"", "error", "$undefined", "\"HOA:\"", "\"States:\"",
  "\"Start:\"", "\"AP:\"", "\"Alias:\"", "\"Acceptance:\"",
  "\"acc-name:\"", "\"tool:\"", "\"name:\"", "\"properties:\"",
  "\"--BODY--\"", "\"--END--\"", "\"State:\"", "\"spot.highlight.edges:\"",
  "\"spot.highlight.states:\"", "\"identifier\"", "\"header name\"",
  "\"alias name\"", "\"string\"", "\"integer\"", "\"DRA\"", "\"DSA\"",
  "\"v2\"", "\"explicit\"", "\"Acceptance-Pairs:\"", "\"Acc-Sig:\"",
  "\"---\"", "'|'", "'&'", "'!'", "\"never\"", "\"skip\"", "\"if\"",
  "\"fi\"", "\"do\"", "\"od\"", "\"->\"", "\"goto\"", "\"false\"",
  "\"atomic\"", "\"assert\"", "\"boolean formula\"", "\"-1\"",
  "\"end of DSTAR automaton\"", "\"LBTT header\"", "\"state acceptance\"",
  "\"acceptance sets for empty automaton\"", "\"acceptance set\"",
  "\"state number\"", "\"destination number\"", "'t'", "'f'", "'('", "')'",
  "'['", "']'", "'{'", "'}'", "'+'", "'-'", "';'", "':'", "$accept", "aut",
  "aut-1", "hoa", "string_opt", "BOOLEAN", "header", "version",
  "format-version", "$@1", "aps", "$@2", "header-items", "header-item",
  "$@3", "$@4", "$@5", "ap-names", "ap-name", "acc-spec", "properties",
  "highlight-edges", "highlight-states", "header-spec", "state-conj-2",
  "init-state-conj-2", "label-expr", "acc-set", "acceptance-cond", "body",
  "state-num", "checked-state-num", "states", "state", "state-name",
  "label", "state-label_opt", "trans-label", "acc-sig", "acc-sets",
  "state-acc_opt", "trans-acc_opt", "labeled-edges", "some-labeled-edges",
  "incorrectly-unlabeled-edge", "labeled-edge", "state-conj-checked",
  "unlabeled-edges", "unlabeled-edge", "incorrectly-labeled-edge", "dstar",
  "dstar_type", "dstar_header", "dstar_sizes", "dstar_state_id", "sign",
  "dstar_accsigs", "dstar_state_accsig", "dstar_transitions",
  "dstar_states", "never", "$@6", "nc-states", "nc-one-ident",
  "nc-ident-list", "nc-transition-block", "nc-state", "nc-transitions",
  "nc-formula-or-ident", "nc-formula", "nc-opt-dest", "nc-src-dest",
  "nc-transition", "lbtt", "lbtt-header-states", "lbtt-header",
  "lbtt-body", "lbtt-states", "lbtt-state", "lbtt-acc", "lbtt-guard",
  "lbtt-transitions", YY_NULLPTR
  };

#if YYDEBUG
  const unsigned short int
  parser::yyrline_[] =
  {
       0,   320,   320,   321,   322,   323,   330,   331,   332,   333,
     339,   340,   342,   343,   344,   344,   346,   609,   616,   616,
     619,   618,   648,   648,   649,   667,   672,   676,   677,   689,
     688,   722,   726,   731,   735,   737,   736,   740,   739,   742,
     751,   753,   753,   754,   782,   782,   783,   784,   788,   788,
     810,   827,   827,   831,   831,   836,   836,   837,   838,   842,
     847,   851,   859,   863,   869,   873,   877,   891,   906,   912,
     919,   926,   932,   950,   978,   996,  1000,  1006,  1012,  1016,
    1025,  1052,  1062,  1105,  1105,  1138,  1139,  1163,  1172,  1197,
    1202,  1207,  1208,  1230,  1257,  1268,  1273,  1276,  1285,  1288,
    1300,  1303,  1317,  1317,  1318,  1319,  1320,  1321,  1339,  1350,
    1363,  1377,  1378,  1379,  1380,  1411,  1442,  1453,  1454,  1459,
    1471,  1484,  1507,  1508,  1509,  1527,  1540,  1544,  1546,  1586,
    1587,  1591,  1594,  1619,  1621,  1622,  1631,  1632,  1633,  1644,
    1643,  1674,  1676,  1677,  1678,  1680,  1692,  1702,  1720,  1724,
    1730,  1740,  1741,  1742,  1758,  1759,  1769,  1769,  1771,  1801,
    1808,  1811,  1815,  1822,  1841,  1845,  1854,  1895,  1901,  1914,
    1919,  1924,  1925,  1926,  1928,  1947,  1948,  1957,  1997,  1998
  };

  // Print the state stack on the debug stream.
  void
  parser::yystack_print_ ()
  {
    *yycdebug_ << "Stack now";
    for (stack_type::const_iterator
           i = yystack_.begin (),
           i_end = yystack_.end ();
         i != i_end; ++i)
      *yycdebug_ << ' ' << i->state;
    *yycdebug_ << std::endl;
  }

  // Report on the debug stream that the rule \a yyrule is going to be reduced.
  void
  parser::yy_reduce_print_ (int yyrule)
  {
    unsigned int yylno = yyrline_[yyrule];
    int yynrhs = yyr2_[yyrule];
    // Print the symbols being reduced, and their result.
    *yycdebug_ << "Reducing stack by rule " << yyrule - 1
               << " (line " << yylno << "):" << std::endl;
    // The symbols being reduced.
    for (int yyi = 0; yyi < yynrhs; yyi++)
      YY_SYMBOL_PRINT ("   $" << yyi + 1 << " =",
                       yystack_[(yynrhs) - (yyi + 1)]);
  }
#endif // YYDEBUG

  // Symbol number corresponding to token number t.
  inline
  parser::token_number_type
  parser::yytranslate_ (int t)
  {
    static
    const token_number_type
    translate_table[] =
    {
     0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,    32,     2,     2,     2,     2,    31,     2,
      55,    56,     2,    61,     2,    62,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,    64,    63,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,    57,     2,    58,     2,     2,     2,     2,     2,     2,
       2,     2,    54,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,    53,     2,     2,     2,
       2,     2,     2,    59,    30,    60,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
      25,    26,    27,    28,    29,    33,    34,    35,    36,    37,
      38,    39,    40,    41,    42,    43,    44,    45,    46,    47,
      48,    49,    50,    51,    52
    };
    const unsigned int user_token_number_max_ = 304;
    const token_number_type undef_token_ = 2;

    if (static_cast<int>(t) <= yyeof_)
      return yyeof_;
    else if (static_cast<unsigned int> (t) <= user_token_number_max_)
      return translate_table[t];
    else
      return undef_token_;
  }


} // hoayy
#line 3749 "parseaut.cc" // lalr1.cc:1155
#line 2017 "parseaut.yy" // lalr1.cc:1156


static void fill_guards(result_& r)
{
  unsigned nap = r.ap.size();

  int* vars = new int[nap];
  for (unsigned i = 0; i < nap; ++i)
    vars[i] = r.ap[nap - 1 - i];

  // build the 2^nap possible guards
  r.guards.reserve(1U << nap);
  for (size_t i = 0; i < (1U << nap); ++i)
    r.guards.push_back(bdd_ibuildcube(i, nap, vars));
  r.cur_guard = r.guards.begin();

  delete[] vars;
}

void
hoayy::parser::error(const location_type& location,
		     const std::string& message)
{
  res.h->errors.emplace_back(location, message);
}

static spot::acc_cond::acc_code
fix_acceptance_aux(spot::acc_cond& acc,
		   spot::acc_cond::acc_code in, unsigned pos,
		   spot::acc_cond::mark_t onlyneg,
		   spot::acc_cond::mark_t both,
		   unsigned base)
{
  auto& w = in[pos];
  switch (w.sub.op)
    {
    case spot::acc_cond::acc_op::And:
      {
	unsigned sub = pos - w.sub.size;
	--pos;
	auto c = fix_acceptance_aux(acc, in, pos, onlyneg, both, base);
	pos -= in[pos].sub.size;
	while (sub < pos)
	  {
	    --pos;
	    c &= fix_acceptance_aux(acc, in, pos, onlyneg, both, base);
	    pos -= in[pos].sub.size;
	  }
	return c;
      }
    case spot::acc_cond::acc_op::Or:
      {
	unsigned sub = pos - w.sub.size;
	--pos;
	auto c = fix_acceptance_aux(acc, in, pos, onlyneg, both, base);
	pos -= in[pos].sub.size;
	while (sub < pos)
	  {
	    --pos;
	    c |= fix_acceptance_aux(acc, in, pos, onlyneg, both, base);
	    pos -= in[pos].sub.size;
	  }
	return c;
      }
    case spot::acc_cond::acc_op::Inf:
      return acc.inf(in[pos - 1].mark);
    case spot::acc_cond::acc_op::Fin:
      return acc.fin(in[pos - 1].mark);
    case spot::acc_cond::acc_op::FinNeg:
      {
	auto m = in[pos - 1].mark;
	auto c = acc.fin(onlyneg & m);
	spot::acc_cond::mark_t tmp = 0U;
	for (auto i: both.sets())
	  {
	    if (m.has(i))
	      tmp.set(base);
	    ++base;
	  }
	if (tmp)
	  c |= acc.fin(tmp);
	return c;
      }
    case spot::acc_cond::acc_op::InfNeg:
      {
	auto m = in[pos - 1].mark;
	auto c = acc.inf(onlyneg & m);
	spot::acc_cond::mark_t tmp = 0U;
	for (auto i: both.sets())
	  {
	    if (m.has(i))
	      tmp.set(base);
	    ++base;
	  }
	if (tmp)
	  c &= acc.inf(tmp);
	return c;
      }
    }
  SPOT_UNREACHABLE();
  return {};
}

static void fix_acceptance(result_& r)
{
  if (r.opts.want_kripke)
    return;
  auto& acc = r.h->aut->acc();

  // If a set x appears only as Inf(!x), we can complement it so that
  // we work with Inf(x) instead.
  auto onlyneg = r.neg_acc_sets - r.pos_acc_sets;
  if (onlyneg)
    {
      for (auto& t: r.h->aut->edge_vector())
	t.acc ^= onlyneg;
    }

  // However if set x is used elsewhere, for instance in
  //   Inf(!x) & Inf(x)
  // complementing x would be wrong.  We need to create a
  // new set, y, that is the complement of x, and rewrite
  // this as Inf(y) & Inf(x).
  auto both = r.neg_acc_sets & r.pos_acc_sets;
  unsigned base = 0;
  if (both)
    {
      auto v = both.sets();
      auto vs = v.size();
      base = acc.add_sets(vs);
      for (auto& t: r.h->aut->edge_vector())
	if ((t.acc & both) != both)
	  for (unsigned i = 0; i < vs; ++i)
	    if (!t.acc.has(v[i]))
	      t.acc |= acc.mark(base + i);
    }

  if (onlyneg || both)
    {
      auto& acc = r.h->aut->acc();
      auto code = acc.get_acceptance();
      r.h->aut->set_acceptance(acc.num_sets(),
			       fix_acceptance_aux(acc, code, code.size() - 1,
						  onlyneg, both, base));
    }
}

// Spot only supports a single initial state.
//
// If the input file does not declare any initial state (this is valid
// in the HOA format) add one nonetheless.
//
// If the input file has multiple initial states we have to merge
// them.
//
//   1) In the non-alternating case, this is as simple as making a new
//   initial state using the union of all the outgoing transitions of
//   the declared initial states.  Note that if one of the original
//   initial state has no incoming transition, then we can use it as
//   initial state, avoiding the creation of a new state.
//
//   2) In the alternating case, the input may have several initial
//   states that are conjuncts.  We have to reduce the conjuncts to a
//   single state first.

static void fix_initial_state(result_& r)
{
  std::vector<std::vector<unsigned>> start;
  start.reserve(r.start.size());
  unsigned ssz = r.info_states.size();
  for (auto& p : r.start)
    {
      std::vector<unsigned> v;
      v.reserve(p.second.size());
      for (unsigned s: p.second)
        // Ignore initial states without declaration
        // (They have been diagnosed already.)
        if (s < ssz && r.info_states[s].declared)
          v.emplace_back(s);
      if (!v.empty())
        start.push_back(v);
    }

  // If no initial state has been declared, add one.
  if (start.empty())
    {
      if (r.opts.want_kripke)
	r.h->ks->set_init_state(r.h->ks->new_state(bddfalse));
      else
	r.h->aut->set_init_state(r.h->aut->new_state());
      return;
    }

  // Remove any duplicate initial state.
  std::sort(start.begin(), start.end());
  auto res = std::unique(start.begin(), start.end());
  start.resize(std::distance(start.begin(), res));

  assert(start.size() >= 1);
  if (start.size() == 1)
    {
      if (r.opts.want_kripke)
	r.h->ks->set_init_state(start.front().front());
      else
	r.h->aut->set_univ_init_state(start.front().begin(),
                                      start.front().end());
    }
  else
    {
      if (r.opts.want_kripke)
	{
	  r.h->errors.emplace_front(r.start.front().first,
				    "Kripke structure only support "
				    "a single initial state");
	  return;
	}
      // Multiple initial states.  We might need to add a fake one,
      // unless one of the actual initial state has no incoming edge.
      auto& aut = r.h->aut;
      std::vector<unsigned char> has_incoming(aut->num_states(), 0);
      for (auto& t: aut->edges())
        for (unsigned ud: aut->univ_dests(t))
          has_incoming[ud] = 1;

      bool found = false;
      unsigned init = 0;
      bool init_alternation = false;
      for (auto& pp: start)
        if (pp.size() == 1)
          {
            unsigned p = pp.front();
            if (!has_incoming[p])
              {
                init = p;
                found = true;
              }
          }
        else
          {
            init_alternation = true;
            break;
          }

      if (!found || init_alternation)
	// We do need a fake initial state
	init = aut->new_state();
      aut->set_init_state(init);

      // The non-alternating case is the easiest, we simply declare
      // the outgoing transitions of all "original initial states"
      // into the only one initial state.
      if (!init_alternation)
        {
          for (auto& pp: start)
            {
              unsigned p = pp.front();
              if (p != init)
                for (auto& t: aut->out(p))
                  aut->new_edge(init, t.dst, t.cond);
            }
        }
      else
        {
          // In the alternating case, we merge outgoing transition of
          // the universal destination of conjunct initial states.
          // (Note that this loop would work for the non-alternating
          // case too, but it is more expansive, so we avoid it if we
          // can.)
          spot::outedge_combiner combiner(aut);
          bdd comb_or = bddfalse;
          for (auto& pp: start)
            {
              bdd comb_and = bddtrue;
              for (unsigned d: pp)
                comb_and &= combiner(d);
              comb_or |= comb_and;
            }
          combiner.new_dests(init, comb_or);
        }
    }
}

static void fix_properties(result_& r)
{
  r.aut_or_ks->prop_deterministic(r.deterministic);
  //r.aut_or_ks->prop_complete(r.complete);
  if (r.acc_style == State_Acc ||
      (r.acc_style == Mixed_Acc && !r.trans_acc_seen))
    r.aut_or_ks->prop_state_acc(true);
}

static void check_version(const result_& r)
{
  if (r.h->type != spot::parsed_aut_type::HOA)
    return;
  auto& v = r.format_version;
  if (v.size() < 2 || v[0] != 'v' || v[1] < '1' || v[1] > '9')
    {
      r.h->errors.emplace_front(r.format_version_loc, "unknown HOA version");
      return;
    }
  const char* beg = &v[1];
  char* end = nullptr;
  long int vers = strtol(beg, &end, 10);
  if (vers != 1)
    {
      r.h->errors.emplace_front(r.format_version_loc,
				  "unsupported HOA version");
      return;
    }
  constexpr const char supported[] = "1";
  if (strverscmp(supported, beg) < 0 && !r.h->errors.empty())
    {
      std::ostringstream s;
      s << "we can read HOA v" << supported
	<< " but this file uses " << v << "; this might "
	<< "cause the following errors";
      r.h->errors.emplace_front(r.format_version_loc, s.str());
      return;
    }
}

namespace spot
{
  automaton_stream_parser::automaton_stream_parser(const std::string& name,
						   automaton_parser_options opt)
    : filename_(name), opts_(opt)
  {
    if (hoayyopen(name))
      throw std::runtime_error(std::string("Cannot open file ") + name);
  }

  automaton_stream_parser::automaton_stream_parser(int fd,
						   const std::string& name,
						   automaton_parser_options opt)
    : filename_(name), opts_(opt)
  {
    if (hoayyopen(fd))
      throw std::runtime_error(std::string("Cannot open file ") + name);
  }

  automaton_stream_parser::automaton_stream_parser(const char* data,
						   const std::string& filename,
						   automaton_parser_options opt)
    : filename_(filename), opts_(opt)
  {
    hoayystring(data);
  }

  automaton_stream_parser::~automaton_stream_parser()
  {
    hoayyclose();
  }

  static void raise_parse_error(const parsed_aut_ptr& pa)
  {
    if (pa->aborted)
      pa->errors.emplace_back(pa->loc, "parsing aborted");
    if (!pa->errors.empty())
      {
	std::ostringstream s;
	if (pa->format_errors(s))
	  throw parse_error(s.str());
      }
    // It is possible that pa->aut == nullptr if we reach the end of a
    // stream.  It is not necessarily an error.
  }

  parsed_aut_ptr
  automaton_stream_parser::parse(const bdd_dict_ptr& dict,
				 environment& env)
  {
  restart:
    result_ r;
    r.opts = opts_;
    r.h = std::make_shared<spot::parsed_aut>(filename_);
    if (opts_.want_kripke)
      r.aut_or_ks = r.h->ks = make_kripke_graph(dict);
    else
      r.aut_or_ks = r.h->aut = make_twa_graph(dict);
    r.env = &env;
    hoayy::parser parser(r, last_loc);
    static bool env_debug = !!getenv("SPOT_DEBUG_PARSER");
    parser.set_debug_level(opts_.debug || env_debug);
    hoayyreset();
    try
      {
	if (parser.parse())
	  {
	    r.h->aut = nullptr;
	    r.h->ks = nullptr;
	    r.aut_or_ks = nullptr;
	  }
      }
    catch (const spot::hoa_abort& e)
      {
	r.h->aborted = true;
	// Bison 3.0.2 lacks a += operator for locations.
	r.h->loc = r.h->loc + e.pos;
      }
    check_version(r);
    last_loc = r.h->loc;
    last_loc.step();
    if (r.h->aborted)
      {
	if (opts_.ignore_abort)
	  goto restart;
	return r.h;
      }
    if (opts_.raise_errors)
      raise_parse_error(r.h);
    if (!r.aut_or_ks)
      return r.h;
    if (r.state_names)
      r.aut_or_ks->set_named_prop("state-names", r.state_names);
    if (r.highlight_edges)
      r.aut_or_ks->set_named_prop("highlight-edges", r.highlight_edges);
    if (r.highlight_states)
      r.aut_or_ks->set_named_prop("highlight-states", r.highlight_states);
    fix_acceptance(r);
    fix_initial_state(r);
    fix_properties(r);
    if (r.h->aut && !r.h->aut->is_existential())
      r.h->aut->merge_univ_dests();
    return r.h;
  }

  parsed_aut_ptr
  parse_aut(const std::string& filename, const bdd_dict_ptr& dict,
	    environment& env, automaton_parser_options opts)
  {
    auto localopts = opts;
    localopts.raise_errors = false;
    parsed_aut_ptr pa;
    try
      {
	automaton_stream_parser p(filename, localopts);
	pa = p.parse(dict, env);
      }
    catch (std::runtime_error& e)
      {
	if (opts.raise_errors)
	  throw;
	parsed_aut_ptr pa = std::make_shared<spot::parsed_aut>(filename);
	pa->errors.emplace_back(spot::location(), e.what());
	return pa;
      }
    if (!pa->aut && !pa->ks && pa->errors.empty())
      pa->errors.emplace_back(pa->loc, "no automaton read (empty input?)");
    if (opts.raise_errors)
      raise_parse_error(pa);
    return pa;
  }


}

// Local Variables:
// mode: c++
// End:
