help-bison
[Top][All Lists]
Advanced

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

Re: memory leak


From: Hans Aberg
Subject: Re: memory leak
Date: Tue, 2 May 2006 13:20:45 +0200

On 2 May 2006, at 09:48, Akim Demaille wrote:


Le 29 avr. 06 à 19:16, Hans Aberg a écrit :

You do not give much info about what is leaking, so it could just as well be in your actions. The Bison generated parser used to leak for various strings that had not been translated from the C- subset of C++ to say using std::string, but I am not sure about the matter nowadays.

Can you detail please?  For instance a pointer to the mailing
list archive referring to this.

I believe you use to say "read the @$#% code" or something. :-) Nevertheless, I only know about the stuff from my own C++ skeleton, unable to use later Bison. Then, after the "switch" statement of the generated parser, I have the stuff below. I have a vague memory that the C stuff that I translated into C++ used to leak. Specifically, I think it was the string I have named "message", which is of C++ type std::string, that in the C version was something that was not properly deallocated. Perhaps it has changed in later Bison versions.


state_stack_.erase(state_stack_.end() - rule_length_, state_stack_.end()); semantic_stack_.erase(semantic_stack_.end() - rule_length_, semantic_stack_.end());
#if YYLSP_NEEDED
location_stack_.erase(location_stack_.end() - rule_length_, location_stack_.end());
#endif

#if YYDEBUG
  if (do_debug_) {
    YYCDEBUG << "state stack now";
    for (state_stack::const_iterator i = state_stack_.begin();
              i != state_stack_.end(); ++i)
            YYCDEBUG << ' ' << *i;
    YYCDEBUG << std::endl;
  }
#endif

  semantic_stack_.push_back(yyval);
#if YYLSP_NEEDED
  location_stack_.push_back(yyloc);
#endif

  // Shift the result of the reduction.
  n_ = r1_[n_];
  state_ = pgoto_[n_ - ntokens_] + state_stack_.back();
if (state_ >= 0 && state_ <= last_ && check_[state_] == state_stack_.back())
    state_ = table_[state_];
  else
    state_ = defgoto_[n_ - ntokens_];
  goto yynewstate;

  // Report and recover from errors.  This is very incomplete.
yyerrlab:
  // If not already recovering from an error, report this error.
  if (!errstatus) {
    ++nerrs;
#if YYERROR_VERBOSE
    n_ = pact_[state_];
    if (pact_ninf_ < n_ && n_ < last_) {
            message = "parse error, unexpected ";
            message += name_[ilooka_];
            int count = 0;
            for (int x = (n_ < 0 ? -n_ : 0); x < ntokens_ + nnts_; ++x)
              if (check_[x + n_] == x && x != terror_)
                      ++count;
            if (count < 5) {
                    count = 0;
                    for (int x = (n_ < 0 ? -n_ : 0); x < ntokens_ + nnts_; ++x)
                      if (check_[x + n_] == x && x != terror_) {
                      message += (!count++) ? ", expecting " : " or ";
                      message += name_[x];
                    }
            }
          }
    else
#endif
            message = "parse error";
#if 1
    yyerror(message);
#else
    error_();
#endif
  }
  goto yyerrlab1;

  // Error raised explicitly by an action.
yyerrlab1:
  if (errstatus == 3) {
  /* If just tried and failed to reuse lookahead token after an
           error, discard it. */

      /* Return failure if at end of input.  */
    if (lookahead_ == eof_)
            goto yyabortlab;
    YYCDEBUG << "Discarding token " << lookahead_
            << " (" << name_[ilooka_] << ")." << std::endl;
    lookahead_ = empty_;
  }

  /* Else will try to reuse lookahead token after shifting the error
     token.  */

  errstatus = 3;

  for (;;) {
    n_ = pact_[state_];
    if (n_ != pact_ninf_) {
            n_ += terror_;
            if (0 <= n_ && n_ <= last_ && check_[n_] == terror_) {
              n_ = table_[n_];
              if (0 < n_)
                    break;
            }
          }

/* Pop the current state because it cannot handle the error token. */
    if (state_stack_.empty())
            goto yyabortlab;

#if YYDEBUG
    if (do_debug_) {
            if (stos_[state_] < ntokens_) {
              YYCDEBUG << "Error: popping token "
                      << token_number_[stos_[state_]]
                      << " (" << name_[stos_[state_]];
# ifdef YYPRINT
YYPRINT(stderr, token_number_[stos_[state_]], semantic_stack_.top());
# endif
              YYCDEBUG << ')' << std::endl;
            }
            else {
              YYCDEBUG << "Error: popping nonterminal ("
                      << name_[stos_[state_]] << ')' << std::endl;
            }
          }
#endif

    state_ = (state_stack_.pop_back(), state_stack_.back());
    semantic_stack_.pop_back();
#if YYLSP_NEEDED
    location_stack_.pop_back();
#endif

#if YYDEBUG
    if (do_debug_) {
            YYCDEBUG << "Error: state stack now";
            for (state_stack::const_iterator i = state_stack_.begin();
                i != state_stack_.end(); ++i)
              YYCDEBUG << ' ' << *i;
            YYCDEBUG << std::endl;
          }
#endif
  }

  if (n_ == final_)
    goto yyacceptlab;

  YYCDEBUG << "Shifting error token, ";

  semantic_stack_.push_back(lookahead_value_);
#if YYLSP_NEEDED
  location_stack_.push_back(lookahead_location_);
#endif

  state_ = n_;
  goto yynewstate;

  // Accept.
yyacceptlab:
  return 0;

  // Abort.
yyabortlab:
  return 1;





reply via email to

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