// 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 186 "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 273 "parseaut.yy" // lalr1.cc:599
        { delete (yysym.value.str); }
#line 372 "parseaut.cc" // lalr1.cc:599
        break;

      case 19: // "header name"

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

      case 20: // "alias name"

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

      case 21: // "string"

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

      case 44: // "boolean formula"

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

      case 69: // string_opt

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

      case 91: // label-expr

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

      case 93: // acceptance-cond

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

      case 127: // nc-one-ident

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

      case 128: // nc-ident-list

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

      case 129: // nc-transition-block

#line 277 "parseaut.yy" // lalr1.cc:599
        {
  for (std::list<pair>::iterator i = (yysym.value.list)->begin();
       i != (yysym.value.list)->end(); ++i)
  {
    bdd_delref(i->first);
    delete i->second;
  }
  delete (yysym.value.list);
  }
#line 450 "parseaut.cc" // lalr1.cc:599
        break;

      case 131: // nc-transitions

#line 277 "parseaut.yy" // lalr1.cc:599
        {
  for (std::list<pair>::iterator i = (yysym.value.list)->begin();
       i != (yysym.value.list)->end(); ++i)
  {
    bdd_delref(i->first);
    delete i->second;
  }
  delete (yysym.value.list);
  }
#line 465 "parseaut.cc" // lalr1.cc:599
        break;

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

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

      case 133: // nc-formula

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

      case 134: // nc-opt-dest

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

      case 135: // nc-src-dest

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

      case 136: // nc-transition

#line 275 "parseaut.yy" // lalr1.cc:599
        { bdd_delref((yysym.value.p)->first); delete (yysym.value.p)->second; delete (yysym.value.p); }
#line 500 "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 286 "parseaut.yy" // lalr1.cc:617
        {
    if ((yysym.value.str))
      debug_stream() << *(yysym.value.str);
    else
      debug_stream() << "\"\""; }
#line 531 "parseaut.cc" // lalr1.cc:617
        break;

      case 19: // "header name"

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

      case 20: // "alias name"

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

      case 21: // "string"

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

      case 22: // "integer"

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

      case 44: // "boolean formula"

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

      case 47: // "LBTT header"

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

      case 48: // "state acceptance"

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

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

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

      case 50: // "acceptance set"

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

      case 51: // "state number"

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

      case 52: // "destination number"

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

      case 69: // string_opt

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

      case 92: // acc-set

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

      case 95: // state-num

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

      case 96: // checked-state-num

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

      case 119: // sign

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

      case 127: // nc-one-ident

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

      case 128: // nc-ident-list

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

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

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

      case 134: // nc-opt-dest

#line 286 "parseaut.yy" // lalr1.cc:617
        {
    if ((yysym.value.str))
      debug_stream() << *(yysym.value.str);
    else
      debug_stream() << "\"\""; }
#line 707 "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 172 "parseaut.yy" // lalr1.cc:725
{ yyla.location = res.h->loc = initial_loc; }

#line 826 "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 294 "parseaut.yy" // lalr1.cc:847
    { res.h->loc = yylhs.location; YYACCEPT; }
#line 940 "parseaut.cc" // lalr1.cc:847
    break;

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

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

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

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

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

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

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

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

  case 16:
#line 321 "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)
		if ((unsigned) res.states <= p.second)
		  {
		    error(p.first,
			  "initial state number is larger than state count...");
		    error(res.states_loc, "... declared here.");
		    states = std::max(states, p.second + 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 structure 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 structure 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;
	      }
	  }
	  {
	    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 w = p.find("weak");
	      auto t = p.find("terminal");
	      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");
		    }
		}
	    }
	}
#line 1220 "parseaut.cc" // lalr1.cc:847
    break;

  case 17:
#line 546 "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 1230 "parseaut.cc" // lalr1.cc:847
    break;

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

  case 20:
#line 555 "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 1253 "parseaut.cc" // lalr1.cc:847
    break;

  case 21:
#line 568 "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 1273 "parseaut.cc" // lalr1.cc:847
    break;

  case 24:
#line 586 "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 1295 "parseaut.cc" // lalr1.cc:847
    break;

  case 25:
#line 604 "parseaut.yy" // lalr1.cc:847
    {
	       error(yystack_[0].location, "alternation is not yet supported");
	       YYABORT;
	     }
#line 1304 "parseaut.cc" // lalr1.cc:847
    break;

  case 26:
#line 609 "parseaut.yy" // lalr1.cc:847
    {
	       res.start.emplace_back(yylhs.location, (yystack_[0].value.num));
	     }
#line 1312 "parseaut.cc" // lalr1.cc:847
    break;

  case 28:
#line 614 "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 1327 "parseaut.cc" // lalr1.cc:847
    break;

  case 29:
#line 625 "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 1353 "parseaut.cc" // lalr1.cc:847
    break;

  case 30:
#line 647 "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 1369 "parseaut.cc" // lalr1.cc:847
    break;

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

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

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

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

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

  case 39:
#line 679 "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 1419 "parseaut.cc" // lalr1.cc:847
    break;

  case 43:
#line 691 "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 1450 "parseaut.cc" // lalr1.cc:847
    break;

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

  case 49:
#line 725 "parseaut.yy" // lalr1.cc:847
    {
		auto pos = res.props.emplace(*(yystack_[0].value.str), result_::prop_info{yystack_[0].location, true});
		if (!pos.first->second.val)
		  {
		    std::ostringstream out(std::ios_base::ate);
		    error(yystack_[0].location, 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 1476 "parseaut.cc" // lalr1.cc:847
    break;

  case 50:
#line 739 "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 1496 "parseaut.cc" // lalr1.cc:847
    break;

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

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

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

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

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

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

  case 66:
#line 792 "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 1562 "parseaut.cc" // lalr1.cc:847
    break;

  case 67:
#line 806 "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 1581 "parseaut.cc" // lalr1.cc:847
    break;

  case 68:
#line 821 "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 1591 "parseaut.cc" // lalr1.cc:847
    break;

  case 69:
#line 827 "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 1602 "parseaut.cc" // lalr1.cc:847
    break;

  case 70:
#line 834 "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 1613 "parseaut.cc" // lalr1.cc:847
    break;

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

  case 72:
#line 847 "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 1642 "parseaut.cc" // lalr1.cc:847
    break;

  case 73:
#line 865 "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 1674 "parseaut.cc" // lalr1.cc:847
    break;

  case 74:
#line 893 "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 1696 "parseaut.cc" // lalr1.cc:847
    break;

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

  case 76:
#line 915 "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 1714 "parseaut.cc" // lalr1.cc:847
    break;

  case 77:
#line 921 "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 1724 "parseaut.cc" // lalr1.cc:847
    break;

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

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

  case 80:
#line 940 "parseaut.yy" // lalr1.cc:847
    {
	for (auto& p: res.start)
	  if (p.second >= res.info_states.size()
	      || !res.info_states[p.second].declared)
	    {
	      error(p.first,
		    "initial state " + std::to_string(p.second) +
		    " has no definition");
	      // Pretend that the state is declared so we do not
	      // mention it in the next loop.
	      if (p.second < res.info_states.size())
		res.info_states[p.second].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 1774 "parseaut.cc" // lalr1.cc:847
    break;

  case 81:
#line 968 "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 1787 "parseaut.cc" // lalr1.cc:847
    break;

  case 82:
#line 978 "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 1833 "parseaut.cc" // lalr1.cc:847
    break;

  case 84:
#line 1021 "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 1870 "parseaut.cc" // lalr1.cc:847
    break;

  case 86:
#line 1055 "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 1898 "parseaut.cc" // lalr1.cc:847
    break;

  case 87:
#line 1079 "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 1909 "parseaut.cc" // lalr1.cc:847
    break;

  case 88:
#line 1088 "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 1938 "parseaut.cc" // lalr1.cc:847
    break;

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

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

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

  case 92:
#line 1124 "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 1988 "parseaut.cc" // lalr1.cc:847
    break;

  case 93:
#line 1146 "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 2018 "parseaut.cc" // lalr1.cc:847
    break;

  case 94:
#line 1173 "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 2033 "parseaut.cc" // lalr1.cc:847
    break;

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

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

  case 97:
#line 1192 "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 2060 "parseaut.cc" // lalr1.cc:847
    break;

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

  case 99:
#line 1204 "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 2083 "parseaut.cc" // lalr1.cc:847
    break;

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

  case 101:
#line 1219 "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 2107 "parseaut.cc" // lalr1.cc:847
    break;

  case 107:
#line 1237 "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 2129 "parseaut.cc" // lalr1.cc:847
    break;

  case 108:
#line 1255 "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 2144 "parseaut.cc" // lalr1.cc:847
    break;

  case 109:
#line 1266 "parseaut.yy" // lalr1.cc:847
    {
		error(yystack_[1].location, "alternation is not yet supported");
		YYABORT;
	      }
#line 2153 "parseaut.cc" // lalr1.cc:847
    break;

  case 113:
#line 1278 "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 2188 "parseaut.cc" // lalr1.cc:847
    break;

  case 114:
#line 1309 "parseaut.yy" // lalr1.cc:847
    {
		  error(yystack_[1].location, "alternation is not yet supported");
		  YYABORT;
		}
#line 2197 "parseaut.cc" // lalr1.cc:847
    break;

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

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

  case 118:
#line 1331 "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 2230 "parseaut.cc" // lalr1.cc:847
    break;

  case 119:
#line 1343 "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 2246 "parseaut.cc" // lalr1.cc:847
    break;

  case 120:
#line 1356 "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 2272 "parseaut.cc" // lalr1.cc:847
    break;

  case 123:
#line 1381 "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 2294 "parseaut.cc" // lalr1.cc:847
    break;

  case 124:
#line 1399 "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 2311 "parseaut.cc" // lalr1.cc:847
    break;

  case 125:
#line 1412 "parseaut.yy" // lalr1.cc:847
    {
    res.start.emplace_back(yystack_[0].location, (yystack_[0].value.num));
  }
#line 2319 "parseaut.cc" // lalr1.cc:847
    break;

  case 127:
#line 1418 "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 2362 "parseaut.cc" // lalr1.cc:847
    break;

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

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

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

  case 131:
#line 1466 "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 2410 "parseaut.cc" // lalr1.cc:847
    break;

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

  case 134:
#line 1494 "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 2428 "parseaut.cc" // lalr1.cc:847
    break;

  case 137:
#line 1505 "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 2437 "parseaut.cc" // lalr1.cc:847
    break;

  case 138:
#line 1515 "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 2453 "parseaut.cc" // lalr1.cc:847
    break;

  case 139:
#line 1527 "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 2475 "parseaut.cc" // lalr1.cc:847
    break;

  case 144:
#line 1552 "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 2490 "parseaut.cc" // lalr1.cc:847
    break;

  case 145:
#line 1564 "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, n);
	}
      (yylhs.value.str) = (yystack_[0].value.str);
    }
#line 2504 "parseaut.cc" // lalr1.cc:847
    break;

  case 146:
#line 1574 "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 2524 "parseaut.cc" // lalr1.cc:847
    break;

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

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

  case 149:
#line 1602 "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 2554 "parseaut.cc" // lalr1.cc:847
    break;

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

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

  case 152:
#line 1614 "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 2584 "parseaut.cc" // lalr1.cc:847
    break;

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

  case 154:
#line 1631 "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 2603 "parseaut.cc" // lalr1.cc:847
    break;

  case 157:
#line 1643 "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 2637 "parseaut.cc" // lalr1.cc:847
    break;

  case 158:
#line 1673 "parseaut.yy" // lalr1.cc:847
    {
       (yylhs.value.b) = 0;
     }
#line 2645 "parseaut.cc" // lalr1.cc:847
    break;

  case 159:
#line 1679 "parseaut.yy" // lalr1.cc:847
    {
      (yylhs.value.str) = nullptr;
    }
#line 2653 "parseaut.cc" // lalr1.cc:847
    break;

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

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

  case 162:
#line 1694 "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 2692 "parseaut.cc" // lalr1.cc:847
    break;

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

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

  case 165:
#line 1726 "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 = rename[i.second];
	    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 2753 "parseaut.cc" // lalr1.cc:847
    break;

  case 166:
#line 1767 "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 2762 "parseaut.cc" // lalr1.cc:847
    break;

  case 167:
#line 1773 "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 2779 "parseaut.cc" // lalr1.cc:847
    break;

  case 168:
#line 1786 "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 2788 "parseaut.cc" // lalr1.cc:847
    break;

  case 169:
#line 1791 "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 2797 "parseaut.cc" // lalr1.cc:847
    break;

  case 173:
#line 1800 "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, res.cur_state);
	    res.acc_state = (yystack_[0].value.mark);
	  }
#line 2819 "parseaut.cc" // lalr1.cc:847
    break;

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

  case 175:
#line 1819 "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 2838 "parseaut.cc" // lalr1.cc:847
    break;

  case 176:
#line 1828 "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 2882 "parseaut.cc" // lalr1.cc:847
    break;

  case 178:
#line 1869 "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 2904 "parseaut.cc" // lalr1.cc:847
    break;


#line 2908 "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_ = -164;

  const signed char parser::yytable_ninf_ = -121;

  const short int
  parser::yypact_[] =
  {
       7,  -164,    44,    15,  -164,  -164,  -164,  -164,    21,  -164,
    -164,    77,  -164,  -164,    28,  -164,  -164,    71,  -164,  -164,
    -164,    20,    85,    59,  -164,  -164,   132,    78,   106,  -164,
    -164,  -164,    89,   105,  -164,  -164,  -164,   139,   144,   145,
    -164,   140,   141,   142,   146,   143,   149,   147,   148,  -164,
    -164,  -164,  -164,  -164,  -164,  -164,  -164,  -164,   150,  -164,
      97,    42,  -164,    94,  -164,  -164,  -164,   113,  -164,    13,
    -164,  -164,   151,   152,  -164,    60,  -164,  -164,   153,  -164,
      76,  -164,  -164,    57,   155,    80,  -164,   119,  -164,  -164,
     139,  -164,  -164,  -164,  -164,  -164,  -164,     5,  -164,   141,
     -20,  -164,    58,  -164,   141,  -164,    13,  -164,    13,  -164,
     141,   141,  -164,  -164,  -164,    60,  -164,  -164,    60,    67,
      -3,    10,  -164,  -164,  -164,   157,   154,   156,  -164,  -164,
    -164,  -164,  -164,  -164,  -164,  -164,   158,   159,   163,  -164,
     123,  -164,  -164,    52,   -21,   121,    18,   153,   141,     1,
    -164,  -164,   141,  -164,   -20,    58,   118,  -164,  -164,   141,
    -164,  -164,  -164,  -164,   165,  -164,    65,    60,    60,   133,
    -164,  -164,    -3,   122,  -164,  -164,  -164,  -164,   167,   168,
      23,  -164,  -164,  -164,  -164,    -9,  -164,   127,  -164,  -164,
    -164,  -164,   118,  -164,   134,   -18,  -164,  -164,  -164,  -164,
    -164,  -164,  -164,  -164,   161,  -164,     4,    70,    -3,    -3,
    -164,  -164,  -164,   171,  -164,   169,  -164,  -164,    81,  -164,
    -164,  -164,  -164,  -164,  -164,   173,   131,  -164,   170,  -164,
     153,  -164,  -164,  -164,  -164,   137,  -164,  -164,   160,  -164,
     162,  -164,  -164,    93,   176,    86,   107,  -164,  -164,  -164,
    -164,   178,  -164,   164,   184,   166,  -164,  -164,  -164,  -164
  };

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

  const short int
  parser::yypgoto_[] =
  {
    -164,  -164,   201,  -164,  -147,    83,  -164,  -164,  -164,  -164,
     120,  -164,  -164,  -164,  -164,  -164,  -164,  -164,  -164,  -164,
    -164,  -164,  -164,  -164,   102,  -164,   -96,  -119,  -163,  -164,
     -37,   -86,  -164,  -164,  -164,   172,  -164,    99,    16,  -164,
    -164,   -99,  -164,  -164,  -164,   103,  -164,   -94,  -164,  -164,
    -164,  -164,  -164,  -164,  -164,  -164,  -164,  -164,  -164,  -164,
    -164,  -164,   174,  -164,  -164,   124,   126,  -164,  -164,  -164,
     -34,  -164,  -164,  -164,  -164,  -164,  -164,  -164,    72,  -164,
    -164
  };

  const short int
  parser::yydefgoto_[] =
  {
      -1,     8,     9,    10,   123,   133,    11,    36,    12,    22,
      53,   112,    26,    54,   120,    81,    82,   164,   202,   121,
      80,   126,   127,    83,   100,    72,   119,   224,   173,    38,
     101,   102,    39,    68,    69,   103,    99,   104,   150,   195,
     220,   151,   105,   106,   157,   107,   108,   109,   161,    13,
      14,    84,    85,   215,   251,   243,   232,   244,   180,    15,
      23,    61,    62,    63,    96,    64,   143,   237,   238,   247,
     239,   188,    16,    17,    18,    32,    33,    59,   140,   217,
      87
  };

  const short int
  parser::yytable_[] =
  {
     192,   146,   194,   153,   222,    73,   145,     1,     2,   207,
       3,   148,   216,   147,   160,   169,    21,   189,   155,   165,
     156,    24,   166,   -96,   212,   113,   222,   114,   174,    27,
       4,     5,   175,   -18,    34,    71,   225,   115,   213,   149,
       6,   184,   223,   187,    19,   228,   229,     3,   167,   168,
     170,   171,   172,    28,     7,   197,   198,   199,   116,   117,
     118,   -96,   193,   131,   132,   200,   196,     4,     5,   214,
      97,   204,   205,   162,   163,   128,   191,     6,   129,   130,
     113,   135,   114,   242,   136,   137,    43,   226,   186,   152,
      25,     7,   115,    29,   124,   167,   168,   167,   168,   233,
     208,   209,    89,    35,   233,    90,   240,   138,   125,  -120,
     131,   132,    60,   116,   117,   118,   187,   149,    37,    30,
      31,   203,   234,   235,    55,   236,   227,   234,    91,    92,
     236,    93,    56,    40,    57,    94,    41,    42,    43,    44,
      45,    46,    47,    48,    49,   -16,    66,   254,    50,    51,
     255,    52,   208,   209,   249,   250,    58,    60,    65,   -80,
      67,    88,    70,    71,    74,    76,    75,    77,    78,    79,
      97,   141,    86,   184,   122,   177,   178,   149,   179,   190,
     181,   182,   110,   111,   134,   183,   201,   241,   206,   210,
     211,   218,   168,   230,   221,   222,   245,   231,   252,   246,
     256,   209,   258,    20,   176,   139,   154,   159,   219,   158,
     259,   253,     0,   185,   142,     0,     0,     0,   248,   144,
       0,     0,     0,     0,   257,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,    95,     0,    98
  };

  const short int
  parser::yycheck_[] =
  {
     147,    97,     1,   102,    22,    42,     1,     0,     1,   172,
       3,    31,    21,    99,   108,    18,     1,    38,   104,   115,
     106,     0,   118,    22,     1,    20,    22,    22,    18,     1,
      23,    24,    22,    18,    14,    22,    32,    32,    15,    59,
      33,    50,    60,    64,     0,   208,   209,     3,    30,    31,
      53,    54,    55,    25,    47,   154,   155,   156,    53,    54,
      55,    60,   148,    53,    54,   159,   152,    23,    24,    46,
      57,   167,   168,   110,   111,    18,    58,    33,    21,    22,
      20,     1,    22,   230,     4,     5,     6,   206,    36,    31,
      13,    47,    32,    22,    18,    30,    31,    30,    31,    18,
      30,    31,    60,    18,    18,    63,   225,    27,    32,    29,
      53,    54,    18,    53,    54,    55,    64,    59,    59,    48,
      49,    56,    41,    42,    46,    44,    56,    41,    34,    35,
      44,    37,    26,     1,    45,    41,     4,     5,     6,     7,
       8,     9,    10,    11,    12,    13,     1,    40,    16,    17,
      43,    19,    30,    31,    61,    62,    51,    18,    14,    14,
      15,    64,    22,    22,    22,    22,    20,    18,    21,    21,
      57,    52,    22,    50,    21,    18,    22,    59,    22,    58,
      22,    22,    31,    31,    29,    22,    21,    56,    55,    22,
      22,    64,    31,    22,    60,    22,    59,    28,    22,    39,
      22,    31,    18,     2,   121,    85,   104,   108,   192,   106,
      44,   245,    -1,   141,    90,    -1,    -1,    -1,    56,    93,
      -1,    -1,    -1,    -1,    60,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    63,    -1,    67
  };

  const unsigned char
  parser::yystos_[] =
  {
       0,     0,     1,     3,    23,    24,    33,    47,    66,    67,
      68,    71,    73,   114,   115,   124,   137,   138,   139,     0,
      67,     1,    74,   125,     0,    13,    77,     1,    25,    22,
      48,    49,   140,   141,    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,   142,
      18,   126,   127,   128,   130,    14,     1,    15,    98,    99,
      22,    22,    90,    95,    22,    20,    22,    18,    21,    21,
      85,    80,    81,    88,   116,   117,    22,   145,    64,    60,
      63,    34,    35,    37,    41,   127,   129,    57,   100,   101,
      89,    95,    96,   100,   102,   107,   108,   110,   111,   112,
      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,
     143,    52,   130,   131,   131,     1,    91,    96,    31,    59,
     103,   106,    31,   106,    89,    96,    96,   109,   110,   102,
     112,   113,    95,    95,    82,    91,    91,    30,    31,    18,
      53,    54,    55,    93,    18,    22,    70,    18,    22,    22,
     123,    22,    22,    22,    50,   143,    36,    64,   136,    38,
      58,    58,    69,    96,     1,   104,    96,   106,   106,   106,
     112,    21,    83,    56,    91,    91,    55,    93,    30,    31,
      22,    22,     1,    15,    46,   118,    21,   144,    64,   103,
     105,    60,    22,    60,    92,    32,    92,    56,    93,    93,
      22,    28,   121,    18,    41,    42,    44,   132,   133,   135,
      92,    56,    69,   120,   122,    59,    39,   134,    56,    61,
      62,   119,    22,   135,    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,   111,   111,   112,   112,   113,   114,   114,   115,   115,
     116,   117,   117,   117,   117,   117,   117,   118,   119,   119,
     120,   120,   121,   122,   122,   123,   123,   123,   125,   124,
     126,   126,   126,   126,   127,   128,   128,   129,   129,   130,
     130,   130,   130,   131,   131,   132,   132,   133,   133,   134,
     134,   134,   135,   136,   136,   137,   137,   138,   139,   139,
     140,   141,   141,   142,   143,   143,   144,   145,   145
  };

  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,     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", "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,   294,   294,   295,   296,   297,   304,   305,   306,   307,
     313,   314,   316,   317,   318,   318,   320,   545,   552,   552,
     555,   554,   584,   584,   585,   603,   608,   612,   613,   625,
     624,   658,   662,   667,   671,   673,   672,   676,   675,   678,
     687,   689,   689,   690,   718,   718,   719,   720,   724,   724,
     738,   755,   755,   759,   759,   764,   764,   765,   766,   770,
     775,   776,   780,   781,   783,   787,   791,   805,   820,   826,
     833,   840,   846,   864,   892,   910,   914,   920,   926,   930,
     939,   967,   977,  1020,  1020,  1053,  1054,  1078,  1087,  1112,
    1117,  1122,  1123,  1145,  1172,  1183,  1188,  1191,  1200,  1203,
    1215,  1218,  1232,  1232,  1233,  1234,  1235,  1236,  1254,  1265,
    1274,  1275,  1276,  1277,  1308,  1313,  1324,  1325,  1330,  1342,
    1355,  1378,  1379,  1380,  1398,  1411,  1415,  1417,  1457,  1458,
    1462,  1465,  1490,  1492,  1493,  1502,  1503,  1504,  1515,  1514,
    1545,  1547,  1548,  1549,  1551,  1563,  1573,  1591,  1595,  1601,
    1611,  1612,  1613,  1629,  1630,  1640,  1640,  1642,  1672,  1679,
    1682,  1686,  1693,  1712,  1716,  1725,  1766,  1772,  1785,  1790,
    1795,  1796,  1797,  1799,  1817,  1818,  1827,  1867,  1868
  };

  // 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 3540 "parseaut.cc" // lalr1.cc:1155
#line 1887 "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.op)
    {
    case spot::acc_cond::acc_op::And:
      {
	unsigned sub = pos - w.size;
	--pos;
	auto c = fix_acceptance_aux(acc, in, pos, onlyneg, both, base);
	pos -= in[pos].size;
	while (sub < pos)
	  {
	    --pos;
	    c &= fix_acceptance_aux(acc, in, pos, onlyneg, both, base);
	    pos -= in[pos].size;
	  }
	return c;
      }
    case spot::acc_cond::acc_op::Or:
      {
	unsigned sub = pos - w.size;
	--pos;
	auto c = fix_acceptance_aux(acc, in, pos, onlyneg, both, base);
	pos -= in[pos].size;
	while (sub < pos)
	  {
	    --pos;
	    c |= fix_acceptance_aux(acc, in, pos, onlyneg, both, base);
	    pos -= in[pos].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));
    }
}

static void fix_initial_state(result_& r)
{
  std::vector<unsigned> start;
  start.reserve(r.start.size());
  for (auto& p : r.start)
    // Ignore initial states without declaration
    if (p.second < r.info_states.size()
	&& r.info_states[p.second].declared)
      start.push_back(p.second);

  if (start.empty())
    {
      // If no initial state has been declared, add one, because
      // Spot will not work without one.
      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());
      else
	r.h->aut->set_init_state(start.front());
    }
  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())
	has_incoming[t.dst] = 1;

      bool found = false;
      unsigned init = 0;
      for (auto p: start)
	if (!has_incoming[p])
	  {
	    init = p;
	    found = true;
	  }
      if (!found)
	// We do need a fake initial state
	init = aut->new_state();
      aut->set_init_state(init);
      for (auto p: start)
	if (p != init)
	  for (auto& t: aut->out(p))
	    aut->new_edge(init, t.dst, t.cond);
    }
}

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);
    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:
