Alien-SmokeQt

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

generator/parser/rpp/test/t005.cpp
generator/parser/rpp/test/t006.cpp
generator/parser/rpp/test/t007.cpp
generator/parser/rpp/test/t008.cpp
generator/parser/rpp/test/t009.cpp
generator/parser/rpp/test/t010.cpp
generator/parser/rpp/test/t011.cpp
generator/parser/rxx_allocator.h
generator/parser/rxx.pri
generator/parser/safetycounter.h
generator/parser/simplecursor.h
generator/parser/stringhelpers.cpp
generator/parser/stringhelpers.h
generator/parser/symbol.h
generator/parser/tests/CMakeLists.txt
generator/parser/tests/testconfig.h.cmake
generator/parser/tests/test_generator.cpp
generator/parser/tests/test_parser.cpp
generator/parser/tests/test_pool.cpp
generator/parser/tests/test_pool.h
generator/parser/tokens.cpp

generator/parser/lexer.cpp  view on Meta::CPAN

  ///A nearly exact copy of rpp::pp_skip_comment_or_divop::operator()
  enum {
    MAYBE_BEGIN,
    BEGIN,
    MAYBE_END,
    END,
    IN_COMMENT,
    IN_CXX_COMMENT
  } state (MAYBE_BEGIN);

  while (cursor < endCursor && *cursor) {
    switch (state) {
      case MAYBE_BEGIN:
        if (*cursor != '/')
          return;

        state = BEGIN;
        break;

      case BEGIN:
        if (*cursor == '*')
          state = IN_COMMENT;
        else if (*cursor == '/')
          state = IN_CXX_COMMENT;
        else
          return;
        break;

      case IN_COMMENT:
        if( *cursor == '\n' ) {
          scan_newline();
          continue;
        }
        if (*cursor == '*')
          state = MAYBE_END;
        break;

      case IN_CXX_COMMENT:
        if (*cursor == '\n')
          return;
        break;

      case MAYBE_END:
        if (*cursor == '/')
          state = END;
        else if (*cursor != '*')
          state = IN_COMMENT;
        if( *cursor == '\n' ) {
          scan_newline();
          continue;
        }
        break;

      case END:
        return;
    }

    ++cursor;
  }
  return;
}

IndexedString Token::symbol() const {
  if(size == 1)
    return IndexedString::fromIndex(session->contents()[position]);
  else
    return IndexedString();
}

generator/parser/lexer.cpp  view on Meta::CPAN

  m_firstInLine = true;
  m_leaveSize = false;
  
  session->token_stream->resize(1024);
  (*session->token_stream)[0].kind = Token_EOF;
  (*session->token_stream)[0].session = session;
  (*session->token_stream)[0].position = 0;
  (*session->token_stream)[0].size = 0;
  index = 1;

  cursor.current = session->contents();
  endCursor = session->contents() + session->contentsVector().size();

  while (cursor < endCursor) {
    size_t previousIndex = index;
    
    if (index == session->token_stream->size())
      session->token_stream->resize(session->token_stream->size() * 2);

    Token *current_token = &(*session->token_stream)[index];
    current_token->session = session;
    current_token->position = cursor.offsetIn( session->contents() );
    current_token->size = 0;
    
    if(cursor.isChar()) {
      (this->*s_scan_table[((uchar)*cursor)])();
    }else{
      //The cursor represents an identifier
      scan_identifier_or_keyword();
    }
    
    if(!m_leaveSize)
      current_token->size = cursor.offsetIn( session->contents() ) - current_token->position;
    
    Q_ASSERT(m_leaveSize || (cursor.current == session->contents() + current_token->position + current_token->size));
    Q_ASSERT(current_token->position + current_token->size <= (uint)session->contentsVector().size());
    Q_ASSERT(previousIndex == index-1 || previousIndex == index); //Never parse more than 1 token, because that won't be initialized correctly

    m_leaveSize = false;
    
    if(previousIndex != index)
      m_firstInLine = false;
    
  }

    if (index == session->token_stream->size())
      session->token_stream->resize(session->token_stream->size() * 2);
  (*session->token_stream)[index].session = session;
  (*session->token_stream)[index].position = cursor.offsetIn(session->contents());
  (*session->token_stream)[index].size = 0;
  (*session->token_stream)[index].kind = Token_EOF;
}

void Lexer::initialize_scan_table()
{
  s_initialized = true;

  for (int i=0; i<256; ++i)
    {

generator/parser/lexer.cpp  view on Meta::CPAN

  s_scan_table[int('{')] = &Lexer::scan_left_brace;
  s_scan_table[int('|')] = &Lexer::scan_or;
  s_scan_table[int('}')] = &Lexer::scan_right_brace;
  s_scan_table[int('~')] = &Lexer::scan_tilde;

  s_scan_table[0] = &Lexer::scan_EOF;
}

void Lexer::scan_preprocessor()
{
  while (cursor != endCursor && *cursor && *cursor != '\n')
    ++cursor;

  if (*cursor != '\n')
    {
      Problem *p = createProblem();
      p->description = "expected end of line";
      control->reportProblem(p);
    }
}

void Lexer::scan_char_constant()
{
  //const char *begin = cursor;

  ++cursor;
  while (cursor != endCursor && *cursor && *cursor != '\'')
    {
       if (*cursor == '\n')
        {
          Problem *p = createProblem();
          p->description = "unexpected new line";
          control->reportProblem(p);
          break;
        }

      if (*cursor == '\\')
	++cursor;

      ++cursor;
    }

  if (*cursor != '\'')
    {
      Problem *p = createProblem();
      p->description = "expected '";
      control->reportProblem(p);
    }
  else
    {
      ++cursor;
    }

  //(*session->token_stream)[index].extra.symbol =
    //control->findOrInsertName((const char*) begin, cursor - begin);

  (*session->token_stream)[index++].kind = Token_char_literal;
}

void Lexer::scan_string_constant()
{
  //const char *begin = cursor;

  ++cursor;
  while (cursor != endCursor && *cursor && *cursor != '"')
    {
       if (*cursor == '\n')
        {
          Problem *p = createProblem();
          p->description = "unexpected new line";
          control->reportProblem(p);
          break;
        }

      if (*cursor == '\\')
	++cursor;

      ++cursor;
    }

  if (*cursor != '"')
    {
      Problem *p = createProblem();
      p->description = "expected \"";
      control->reportProblem(p);
    }
  else
    {
      ++cursor;
    }

  //(*session->token_stream)[index].extra.symbol =
    //control->findOrInsertName((const char*) begin, cursor - begin);

  (*session->token_stream)[index++].kind = Token_string_literal;
}

void Lexer::scan_newline()
{
  ++cursor;
  m_firstInLine = true;
}

void Lexer::scan_white_spaces()
{
  while (cursor != endCursor && isspace(*cursor))
    {
      if (*cursor == '\n')
	scan_newline();
      else
	++cursor;
    }
}

void Lexer::scan_identifier_or_literal()
{
  switch (*(cursor + 1))
    {
    case '\'':
      ++cursor;
      scan_char_constant();
      break;

    case '\"':
      ++cursor;
      scan_string_constant();
      break;

    default:
      scan_identifier_or_keyword();
      break;
    }
}

void Lexer::scan_identifier_or_keyword()
{
  if(!(cursor < endCursor))
    return;
  
  //We have to merge symbols tokenized separately, they may have been contracted using ##
  SpecialCursor nextCursor(cursor);
  ++nextCursor;
  
  while(nextCursor < endCursor && (!isCharacter(*(nextCursor.current)) || isLetterOrNumber(*nextCursor.current) || characterFromIndex(*nextCursor.current) == '_')) {
    //Fortunately this shouldn't happen too often, only when ## is used within the preprocessor
    IndexedString mergedSymbol(IndexedString::fromIndex(*(cursor.current)).byteArray() + IndexedString::fromIndex(*(nextCursor.current)).byteArray());
    
    (*cursor.current) = mergedSymbol.index();
    (*nextCursor.current) = 0;
    ++nextCursor;
  }
  
  uint bucket = (*cursor.current) % index_size;
  for(int a = 0; a < indicesForTokens[bucket].size(); ++a) {
    if(indicesForTokens[bucket][a].first == *cursor.current) {
      (*session->token_stream)[index++].kind = indicesForTokens[bucket][a].second;
      ++cursor;
      return;
    }
  }

  m_leaveSize = true; //Since we may have skipped input tokens while mergin, we have to make sure that the size stays 1(the merged tokens will be empty)
  (*session->token_stream)[index].size = 1;
  (*session->token_stream)[index++].kind = Token_identifier;
  
  cursor = nextCursor;
}

void Lexer::scan_int_constant()
{
  if (*cursor == '.' && !std::isdigit(*(cursor + 1)))
    {
      scan_dot();
      return;
    }

  //const char *begin = cursor;

  while (cursor != endCursor &&  (isalnum(*cursor) || *cursor == '.'))
    ++cursor;

  //(*session->token_stream)[index].extra.symbol =
    //control->findOrInsertName((const char*) begin, cursor - begin);

  (*session->token_stream)[index++].kind = Token_number_literal;
}

void Lexer::scan_not()
{
  /*
    '!'		::= not
    '!='		::= not_equal
  */

  ++cursor;

  if (*cursor == '=')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_not_eq;
    }
  else
    {
      (*session->token_stream)[index++].kind = '!';
    }
}

void Lexer::scan_remainder()
{
  /*
    '%'		::= remainder
    '%='		::= remainder_equal
  */

  ++cursor;

  if (*cursor == '=')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_assign;
    }
  else
    {
      (*session->token_stream)[index++].kind = '%';
    }
}

void Lexer::scan_and()
{
  /*
    '&&'		::= and_and
    '&'		::= and
    '&='		::= and_equal
  */

  ++cursor;
  if (*cursor == '=')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_assign;
    }
  else if (*cursor == '&')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_and;
    }
  else
    {
      (*session->token_stream)[index++].kind = '&';
    }
}

void Lexer::scan_left_paren()
{
  ++cursor;
  (*session->token_stream)[index++].kind = '(';
}

void Lexer::scan_right_paren()
{
  ++cursor;
  (*session->token_stream)[index++].kind = ')';
}

void Lexer::scan_star()
{
  /*
    '*'		::= star
    '*='		::= star_equal
  */

  ++cursor;

  if (*cursor == '=')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_assign;
    }
  else
    {
      (*session->token_stream)[index++].kind = '*';
    }
}

void Lexer::scan_plus()
{
  /*
    '+'		::= plus
    '++'		::= incr
    '+='		::= plus_equal
  */

  ++cursor;
  if (*cursor == '=')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_assign;
    }
  else if (*cursor == '+')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_incr;
    }
  else
    {
      (*session->token_stream)[index++].kind = '+';
    }
}

void Lexer::scan_comma()
{
  ++cursor;
  (*session->token_stream)[index++].kind = ',';
}

void Lexer::scan_minus()
{
  /*
    '-'		::= minus
    '--'		::= decr
    '-='		::= minus_equal
    '->'		::= left_arrow
  */

  ++cursor;
  if (*cursor == '=')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_assign;
    }
  else if (*cursor == '-')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_decr;
    }
  else if (*cursor == '>')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_arrow;
    }
  else
    {
      (*session->token_stream)[index++].kind = '-';
    }
}

void Lexer::scan_dot()
{
  /*
    '.'		::= dot
    '...'		::= ellipsis
  */

  ++cursor;
  if (*cursor == '.' && *(cursor + 1) == '.')
    {
      cursor += 2;
      (*session->token_stream)[index++].kind = Token_ellipsis;
    }
  else if (*cursor == '.' && *(cursor + 1) == '*')
    {
      cursor += 2;
      (*session->token_stream)[index++].kind = Token_ptrmem;
    }
  else
    (*session->token_stream)[index++].kind = '.';
}

void Lexer::scan_divide()
{
  /*
    '/'		::= divide
    '/='	::= divide_equal
  */

  ++cursor;

  if (*cursor == '=')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_assign;
    }
  else if( *cursor == '*' || *cursor == '/' )
    {
      ///It is a comment
      --cursor; //Move back to the '/'
      SpecialCursor commentBegin = cursor;
      skipComment();
      if( cursor != commentBegin ) {
        ///Store the comment
        if(!m_canMergeComment || (*session->token_stream)[index-1].kind != Token_comment) {

          //Only allow appending to comments that are behind a newline, because else they may belong to the item on their left side.
          //If index is 1, this comment is the first token, which should be the translation-unit comment. So do not merge following comments.
          if(m_firstInLine && index != 1) 
            m_canMergeComment = true;
          else
            m_canMergeComment = false;
          
          (*session->token_stream)[index++].kind = Token_comment;
          (*session->token_stream)[index-1].size = (size_t)(cursor - commentBegin);
          (*session->token_stream)[index-1].position = commentBegin.offsetIn( session->contents() );
          (*session->token_stream)[index-1].session = session;
        }else{
          //Merge with previous comment
          (*session->token_stream)[index-1].size = cursor.offsetIn(session->contents()) - (*session->token_stream)[index-1].position;
        }
      }
    }
  else
    {
      (*session->token_stream)[index++].kind = '/';
    }
}

void Lexer::scan_colon()
{
  ++cursor;
  if (*cursor == ':')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_scope;
    }
  else
    {
      (*session->token_stream)[index++].kind = ':';
    }
}

void Lexer::scan_semicolon()
{
  ++cursor;
  (*session->token_stream)[index++].kind = ';';
}

void Lexer::scan_less()
{
  /*
    '<'			::= less
    '<<'		::= left_shift
    '<<='		::= left_shift_equal
    '<='		::= less_equal
  */

  ++cursor;
  if (*cursor == '=')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_leq;
    }
  else if (*cursor == '<')
    {
      ++cursor;
      if (*cursor == '=')
	{
	  ++cursor;
	  (*session->token_stream)[index++].kind = Token_assign;
	}
      else
	{
	  (*session->token_stream)[index++].kind = Token_shift;
	}
    }
  else
    {
      (*session->token_stream)[index++].kind = '<';
    }
}

void Lexer::scan_equal()
{
  /*
    '='			::= equal
    '=='		::= equal_equal
  */
  ++cursor;

  if (*cursor == '=')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_eq;
    }
  else
    {
      (*session->token_stream)[index++].kind = '=';
    }
}

void Lexer::scan_greater()
{
  /*
    '>'			::= greater
    '>='		::= greater_equal
    '>>'		::= right_shift
    '>>='		::= right_shift_equal
  */

  ++cursor;
  if (*cursor == '=')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_geq;
    }
  else if (*cursor == '>')
    {
      ++cursor;
      if (*cursor == '=')
	{
	  ++cursor;
	  (*session->token_stream)[index++].kind = Token_assign;
	}
      else
	{
	  (*session->token_stream)[index++].kind = Token_shift;
	}
    }
  else
    {
      (*session->token_stream)[index++].kind = '>';
    }
}

void Lexer::scan_question()
{
  ++cursor;
  (*session->token_stream)[index++].kind = '?';
}

void Lexer::scan_left_bracket()
{
  ++cursor;
  (*session->token_stream)[index++].kind = '[';
}

void Lexer::scan_right_bracket()
{
  ++cursor;
  (*session->token_stream)[index++].kind = ']';
}

void Lexer::scan_xor()
{
  /*
    '^'			::= xor
    '^='		::= xor_equal
  */
  ++cursor;

  if (*cursor == '=')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_assign;
    }
  else
    {
      (*session->token_stream)[index++].kind = '^';
    }
}

void Lexer::scan_left_brace()
{
  ++cursor;
  (*session->token_stream)[index++].kind = '{';
}

void Lexer::scan_or()
{
  /*
    '|'			::= or
    '|='		::= or_equal
    '||'		::= or_or
  */
  ++cursor;
  if (*cursor == '=')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_assign;
    }
  else if (*cursor == '|')
    {
      ++cursor;
      (*session->token_stream)[index++].kind = Token_or;
    }
  else
    {
    (*session->token_stream)[index++].kind = '|';
  }
}

void Lexer::scan_right_brace()
{
  ++cursor;
  (*session->token_stream)[index++].kind = '}';
}

void Lexer::scan_tilde()
{
  ++cursor;
  (*session->token_stream)[index++].kind = '~';
}

void Lexer::scan_EOF()
{
  ++cursor;
  (*session->token_stream)[index++].kind = Token_EOF;
}

void Lexer::scan_invalid_input()
{
  Problem *p = createProblem();
  p->description = "invalid input: %1", IndexedString::fromIndex(*cursor.current).str();
  control->reportProblem(p);

  ++cursor;
}

Problem *Lexer::createProblem() const
{
  Q_ASSERT(index > 0);

  Problem *p = new Problem;

  p->source = Problem::Source_Lexer;
  p->file = session->url().str();

generator/parser/lexer.h  view on Meta::CPAN

  {
    //const NameSymbol *symbol;
    std::size_t right_brace;
  } extra;
};

/**Stream of tokens found by lexer.
Internally works like an array of @ref Token continuosly allocated.
All tokens are destructed when this stream is deleted.

The stream has a "cursor" which is simply an integer which defines
the offset (index) of the token currently "observed" from the beginning of
the stream.*/
class CPPPARSER_EXPORT TokenStream
{
private:
  TokenStream(const TokenStream &);
  void operator = (const TokenStream &);

public:
  /**Creates a token stream with the default size of 1024 tokens.*/

generator/parser/lexer.h  view on Meta::CPAN

    resize(size);
  }

  inline ~TokenStream()
  { ::free(tokens); }

  /**@return the size of the token stream.*/
  inline std::size_t size() const
  { return token_count; }

  /**@return the "cursor" - the offset (index) of the token
  currently "observed" from the beginning of the stream.*/
  inline std::size_t cursor() const
  { return index; }

  /**Sets the cursor to the position @p i.*/
  inline void rewind(int i)
  { index = i; }

  /**Resizes the token stream.*/
  void resize(std::size_t size)
  {
    Q_ASSERT(size > 0);
    tokens = (Token*) ::realloc(tokens, sizeof(Token) * size);
    token_count = size;
  }

  /**Updates the cursor position to point to the next token and returns
  the cursor.*/
  inline std::size_t nextToken()
  { return index++; }

  /**@return the kind of the next (LA) token in the stream.*/
  inline int lookAhead(std::size_t i = 0) const
  { return tokens[index + i].kind; }

  /**@return the kind of the current token in the stream.*/
  inline int kind(std::size_t i) const
  { return tokens[i].kind; }

generator/parser/lexer.h  view on Meta::CPAN

    
    SpecialCursor operator +(int offset) {
      SpecialCursor ret(*this);
      ret.current += offset;
      return ret;
    }
    
    uint* current;
  };
  
  SpecialCursor cursor;
  const uint* endCursor;
  std::size_t index;

  bool m_leaveSize; //Marks the current token that its size should not be automatically set
  bool m_canMergeComment; //Whether we may append new comments to the last encountered one
  bool m_firstInLine;   //Whether the next token is the first one in a line
  
  ///scan table contains pointers to the methods to scan for various token types
  static scan_fun_ptr s_scan_table[];
  static scan_fun_ptr s_scan_keyword_table[];

generator/parser/parser.cpp  view on Meta::CPAN


  _M_last_valid_token = position > 0 ? position-1 : position;

  while( _M_last_valid_token > 0 && session->token_stream->kind(_M_last_valid_token) == Token_comment )
    --_M_last_valid_token;
}

void Parser::advance( bool skipComment ) {
  size_t t = session->token_stream->lookAhead();
  if(  t != Token_comment )
    _M_last_valid_token = session->token_stream->cursor();

  session->token_stream->nextToken();

  if( session->token_stream->lookAhead() == Token_comment ) {
    if( skipComment ) {
      processComment();
      advance();
    }
  }
}

generator/parser/parser.cpp  view on Meta::CPAN

}

void Parser::preparseLineComments( int tokenNumber ) {
  const Token& token( (*session->token_stream)[tokenNumber] );
  SimpleCursor tokenPosition = SimpleCursor::invalid();

  for( int a = 0; a < 40; a++ ) {
      if( !session->token_stream->lookAhead(a) ) break;
      if( session->token_stream->lookAhead(a) == Token_comment ) {
        //Make sure the token's line is before the searched token's line
        const Token& commentToken( (*session->token_stream)[session->token_stream->cursor() + a] );

        if( !tokenPosition.isValid() ) //Get the token line. Only on-demand, because it's not cheap.
          tokenPosition = session->positionAt(token.position);

        SimpleCursor commentPosition = session->positionAt( commentToken.position );

        if( commentPosition.line < tokenPosition.line ) {
            continue;
        } else if( commentPosition.line == tokenPosition.line ) {
            processComment( a );

generator/parser/parser.cpp  view on Meta::CPAN

  }
}

int Parser::lineFromTokenNumber( size_t tokenNumber ) const {
  const Token& token( (*session->token_stream)[tokenNumber] );
  return session->positionAt( token.position ).line;
}


void Parser::processComment( int offset, int line ) {
  size_t tokenNumber = session->token_stream->cursor() + offset;

  if(_M_last_parsed_comment >= tokenNumber)
    return; //The comment was already parsed. May happen because of pre-parsing

  _M_last_parsed_comment = tokenNumber;

  const Token& commentToken( (*session->token_stream)[tokenNumber] );
  Q_ASSERT(commentToken.kind == Token_comment);
  if( line == -1 ) {
    SimpleCursor position = session->positionAt( commentToken.position );
    line = position.line;
  }

/*  kDebug() << "noticing comment" << commentToken.symbol();*/
  m_commentStore.addComment( Comment( session->token_stream->cursor() + offset, line ) );

}

void Parser::clearComment( ) {
  m_commentStore.clear();
}

TranslationUnitAST *Parser::parse(ParseSession* _session)
{
  clear();

generator/parser/parser.cpp  view on Meta::CPAN

    return None;
}

IndexedString declSpecString("__declspec");

bool Parser::parseWinDeclSpec(WinDeclSpecAST *&node)
{
  if (session->token_stream->lookAhead() != Token_identifier)
    return false;

  std::size_t start = session->token_stream->cursor();

  IndexedString name = session->token_stream->token(session->token_stream->cursor()).symbol();
  if (name != declSpecString)
    return false;
  std::size_t specifier = session->token_stream->cursor();

  advance();
  if (session->token_stream->lookAhead() != '(')
    return false;

  advance();
  if (session->token_stream->lookAhead() != Token_identifier)
    return false;
  std::size_t modifier = session->token_stream->cursor();

  advance();
  if (session->token_stream->lookAhead() != ')')
    return false;

  advance();

  node = CreateNode<WinDeclSpecAST>(session->mempool);
  node->specifier = specifier;
  node->modifier = modifier;

generator/parser/parser.cpp  view on Meta::CPAN

  err += '\'';
  
  if(token == '}' || token == '{')
    _M_hadMismatchingCompoundTokens = true;

  reportError(err);
}

void Parser::syntaxError()
{
  std::size_t cursor = session->token_stream->cursor();
  std::size_t kind = session->token_stream->lookAhead();

  if (m_syntaxErrorTokens.contains(cursor))
      return; // syntax error at this point has already been reported

  m_syntaxErrorTokens.insert(cursor);

  QString err;

  if (kind == Token_EOF)
    err += "Unexpected end of file";
  else
  {
    err += "Unexpected token ";
    err += '\'';
    err += token_name(kind);
    err += '\'';
  }

  reportError(err);
}

void Parser::reportPendingErrors()
{
  bool hold = holdErrors(false);

  std::size_t start = session->token_stream->cursor();
 while (m_pendingErrors.count() > 0)
 {
   PendingError error = m_pendingErrors.dequeue();
    session->token_stream->rewind(error.cursor);
    reportError(error.message);
 }
  rewind(start);

  holdErrors(hold);
}

void Parser::reportError(const QString& msg)
{
  if (!_M_hold_errors && _M_problem_count < _M_max_problem_count)
    {
      ++_M_problem_count;

      QString fileName;

      std::size_t tok = session->token_stream->cursor();
      SimpleCursor position = session->positionAt(session->token_stream->position(tok));

      Problem *p = new Problem;
      p->file = session->url().str();
      p->position = position;
      p->description = msg + " : " + QString::fromUtf8(lineFromContents(session->size(), session->contents(), p->position.line));
      p->source = Problem::Source_Parser;
      control->reportProblem(p);
    }
  else if (_M_hold_errors)
  {
    PendingError pending;
    pending.message = msg;
    pending.cursor = session->token_stream->cursor();
    m_pendingErrors.enqueue(pending);
  }
}

bool Parser::skipUntil(int token)
{
  clearComment();

  while (session->token_stream->lookAhead())
    {

generator/parser/parser.cpp  view on Meta::CPAN

        return true;

      advance();
    }

  return false;
}

bool Parser::parseName(NameAST*& node, ParseNameAcceptTemplate acceptTemplateId)
{
  std::size_t start = session->token_stream->cursor();

  WinDeclSpecAST *winDeclSpec = 0;
  parseWinDeclSpec(winDeclSpec);

  NameAST *ast = CreateNode<NameAST>(session->mempool);

  if (session->token_stream->lookAhead() == Token_scope)
    {
      ast->global = true;
      advance();
    }

  std::size_t idx = session->token_stream->cursor();

  while (true)
    {
      UnqualifiedNameAST *n = 0;
      if (!parseUnqualifiedName(n)) {
        return false;
      }

      if (session->token_stream->lookAhead() == Token_scope)
        {

generator/parser/parser.cpp  view on Meta::CPAN

            {
              rewind(n->start_token);
              parseUnqualifiedName(n, false);
            }

          ast->unqualified_name = n;
          break;
        }
    }

  if (idx == session->token_stream->cursor())
    return false;

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseTranslationUnit(TranslationUnitAST *&node)
{
  _M_problem_count = 0;
  _M_hadMismatchingCompoundTokens = false;

/*  kDebug() << "tokens:";
  for(size_t a = 0; a < session->token_stream->size(); ++a)
    kDebug() << token_name(session->token_stream->token(a).kind) << session->token_stream->token(a).symbolString();*/

  std::size_t start = session->token_stream->cursor();
  TranslationUnitAST *ast = CreateNode<TranslationUnitAST>(session->mempool);

  if( m_commentStore.hasComment() )
    addComment(ast, m_commentStore.takeFirstComment());

  while (session->token_stream->lookAhead())
    {
      std::size_t startDecl = session->token_stream->cursor();

      DeclarationAST *declaration = 0;
      if (parseDeclaration(declaration))
        {
          ast->declarations =
            snoc(ast->declarations, declaration, session->mempool);
        }
      else
        {
          // error recovery
          if (startDecl == session->token_stream->cursor())
            {
              // skip at least one token
              advance();
            }

          skipUntilDeclaration();
        }
    }

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;
  
  ast->hadMissingCompoundTokens = _M_hadMismatchingCompoundTokens;
  
  return true;
}

bool Parser::parseDeclaration(DeclarationAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  switch(session->token_stream->lookAhead())
    {
    case ';':
      advance();
      return true;

    case Token_extern:
      return parseLinkageSpecification(node);

generator/parser/parser.cpp  view on Meta::CPAN

            }
          }
      }
    } // end switch

    return false;
}

bool Parser::parseLinkageSpecification(DeclarationAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  CHECK(Token_extern);

  LinkageSpecificationAST *ast = CreateNode<LinkageSpecificationAST>(session->mempool);

  if (session->token_stream->lookAhead() == Token_string_literal)
    {
      ast->extern_type = session->token_stream->cursor();
      advance();
    }

  if (session->token_stream->lookAhead() == '{')
    {
      parseLinkageBody(ast->linkage_body);
    }
  else if (!parseDeclaration(ast->declaration))
    {
      reportError(("Declaration syntax error"));
    }

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseLinkageBody(LinkageBodyAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  CHECK('{');

  LinkageBodyAST *ast = CreateNode<LinkageBodyAST>(session->mempool);

  while (session->token_stream->lookAhead())
    {
      int tk = session->token_stream->lookAhead();

      if (tk == '}')
        break;

      std::size_t startDecl = session->token_stream->cursor();

      DeclarationAST *declaration = 0;
      if (parseDeclaration(declaration))
        {
          ast->declarations = snoc(ast->declarations, declaration, session->mempool);
        }
      else
        {
          // error recovery
          if (startDecl == session->token_stream->cursor())
            {
              // skip at least one token
              advance();
            }

          skipUntilDeclaration();
        }
    }

  clearComment();

generator/parser/parser.cpp  view on Meta::CPAN

    advance();

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseNamespace(DeclarationAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  CHECK(Token_namespace);

  std::size_t namespace_name = 0;
  if (session->token_stream->lookAhead() == Token_identifier)
    {
      namespace_name = session->token_stream->cursor();
      advance();
    }

  if (session->token_stream->lookAhead() == '=')
    {
      // namespace alias
      advance();

      NameAST *name = 0;
      if (parseName(name))

generator/parser/parser.cpp  view on Meta::CPAN

  parseLinkageBody(ast->linkage_body);

  UPDATE_POS(ast, start, ast->linkage_body->end_token);
  node = ast;

  return true;
}

bool Parser::parseUsing(DeclarationAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  CHECK(Token_using);

  if (session->token_stream->lookAhead() == Token_namespace)
    return parseUsingDirective(node);

  UsingAST *ast = CreateNode<UsingAST>(session->mempool);

  if (session->token_stream->lookAhead() == Token_typename)
    {
      ast->type_name = session->token_stream->cursor();
      advance();
    }

  if (!parseName(ast->name))
    return false;

  ADVANCE(';', ";");

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseUsingDirective(DeclarationAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  CHECK(Token_namespace);

  NameAST *name = 0;
  if (!parseName(name))
    {
      reportError(("Namespace name expected"));
      return false;
    }

generator/parser/parser.cpp  view on Meta::CPAN

  ast->name = name;
  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}


bool Parser::parseOperatorFunctionId(OperatorFunctionIdAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  CHECK(Token_operator);

  OperatorFunctionIdAST *ast = CreateNode<OperatorFunctionIdAST>(session->mempool);
  if (!parseOperator(ast->op))
    {
      ast->op = 0;

      // parse cast operator
      const ListNode<std::size_t> *cv = 0;

generator/parser/parser.cpp  view on Meta::CPAN

        }

      node = snoc(node, templArg, session->mempool);
    }

  return true;
}

bool Parser::parseTypedef(DeclarationAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  Comment mcomment = comment();

  CHECK(Token_typedef);

  TypeSpecifierAST *spec = 0;
  if (!parseTypeSpecifierOrClassSpec(spec))
    {
      reportError(("Need a type specifier to declare"));
      return false;

generator/parser/parser.cpp  view on Meta::CPAN

  preparseLineComments( ast->end_token-1 );

  if( m_commentStore.hasComment() )
    addComment( ast, m_commentStore.takeCommentInRange( lineFromTokenNumber( --ast->end_token ) ) );

  return true;
}

bool Parser::parseAsmDefinition(DeclarationAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  ADVANCE(Token_asm, "asm");

  const ListNode<std::size_t> *cv = 0;
  parseCvQualify(cv);

#if defined(__GNUC__)
#warning "implement me"
#endif
  skip('(', ')');

generator/parser/parser.cpp  view on Meta::CPAN

  AsmDefinitionAST *ast = CreateNode<AsmDefinitionAST>(session->mempool);
  ast->cv = cv;
  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseTemplateDeclaration(DeclarationAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  std::size_t exported = 0;
  if (session->token_stream->lookAhead() == Token_export)
    {
      exported = session->token_stream->cursor();
      advance();
    }

  CHECK(Token_template);

  const ListNode<TemplateParameterAST*> *params = 0;
  if (session->token_stream->lookAhead() == '<')
    {
      advance();
      parseTemplateParameterList(params);

generator/parser/parser.cpp  view on Meta::CPAN

  ast->declaration = declaration;

  UPDATE_POS(ast, start, declaration ? declaration->end_token : _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseOperator(OperatorAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  OperatorAST *ast = CreateNode<OperatorAST>(session->mempool);

  switch(session->token_stream->lookAhead())
    {
    case Token_new:
    case Token_delete:
      {
        ast->op = session->token_stream->cursor();
        advance();

        if (session->token_stream->lookAhead() == '['
            && session->token_stream->lookAhead(1) == ']')
          {
            ast->open = session->token_stream->cursor();
            advance();

            ast->close = session->token_stream->cursor();
            advance();
          }
      }
      break;

    case '+':
    case '-':
    case '*':
    case '/':
    case '%':

generator/parser/parser.cpp  view on Meta::CPAN

    case Token_not:
    case Token_not_eq:
    case Token_leq:
    case Token_geq:
    case Token_and:
    case Token_or:
    case Token_incr:
    case Token_decr:
    case Token_ptrmem:
    case Token_arrow:
      ast->op = session->token_stream->cursor();
      advance();
      break;

    default:
      if (session->token_stream->lookAhead() == '('
          && session->token_stream->lookAhead(1) == ')')
        {
          ast->op = ast->open = session->token_stream->cursor();
          advance();
          ast->close = session->token_stream->cursor();
          advance();
        }
      else if (session->token_stream->lookAhead() == '['
               && session->token_stream->lookAhead(1) == ']')
        {
          ast->op = ast->open = session->token_stream->cursor();
          advance();
          ast->close = session->token_stream->cursor();
          advance();
        }
      else
        {
          return false;
        }
    }

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseCvQualify(const ListNode<std::size_t> *&node)
{
  std::size_t start = session->token_stream->cursor();

  int tk;
  while (0 != (tk = session->token_stream->lookAhead())
         && (tk == Token_const || tk == Token_volatile))
    {
      node = snoc(node, session->token_stream->cursor(), session->mempool);
      advance();
    }

  return start != session->token_stream->cursor();
}

bool Parser::parseSimpleTypeSpecifier(TypeSpecifierAST *&node,
                                      bool onlyIntegral)
{
  std::size_t start = session->token_stream->cursor();
  bool isIntegral = false;
  bool done = false;

  const ListNode<std::size_t> *integrals = 0;

  while (!done)
    {
      switch(session->token_stream->lookAhead())
        {
        case Token_char:

generator/parser/parser.cpp  view on Meta::CPAN

        case Token_wchar_t:
        case Token_bool:
        case Token_short:
        case Token_int:
        case Token_long:
        case Token_signed:
        case Token_unsigned:
        case Token_float:
        case Token_double:
        case Token_void:
          integrals = snoc(integrals, session->token_stream->cursor(), session->mempool);
          isIntegral = true;
          advance();
          break;

        default:
          done = true;
        }
    }

  SimpleTypeSpecifierAST *ast = CreateNode<SimpleTypeSpecifierAST>(session->mempool);

  if (isIntegral)
    {
      ast->integrals = integrals;
    }
  else if (session->token_stream->lookAhead() == Token___typeof)
    {
      ast->type_of = session->token_stream->cursor();
      advance();

      if (session->token_stream->lookAhead() == '(')
        {
          advance();

          std::size_t saved = session->token_stream->cursor();
          parseTypeId(ast->type_id);
          if (session->token_stream->lookAhead() != ')')
            {
              ast->type_id = 0;
              rewind(saved);
              parseUnaryExpression(ast->expression);
            }
          ADVANCE(')', ")");
        }
      else

generator/parser/parser.cpp  view on Meta::CPAN

bool Parser::parsePtrOperator(PtrOperatorAST *&node)
{
  int tk = session->token_stream->lookAhead();

  if (tk != '&' && tk != '*'
      && tk != Token_scope && tk != Token_identifier)
    {
      return false;
    }

  std::size_t start = session->token_stream->cursor();

  PtrOperatorAST *ast = CreateNode<PtrOperatorAST>(session->mempool);
  switch (session->token_stream->lookAhead())
    {
    case '&':
    case '*':
      ast->op = session->token_stream->cursor();
      advance();
      break;

    case Token_scope:
    case Token_identifier:
      {
        if (!parsePtrToMember(ast->mem_ptr))
          {
            rewind(start);
            return false;

generator/parser/parser.cpp  view on Meta::CPAN

  parseCvQualify(ast->cv);

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseTemplateArgument(TemplateArgumentAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  TypeIdAST *typeId = 0;
  ExpressionAST *expr = 0;

  if (!parseTypeId(typeId) || (session->token_stream->lookAhead() != ','
                               && session->token_stream->lookAhead() != '>' && session->token_stream->lookAhead() != ')'))
    {
      rewind(start);

      if (!parseLogicalOrExpression(expr, true))

generator/parser/parser.cpp  view on Meta::CPAN

  ast->expression = expr;

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseTypeSpecifier(TypeSpecifierAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  const ListNode<std::size_t> *cv = 0;
  parseCvQualify(cv);
  
  TypeSpecifierAST *ast = 0;
  if (!parseElaboratedTypeSpecifier(ast) && !parseSimpleTypeSpecifier(ast))
    {
      rewind(start);
      return false;
    }

generator/parser/parser.cpp  view on Meta::CPAN

  ast->cv = cv;
  UPDATE_POS(ast, start, _M_last_valid_token+1);
  
  node = ast;

  return true;
}

bool Parser::parseDeclarator(DeclaratorAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  DeclaratorAST *ast = CreateNode<DeclaratorAST>(session->mempool);
  DeclaratorAST *decl = 0;
  NameAST *declId = 0;

  PtrOperatorAST *ptrOp = 0;
  while (parsePtrOperator(ptrOp))
    {
      ast->ptr_ops = snoc(ast->ptr_ops, ptrOp, session->mempool);
    }

generator/parser/parser.cpp  view on Meta::CPAN


    int tok = session->token_stream->lookAhead();
    if (ast->sub_declarator
        && !(isVector || tok == '(' || tok == ','
             || tok == ';' || tok == '='))
      {
        rewind(start);
        return false;
      }

    std::size_t index = session->token_stream->cursor();
    if (session->token_stream->lookAhead() == '(')
      {
        advance();
        ///@todo Sometimes something like (test()) is parsed as a parameter declaration clause, although it cannot be one.
        ParameterDeclarationClauseAST *params = 0;
        if (!parseParameterDeclarationClause(params))
          {
            rewind(index);
            goto update_pos;
          }

generator/parser/parser.cpp  view on Meta::CPAN


 update_pos:
  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseAbstractDeclarator(DeclaratorAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  DeclaratorAST *ast = CreateNode<DeclaratorAST>(session->mempool);
  DeclaratorAST *decl = 0;

  PtrOperatorAST *ptrOp = 0;
  while (parsePtrOperator(ptrOp))
    {
      ast->ptr_ops = snoc(ast->ptr_ops, ptrOp, session->mempool);
    }

  int index = session->token_stream->cursor();
  if (session->token_stream->lookAhead() == '(')
    {
      advance();

      if (!parseAbstractDeclarator(decl))
        {
          rewind(index);
          goto label1;
        }

generator/parser/parser.cpp  view on Meta::CPAN


    int tok = session->token_stream->lookAhead();
    if (ast->sub_declarator
        && !(isVector || tok == '(' || tok == ','
             || tok == ';' || tok == '='))
      {
        rewind(start);
        return false;
      }

    int index = session->token_stream->cursor();
    if (session->token_stream->lookAhead() == '(')
      {
        advance();

        ParameterDeclarationClauseAST *params = 0;
        if (!parseParameterDeclarationClause(params))
          {
            rewind(index);
            goto update_pos;
          }

generator/parser/parser.cpp  view on Meta::CPAN

          }

        advance();  // skip ')'

        parseCvQualify(ast->fun_cv);
        parseExceptionSpecification(ast->exception_spec);
      }
  }

 update_pos:
  if (session->token_stream->cursor() == start)
    return false;

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseEnumSpecifier(TypeSpecifierAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  CHECK(Token_enum);

  NameAST *name = 0;
  parseName(name);

  if (session->token_stream->lookAhead() != '{')
    {
      rewind(start);
      return false;

generator/parser/parser.cpp  view on Meta::CPAN

        {
          node = snoc(node, param, session->mempool);
        }
    }

  return true;
}

bool Parser::parseTemplateParameter(TemplateParameterAST *&node)
{
  std::size_t start = session->token_stream->cursor();
  TemplateParameterAST *ast = CreateNode<TemplateParameterAST>(session->mempool);

  int tk = session->token_stream->lookAhead();

  if ((tk == Token_class || tk == Token_typename || tk == Token_template)
      && parseTypeParameter(ast->type_parameter))
    {
      // nothing to do
    }
  else if (!parseParameterDeclaration(ast->parameter_declaration))
    return false;

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseTypeParameter(TypeParameterAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  TypeParameterAST *ast = CreateNode<TypeParameterAST>(session->mempool);
  ast->type = start;

  switch(session->token_stream->lookAhead())
    {
    case Token_class:
    case Token_typename:
      {
        advance(); // skip class

generator/parser/parser.cpp  view on Meta::CPAN

    } // end switch


  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;
  return true;
}

bool Parser::parseStorageClassSpecifier(const ListNode<std::size_t> *&node)
{
  std::size_t start = session->token_stream->cursor();

  int tk;
  while (0 != (tk = session->token_stream->lookAhead())
         && (tk == Token_friend || tk == Token_auto
             || tk == Token_register || tk == Token_static
             || tk == Token_extern || tk == Token_mutable))
    {
      node = snoc(node, session->token_stream->cursor(), session->mempool);
      advance();
    }

  return start != session->token_stream->cursor();
}

bool Parser::parseFunctionSpecifier(const ListNode<std::size_t> *&node)
{
  std::size_t start = session->token_stream->cursor();

  int tk;
  while (0 != (tk = session->token_stream->lookAhead())
         && (tk == Token_inline || tk == Token_virtual
             || tk == Token_explicit))
    {
      node = snoc(node, session->token_stream->cursor(), session->mempool);
      advance();
    }

  return start != session->token_stream->cursor();
}

bool Parser::parseTypeId(TypeIdAST *&node)
{
  /// @todo implement the AST for typeId
  std::size_t start = session->token_stream->cursor();

  TypeSpecifierAST *spec = 0;
  if (!parseTypeSpecifier(spec))
    {
      rewind(start);
      return false;
    }

  DeclaratorAST *decl = 0;
  parseAbstractDeclarator(decl);

generator/parser/parser.cpp  view on Meta::CPAN

          break;
        }
      node = snoc(node, decl, session->mempool);
    }

  return true;
}

bool Parser::parseParameterDeclarationClause(ParameterDeclarationClauseAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  ParameterDeclarationClauseAST *ast
    = CreateNode<ParameterDeclarationClauseAST>(session->mempool);

  if (!parseParameterDeclarationList(ast->parameter_declarations))
    {
      if (session->token_stream->lookAhead() == ')')
        goto good;

      if (session->token_stream->lookAhead() == Token_ellipsis
          && session->token_stream->lookAhead(1) == ')')
        {
          ast->ellipsis = session->token_stream->cursor();
          goto good;
        }

      return false;
    }

 good:

  if (session->token_stream->lookAhead() == Token_ellipsis)
    {
      ast->ellipsis = session->token_stream->cursor();
      advance();
    }

  /// @todo add ellipsis
  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseParameterDeclarationList(const ListNode<ParameterDeclarationAST*> *&node)
{
  std::size_t start = session->token_stream->cursor();

  ParameterDeclarationAST *param = 0;
  if (!parseParameterDeclaration(param))
    {
      rewind(start);
      return false;
    }

  node = snoc(node, param, session->mempool);

generator/parser/parser.cpp  view on Meta::CPAN

          return false;
        }
      node = snoc(node, param, session->mempool);
    }

  return true;
}

bool Parser::parseParameterDeclaration(ParameterDeclarationAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  const ListNode<std::size_t> *storage = 0;
  parseStorageClassSpecifier(storage);

  // parse decl spec
  TypeSpecifierAST *spec = 0;
  if (!parseTypeSpecifier(spec))
    {
      rewind(start);
      return false;
    }

  int index = session->token_stream->cursor();

  DeclaratorAST *decl = 0;
  if (!parseDeclarator(decl))
    {
      rewind(index);

      // try with abstract declarator
      parseAbstractDeclarator(decl);
    }

generator/parser/parser.cpp  view on Meta::CPAN

  ast->expression = expr;

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseClassSpecifier(TypeSpecifierAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  int kind = session->token_stream->lookAhead();
  if (kind != Token_class && kind != Token_struct && kind != Token_union)
    return false;

  std::size_t class_key = session->token_stream->cursor();
  advance();

  WinDeclSpecAST *winDeclSpec = 0;
  parseWinDeclSpec(winDeclSpec);

  while (session->token_stream->lookAhead() == Token_identifier
         && session->token_stream->lookAhead(1) == Token_identifier)
    {
      advance();
    }

generator/parser/parser.cpp  view on Meta::CPAN

  ast->win_decl_specifiers = winDeclSpec;
  ast->class_key = class_key;
  ast->name = name;
  ast->base_clause = bases;

  while (session->token_stream->lookAhead())
    {
      if (session->token_stream->lookAhead() == '}')
        break;

      std::size_t startDecl = session->token_stream->cursor();

      DeclarationAST *memSpec = 0;
      if (!parseMemberSpecification(memSpec))
        {
          if (startDecl == session->token_stream->cursor())
            advance(); // skip at least one token
          skipUntilDeclaration();
        }
      else
        ast->member_specs = snoc(ast->member_specs, memSpec, session->mempool);
    }

  clearComment();

  ADVANCE_NR('}', "}");

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseAccessSpecifier(DeclarationAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  const ListNode<std::size_t> *specs = 0;

  bool done = false;
  while (!done)
    {
      switch(session->token_stream->lookAhead())
        {
        case Token_signals:
        case Token_slots:
        case Token_k_dcop:
        case Token_k_dcop_signals:
        case Token_public:
        case Token_protected:
        case Token_private:
          specs = snoc(specs, session->token_stream->cursor(), session->mempool);
          advance();
          break;

        default:
          done = true;
          break;
        }
    }

  if (!specs)

generator/parser/parser.cpp  view on Meta::CPAN

  AccessSpecifierAST *ast = CreateNode<AccessSpecifierAST>(session->mempool);
  ast->specs = specs;
  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseMemberSpecification(DeclarationAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  if (session->token_stream->lookAhead() == ';')
    {
      advance();
      return true;
    }
  else if (session->token_stream->lookAhead() == Token_Q_OBJECT || session->token_stream->lookAhead() == Token_K_DCOP)
    {
      advance();
      return true;

generator/parser/parser.cpp  view on Meta::CPAN

          addComment( node, m_commentStore.takeCommentInRange( lineFromTokenNumber( --node->end_token ) ) );

        return true;
      }
    }
    return false;
}

bool Parser::parseCtorInitializer(CtorInitializerAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  CHECK(':');

  CtorInitializerAST *ast = CreateNode<CtorInitializerAST>(session->mempool);
  ast->colon = start;

  if (!parseMemInitializerList(ast->member_initializers))
    {
      reportError(("Member initializers expected"));
    }

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseElaboratedTypeSpecifier(TypeSpecifierAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  int tk = session->token_stream->lookAhead();
  if (tk == Token_class  ||
      tk == Token_struct ||
      tk == Token_union  ||
      tk == Token_enum   ||
      tk == Token_typename)
    {
      std::size_t type = session->token_stream->cursor();
      advance();

      NameAST *name = 0;
      if (parseName(name, AcceptTemplate))
        {
          ElaboratedTypeSpecifierAST *ast
            = CreateNode<ElaboratedTypeSpecifierAST>(session->mempool);

          ast->type = type;
          ast->name = name;

generator/parser/parser.cpp  view on Meta::CPAN

          return true;
        }
    }

  rewind(start);
  return false;
}

bool Parser::parseExceptionSpecification(ExceptionSpecificationAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  CHECK(Token_throw);
  ADVANCE('(', "(");

  ExceptionSpecificationAST *ast
    = CreateNode<ExceptionSpecificationAST>(session->mempool);

  if (session->token_stream->lookAhead() == Token_ellipsis)
    {
      ast->ellipsis = session->token_stream->cursor();
      advance();
    }
  else
    {
      parseTypeIdList(ast->type_ids);
    }

  ADVANCE(')', ")");

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseEnumerator(EnumeratorAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  CHECK(Token_identifier);
  std::size_t id = start;

  EnumeratorAST *ast = CreateNode<EnumeratorAST>(session->mempool);
  ast->id = id;


  if (session->token_stream->lookAhead() == '=')
    {

generator/parser/parser.cpp  view on Meta::CPAN

  preparseLineComments( ast->end_token-1 );

  if( m_commentStore.hasComment() )
    addComment( node, m_commentStore.takeCommentInRange( lineFromTokenNumber(--ast->end_token) ) );

  return true;
}

bool Parser::parseInitDeclarator(InitDeclaratorAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  DeclaratorAST *decl = 0;
  if (!parseDeclarator(decl))
    {
      return false;
    }

  if (session->token_stream->lookAhead(0) == Token_asm)
    {
      advance();

generator/parser/parser.cpp  view on Meta::CPAN

  ast->initializer = init;

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseBaseClause(BaseClauseAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  CHECK(':');

  BaseSpecifierAST *baseSpec = 0;
  if (!parseBaseSpecifier(baseSpec))
    return false;

  BaseClauseAST *ast = CreateNode<BaseClauseAST>(session->mempool);
  ast->base_specifiers = snoc(ast->base_specifiers, baseSpec, session->mempool);

generator/parser/parser.cpp  view on Meta::CPAN

    }

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseInitializer(InitializerAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  int tk = session->token_stream->lookAhead();
  if (tk != '=' && tk != '(')
    return false;

  InitializerAST *ast = CreateNode<InitializerAST>(session->mempool);

  if (tk == '=')
    {
      advance();

generator/parser/parser.cpp  view on Meta::CPAN

        break;

      node = snoc(node, init, session->mempool);
    }

  return true;
}

bool Parser::parseMemInitializer(MemInitializerAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  NameAST *initId = 0;
  if (!parseName(initId, AcceptTemplate))
    {
      reportError(("Identifier expected"));
      return false;
    }

  ADVANCE('(', "(");
  ExpressionAST *expr = 0;

generator/parser/parser.cpp  view on Meta::CPAN

          reportError(("Type id expected"));
          break;
        }
    }

  return true;
}

bool Parser::parseBaseSpecifier(BaseSpecifierAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  BaseSpecifierAST *ast = CreateNode<BaseSpecifierAST>(session->mempool);

  if (session->token_stream->lookAhead() == Token_virtual)
    {
      ast->virt = session->token_stream->cursor();
      advance();

      int tk = session->token_stream->lookAhead();
      if (tk == Token_public || tk == Token_protected
          || tk == Token_private)
        {
          ast->access_specifier = session->token_stream->cursor();
          advance();
        }
    }
  else
    {
      int tk = session->token_stream->lookAhead();
      if (tk == Token_public || tk == Token_protected
          || tk == Token_private)
        {
          ast->access_specifier = session->token_stream->cursor();
          advance();
        }

      if (session->token_stream->lookAhead() == Token_virtual)
        {
          ast->virt = session->token_stream->cursor();
          advance();
        }
    }

  if (!parseName(ast->name, AcceptTemplate))
    reportError(("Class name expected"));

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

generator/parser/parser.cpp  view on Meta::CPAN

      list = snoc(list,init_clause,session->mempool);
    } while (session->token_stream->lookAhead() == ',');

  node = list;

  return true;
}

bool Parser::parseInitializerClause(InitializerClauseAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  InitializerClauseAST *ast = CreateNode<InitializerClauseAST>(session->mempool);

  if (session->token_stream->lookAhead() == '{')
    {
      advance();
      const ListNode<InitializerClauseAST*> *initializer_list = 0;
      if (session->token_stream->lookAhead() != '}' &&
              !parseInitializerList(initializer_list))
        {

generator/parser/parser.cpp  view on Meta::CPAN


  return true;
}

bool Parser::parsePtrToMember(PtrToMemberAST *&node)
{
#if defined(__GNUC__)
#warning "implemente me (AST)"
#endif

  std::size_t start = session->token_stream->cursor();

  std::size_t global_scope = 0;
  if (session->token_stream->lookAhead() == Token_scope)
    {
      global_scope = session->token_stream->cursor();
      advance();
    }

  UnqualifiedNameAST *name = 0;
  while (session->token_stream->lookAhead() == Token_identifier)
    {
      if (!parseUnqualifiedName(name))
        break;

      if (session->token_stream->lookAhead() == Token_scope

generator/parser/parser.cpp  view on Meta::CPAN

        advance();
    }

  rewind(start);
  return false;
}

bool Parser::parseUnqualifiedName(UnqualifiedNameAST *&node,
                                  bool parseTemplateId)
{
  std::size_t start = session->token_stream->cursor();

  std::size_t tilde = 0;
  std::size_t id = 0;
  OperatorFunctionIdAST *operator_id = 0;

  if (session->token_stream->lookAhead() == Token_identifier)
    {
      id = session->token_stream->cursor();
      advance();
    }
  else if (session->token_stream->lookAhead() == '~'
           && session->token_stream->lookAhead(1) == Token_identifier)
    {
      tilde = session->token_stream->cursor();
      advance(); // skip ~

      id = session->token_stream->cursor();
      advance(); // skip classname
    }
  else if (session->token_stream->lookAhead() == Token_operator)
    {
      if (!parseOperatorFunctionId(operator_id))
        return false;
    }
  else
    {
      return false;
    }

  UnqualifiedNameAST *ast = CreateNode<UnqualifiedNameAST>(session->mempool);
  ast->tilde = tilde;
  ast->id = id;
  ast->operator_id = operator_id;

  if (parseTemplateId && !tilde)
    {
      std::size_t index = session->token_stream->cursor();

      if (session->token_stream->lookAhead() == '<' && !(tokenMarkers(index) & IsNoTemplateArgumentList))
        {
          advance();

          // optional template arguments
          parseTemplateArgumentList(ast->template_arguments);

          if (session->token_stream->lookAhead() == '>')
            {

generator/parser/parser.cpp  view on Meta::CPAN

    }

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseStringLiteral(StringLiteralAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  if (session->token_stream->lookAhead() != Token_string_literal)
    return false;

  StringLiteralAST *ast = CreateNode<StringLiteralAST>(session->mempool);

  while (session->token_stream->lookAhead() == Token_string_literal)
    {
      ast->literals = snoc(ast->literals, session->token_stream->cursor(), session->mempool);
      advance();
    }

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseExpressionStatement(StatementAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  ExpressionAST *expr = 0;
  parseCommaExpression(expr);

  ADVANCE(';', ";");

  ExpressionStatementAST *ast = CreateNode<ExpressionStatementAST>(session->mempool);
  ast->expression = expr;

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;
  return true;
}

bool Parser::parseJumpStatement(StatementAST *&node)
{
  std::size_t op = session->token_stream->cursor();
  std::size_t kind = session->token_stream->lookAhead();
  std::size_t identifier = 0;

  if (kind != Token_break && kind != Token_continue && kind != Token_goto)
      return false;

  advance();
  if (kind == Token_goto)
    {
      ADVANCE(Token_identifier,"label");

generator/parser/parser.cpp  view on Meta::CPAN

  ast->op = op;
  ast->identifier = identifier;

  UPDATE_POS(ast,ast->op,_M_last_valid_token+1);
  node = ast;
  return true;
}

bool Parser::parseStatement(StatementAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  switch(session->token_stream->lookAhead())
    {
    case Token_while:
      return parseWhileStatement(node);

    case Token_do:
      return parseDoStatement(node);

    case Token_for:

generator/parser/parser.cpp  view on Meta::CPAN


  return parseExpressionOrDeclarationStatement(node);
}

bool Parser::parseExpressionOrDeclarationStatement(StatementAST *&node)
{
  // hold any errors while the expression/declaration ambiguity is resolved
  // for this statement
  bool hold = holdErrors(true);

  std::size_t start = session->token_stream->cursor();

  ///@todo solve -1 thing
  StatementAST *decl_ast = 0;
  bool maybe_amb = parseDeclarationStatement(decl_ast);
  maybe_amb &= session->token_stream->kind(session->token_stream->cursor() - 1) == ';';

  // if parsing as a declaration succeeded, then any pending errors are genuine.
  // Otherwise this is not a declaration so ignore the errors.
  if (decl_ast)
      reportPendingErrors();
  else
      m_pendingErrors.clear();

  std::size_t end = session->token_stream->cursor();

  rewind(start);
  StatementAST *expr_ast = 0;
  maybe_amb &= parseExpressionStatement(expr_ast);
  maybe_amb &= session->token_stream->kind(session->token_stream->cursor() - 1) == ';';

  // if parsing as an expression succeeded, then any pending errors are genuine.
  // Otherwise this is not an expression so ignore the errors.
  if (expr_ast)
      reportPendingErrors();
  else
      m_pendingErrors.clear();

  if (maybe_amb)
    {

generator/parser/parser.cpp  view on Meta::CPAN

      ExpressionOrDeclarationStatementAST *ast
        = CreateNode<ExpressionOrDeclarationStatementAST>(session->mempool);
      ast->declaration = decl_ast;
      ast->expression = expr_ast;

      UPDATE_POS(ast, start, _M_last_valid_token+1);
      node = ast;
    }
  else
    {
      rewind(std::max(end, session->token_stream->cursor()));

      node = decl_ast;
      if (!node)
        node = expr_ast;
    }

  holdErrors(hold);

  if (!node)
    syntaxError();

  return node != 0;
}

bool Parser::parseCondition(ConditionAST *&node, bool initRequired)
{
  std::size_t start = session->token_stream->cursor();

  ConditionAST *ast = CreateNode<ConditionAST>(session->mempool);
  TypeSpecifierAST *spec = 0;

  if (parseTypeSpecifier(spec))
    {
      ast->type_specifier = spec;

      std::size_t declarator_start = session->token_stream->cursor();

      DeclaratorAST *decl = 0;
      if (!parseDeclarator(decl))
        {
          rewind(declarator_start);
          if (!initRequired && !parseAbstractDeclarator(decl))
            decl = 0;
        }

      if (decl && (!initRequired || session->token_stream->lookAhead() == '='))

generator/parser/parser.cpp  view on Meta::CPAN


  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}


bool Parser::parseWhileStatement(StatementAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  ADVANCE(Token_while, "while");
  ADVANCE('(' , "(");

  ConditionAST *cond = 0;
  if (!parseCondition(cond))
    {
      reportError("Condition expected");
      return false;
    }

generator/parser/parser.cpp  view on Meta::CPAN

  ast->statement = body;

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseDoStatement(StatementAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  ADVANCE(Token_do, "do");

  StatementAST *body = 0;
  if (!parseStatement(body))
    {
      reportError(("Statement expected"));
      //return false;
    }

generator/parser/parser.cpp  view on Meta::CPAN

  ast->expression = expr;

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseForStatement(StatementAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  ADVANCE(Token_for, "for");
  ADVANCE('(', "(");

  StatementAST *init = 0;
  if (!parseForInitStatement(init))
    {
      reportError(("'for' initialization expected"));
      return false;
    }

generator/parser/parser.cpp  view on Meta::CPAN

bool Parser::parseForInitStatement(StatementAST *&node)
{
  if (parseDeclarationStatement(node))
    return true;

  return parseExpressionStatement(node);
}

bool Parser::parseCompoundStatement(StatementAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  CHECK('{');

  CompoundStatementAST *ast = CreateNode<CompoundStatementAST>(session->mempool);
  while (session->token_stream->lookAhead())
    {
      if (session->token_stream->lookAhead() == '}')
        break;

      std::size_t startStmt = session->token_stream->cursor();

      StatementAST *stmt = 0;
      if (!parseStatement(stmt))
        {
          if (startStmt == session->token_stream->cursor())
            advance();

          skipUntilStatement();
        }
      else
        {
          ast->statements = snoc(ast->statements, stmt, session->mempool);
        }
    }

generator/parser/parser.cpp  view on Meta::CPAN



  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseIfStatement(StatementAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  ADVANCE(Token_if, "if");

  ADVANCE('(' , "(");
  IfStatementAST *ast = CreateNode<IfStatementAST>(session->mempool);

  ConditionAST *cond = 0;
  if (!parseCondition(cond))
    {
      reportError(("Condition expected"));

generator/parser/parser.cpp  view on Meta::CPAN

    }

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseSwitchStatement(StatementAST *&node)
{
  std::size_t start = session->token_stream->cursor();
  ADVANCE(Token_switch, "switch");

  ADVANCE('(' , "(");

  ConditionAST *cond = 0;
  if (!parseCondition(cond))
    {
      reportError(("Condition expected"));
      return false;
    }

generator/parser/parser.cpp  view on Meta::CPAN

  return true;
}

bool Parser::parseLabeledStatement(StatementAST *&node)
{
  switch(session->token_stream->lookAhead())
    {
    case Token_identifier:
    case Token_default:
      {
        std::size_t start = session->token_stream->cursor();
        if (session->token_stream->lookAhead(1) == ':')
          {
            advance();
            advance();

            StatementAST *stmt = 0;
            if (parseStatement(stmt))
              {
                LabeledStatementAST* ast = CreateNode<LabeledStatementAST>(session->mempool);
                ast->label = start;

generator/parser/parser.cpp  view on Meta::CPAN

                UPDATE_POS(ast, start, _M_last_valid_token+1);
                node = ast;
                return true;
              }
          }
          break;
      }

    case Token_case:
      {
        std::size_t start = session->token_stream->cursor();

        advance();
        ExpressionAST *expr = 0;
        if (!parseConstantExpression(expr))
          {
            reportError(("Expression expected"));
          }
        else if (session->token_stream->lookAhead() == Token_ellipsis)
          {
            advance();

generator/parser/parser.cpp  view on Meta::CPAN

      return parseUsing(node);
    case Token_asm:
      return parseAsmDefinition(node);
    case Token_namespace:
      return parseNamespaceAliasDefinition(node);
    }

  Comment mcomment = comment();
  clearComment();

  std::size_t start = session->token_stream->cursor();

  const ListNode<std::size_t> *cv = 0;
  parseCvQualify(cv);

  const ListNode<std::size_t> *storageSpec = 0;
  parseStorageClassSpecifier(storageSpec);

  parseCvQualify(cv);

  TypeSpecifierAST *spec = 0;

generator/parser/parser.cpp  view on Meta::CPAN

    addComment(ast, mcomment);

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseNamespaceAliasDefinition(DeclarationAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  CHECK(Token_namespace);

  NamespaceAliasDefinitionAST *ast
    = CreateNode<NamespaceAliasDefinitionAST>(session->mempool);

  size_t pos = session->token_stream->cursor();
  ADVANCE(Token_identifier,  "identifier");
  ast->namespace_name = pos;

  ADVANCE('=', "=");

  if (!parseName(ast->alias_name))
    {
      reportError(("Namespace name expected"));
    }

  ADVANCE(';', ";");

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseDeclarationStatement(StatementAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  DeclarationAST *decl = 0;
  if (!parseBlockDeclaration(decl))
    return false;

  DeclarationStatementAST *ast = CreateNode<DeclarationStatementAST>(session->mempool);
  ast->declaration = decl;

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseDeclarationInternal(DeclarationAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  // that is for the case '__declspec(dllexport) int ...' or
  // '__declspec(dllexport) inline int ...', etc.
  WinDeclSpecAST *winDeclSpec = 0;
  parseWinDeclSpec(winDeclSpec);

  const ListNode<std::size_t> *funSpec = 0;
  bool hasFunSpec = parseFunctionSpecifier(funSpec);

  const ListNode<std::size_t> *cv = 0;

generator/parser/parser.cpp  view on Meta::CPAN

  if (hasStorageSpec && !hasFunSpec)
    hasFunSpec = parseFunctionSpecifier(funSpec);

  // that is for the case 'friend __declspec(dllexport) ....'
  if (!winDeclSpec)
    parseWinDeclSpec(winDeclSpec);

  if (!cv)
    parseCvQualify(cv);

  int index = session->token_stream->cursor();
  NameAST *name = 0;
  if (parseName(name, AcceptTemplate) && session->token_stream->lookAhead() == '(')
    {
      // no type specifier, maybe a constructor or a cast operator??

      rewind(index);

      InitDeclaratorAST *declarator = 0;
      if (parseInitDeclarator(declarator))
        {

generator/parser/parser.cpp  view on Meta::CPAN

    {
      Q_ASSERT(spec != 0);

      if (!hasFunSpec)
        parseFunctionSpecifier(funSpec);         // e.g. "void inline"

      spec->cv = cv;

      const ListNode<InitDeclaratorAST*> *declarators = 0;
      InitDeclaratorAST *decl = 0;
      int startDeclarator = session->token_stream->cursor();
      bool maybeFunctionDefinition = false;

      if (session->token_stream->lookAhead() != ';')
        {
          if (parseInitDeclarator(decl) && (session->token_stream->lookAhead() == '{' || session->token_stream->lookAhead() == Token_try))
            {
              // function definition
              maybeFunctionDefinition = true;
            }
          else

generator/parser/parser.cpp  view on Meta::CPAN

  else if (parseEnumSpecifier(node))
    return true;
  else if (parseTypeSpecifier(node))
    return true;

  return false;
}

bool Parser::parseTryBlockStatement(StatementAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  CHECK(Token_try);

  TryBlockStatementAST *ast = CreateNode<TryBlockStatementAST>(session->mempool);

  StatementAST *stmt = 0;
  if (!parseCompoundStatement(stmt))
    {
      syntaxError();
      return false;

generator/parser/parser.cpp  view on Meta::CPAN

  ast->try_block = stmt;

  if (session->token_stream->lookAhead() != Token_catch)
    {
      reportError(("'catch' expected after try block"));
      return false;
    }

  while (session->token_stream->lookAhead() == Token_catch)
    {
      std::size_t catchStart = session->token_stream->cursor();
      
      advance();
      ADVANCE('(', "(");
      ConditionAST *cond = 0;
      if (session->token_stream->lookAhead() == Token_ellipsis)
        {
          advance();
        }
      else if(session->token_stream->lookAhead() == ')') {
        //Do nothing, this is equivalent to ellipsis

generator/parser/parser.cpp  view on Meta::CPAN

      ast->catch_blocks = snoc(ast->catch_blocks, catch_ast, session->mempool);
    }

  node = ast;
  UPDATE_POS(ast, start, _M_last_valid_token+1);
  return true;
}

bool Parser::parsePrimaryExpression(ExpressionAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  PrimaryExpressionAST *ast = CreateNode<PrimaryExpressionAST>(session->mempool);

  switch(session->token_stream->lookAhead())
    {
    case Token_string_literal:
      parseStringLiteral(ast->literal);
      break;

    case Token_number_literal:
    case Token_char_literal:
    case Token_true:
    case Token_false:
    case Token_this:
      ast->token = session->token_stream->cursor();
      advance();
      break;

    case '(':
      advance();

      if (session->token_stream->lookAhead() == '{')
        {
          if (!parseCompoundStatement(ast->expression_statement))
            return false;

generator/parser/parser.cpp  view on Meta::CPAN

  postfix-expression-internal:
  [ expression ]
  ( expression-list [opt] )
  (.|->) template [opt] id-expression
  (.|->) pseudo-destructor-name
  ++
  --
*/
bool Parser::parsePostfixExpressionInternal(ExpressionAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  switch (session->token_stream->lookAhead())
    {
    case '[':
      {
        advance();
        ExpressionAST *expr = 0;
        parseExpression(expr);
        CHECK(']');

generator/parser/parser.cpp  view on Meta::CPAN

        ast->arguments = expr;

        UPDATE_POS(ast, start, _M_last_valid_token+1);
        node = ast;
      }
      return true;

    case '.':
    case Token_arrow:
      {
        std::size_t op = session->token_stream->cursor();
        advance();

//         std::size_t templ = 0;
//         if (session->token_stream->lookAhead() == Token_template)
//           {
//             templ = session->token_stream->cursor();
//             advance();
//           }

        NameAST *name = 0;
        if (!parseName(name, EventuallyAcceptTemplate))
          return false;

        ClassMemberAccessAST *ast = CreateNode<ClassMemberAccessAST>(session->mempool);
        ast->op = op;
        ast->name = name;

        UPDATE_POS(ast, start, _M_last_valid_token+1);
        node = ast;
      }
      return true;

    case Token_incr:
    case Token_decr:
      {
        std::size_t op = session->token_stream->cursor();
        advance();

        IncrDecrExpressionAST *ast = CreateNode<IncrDecrExpressionAST>(session->mempool);
        ast->op = op;

        UPDATE_POS(ast, start, _M_last_valid_token+1);
        node = ast;
      }
      return true;

generator/parser/parser.cpp  view on Meta::CPAN

    }
}

/*
  postfix-expression:
  simple-type-specifier ( expression-list [opt] )
  primary-expression postfix-expression-internal*
*/
bool Parser::parsePostfixExpression(ExpressionAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  switch (session->token_stream->lookAhead())
    {
    case Token_dynamic_cast:
    case Token_static_cast:
    case Token_reinterpret_cast:
    case Token_const_cast:
      {
        std::size_t castOp = session->token_stream->cursor();
        advance();

        CHECK('<');
        TypeIdAST *typeId = 0;
        parseTypeId(typeId);
        CHECK('>');

        CHECK('(');
        ExpressionAST *expr = 0;
        parseCommaExpression(expr);

generator/parser/parser.cpp  view on Meta::CPAN

            ast->sub_expressions = snoc(ast->sub_expressions, e, session->mempool);
          }

        UPDATE_POS(ast, start, _M_last_valid_token+1);
        node = ast;
      }
      return true;

    case Token_typename:
      {
        std::size_t token = session->token_stream->cursor();
        advance();

        NameAST* name = 0;
        if (!parseName(name, AcceptTemplate))
          return false;

        CHECK('(');
        ExpressionAST *expr = 0;
        parseCommaExpression(expr);
        CHECK(')');

generator/parser/parser.cpp  view on Meta::CPAN

        TypeIdentificationAST *ast = CreateNode<TypeIdentificationAST>(session->mempool);
        UPDATE_POS(ast, start, _M_last_valid_token+1);
        node = ast;
      }
      return true;

    default:
      break;
    }

  std::size_t saved_pos = session->token_stream->cursor();

  TypeSpecifierAST *typeSpec = 0;
  ExpressionAST *expr = 0;

  // let's try to parse a type
  NameAST *name = 0;
  if (parseName(name, AcceptTemplate))
    {
      Q_ASSERT(name->unqualified_name != 0);

generator/parser/parser.cpp  view on Meta::CPAN


      UPDATE_POS(ast, start, _M_last_valid_token+1);
      node = ast;
    }

  return true;
}

bool Parser::parseUnaryExpression(ExpressionAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  switch(session->token_stream->lookAhead())
    {
    case Token_incr:
    case Token_decr:
    case '*':
    case '&':
    case '+':
    case '-':
    case '!':
    case Token_not:
    case '~':
      {
        std::size_t op = session->token_stream->cursor();
        advance();

        ExpressionAST *expr = 0;
        if (!parseCastExpression(expr))
          return false;

        UnaryExpressionAST *ast = CreateNode<UnaryExpressionAST>(session->mempool);
        ast->op = op;
        ast->expression = expr;

        UPDATE_POS(ast, start, _M_last_valid_token+1);
        node = ast;
      }
      return true;

    case Token_sizeof:
      {
        std::size_t sizeof_token = session->token_stream->cursor();
        advance();

        SizeofExpressionAST *ast = CreateNode<SizeofExpressionAST>(session->mempool);
        ast->sizeof_token = sizeof_token;

        std::size_t index = session->token_stream->cursor();
        if (session->token_stream->lookAhead() == '(')
          {
            advance();
            if (parseTypeId(ast->type_id) && session->token_stream->lookAhead() == ')')
              {
                advance(); // skip )

                UPDATE_POS(ast, start, _M_last_valid_token+1);
                node = ast;
                return true;

generator/parser/parser.cpp  view on Meta::CPAN


  if (token == Token_delete
      || (token == Token_scope && session->token_stream->lookAhead(1) == Token_delete))
    return parseDeleteExpression(node);

  return parsePostfixExpression(node);
}

bool Parser::parseNewExpression(ExpressionAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  NewExpressionAST *ast = CreateNode<NewExpressionAST>(session->mempool);

  if (session->token_stream->lookAhead() == Token_scope
      && session->token_stream->lookAhead(1) == Token_new)
    {
      ast->scope_token = session->token_stream->cursor();
      advance();
    }

  size_t pos = session->token_stream->cursor();
  CHECK(Token_new);
  ast->new_token = pos;

  if (session->token_stream->lookAhead() == '(')
    {
      advance();
      parseCommaExpression(ast->expression);
      CHECK(')');
    }

generator/parser/parser.cpp  view on Meta::CPAN

  parseNewInitializer(ast->new_initializer);

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseNewTypeId(NewTypeIdAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  TypeSpecifierAST *typeSpec = 0;
  if (!parseTypeSpecifier(typeSpec))
    return false;

  NewTypeIdAST *ast = CreateNode<NewTypeIdAST>(session->mempool);
  ast->type_specifier = typeSpec;

  parseNewDeclarator(ast->new_declarator);

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseNewDeclarator(NewDeclaratorAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  NewDeclaratorAST *ast = CreateNode<NewDeclaratorAST>(session->mempool);
  PtrOperatorAST *ptrOp = 0;
  if (parsePtrOperator(ptrOp))
    {
      ast->ptr_op = ptrOp;
      parseNewDeclarator(ast->sub_declarator);
    }

  while (session->token_stream->lookAhead() == '[')

generator/parser/parser.cpp  view on Meta::CPAN

    }

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseNewInitializer(NewInitializerAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  CHECK('(');

  NewInitializerAST *ast = CreateNode<NewInitializerAST>(session->mempool);

  parseCommaExpression(ast->expression);

  CHECK(')');

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseDeleteExpression(ExpressionAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  DeleteExpressionAST *ast = CreateNode<DeleteExpressionAST>(session->mempool);

  if (session->token_stream->lookAhead() == Token_scope
      && session->token_stream->lookAhead(1) == Token_delete)
    {
      ast->scope_token = session->token_stream->cursor();
      advance();
    }

  size_t pos = session->token_stream->cursor();
  CHECK(Token_delete);
  ast->delete_token =  pos;

  if (session->token_stream->lookAhead() == '[')
    {
      ast->lbracket_token = session->token_stream->cursor();
      advance();
      size_t pos = session->token_stream->cursor();
      CHECK(']');
      ast->rbracket_token = pos;
    }

  if (!parseCastExpression(ast->expression))
    return false;

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

  return true;
}

bool Parser::parseCastExpression(ExpressionAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  if (session->token_stream->lookAhead() == '(')
    {
      advance();

      CastExpressionAST *ast = CreateNode<CastExpressionAST>(session->mempool);

      if (parseTypeId(ast->type_id))
        {
          if (session->token_stream->lookAhead() == ')')

generator/parser/parser.cpp  view on Meta::CPAN

            }
        }
    }

  rewind(start);
  return parseUnaryExpression(node);
}

bool Parser::parsePmExpression(ExpressionAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  if (!parseCastExpression(node) || !node) // ### fixme
    return false;

  while (session->token_stream->lookAhead() == Token_ptrmem)
    {
      std::size_t op = session->token_stream->cursor();
      advance();

      ExpressionAST *rightExpr = 0;
      if (!parseCastExpression(rightExpr))
        return false;

      BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(session->mempool);
      ast->op = op;
      ast->left_expression = node;
      ast->right_expression = rightExpr;

      UPDATE_POS(ast, start, _M_last_valid_token+1);
      node = ast;
    }

  return true;
}

bool Parser::parseMultiplicativeExpression(ExpressionAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  if (!parsePmExpression(node))
    return false;

  while (session->token_stream->lookAhead() == '*'
         || session->token_stream->lookAhead() == '/'
         || session->token_stream->lookAhead() == '%')
    {
      std::size_t op = session->token_stream->cursor();
      advance();

      ExpressionAST *rightExpr = 0;
      if (!parsePmExpression(rightExpr))
        return false;

      BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(session->mempool);
      ast->op = op;
      ast->left_expression = node;
      ast->right_expression = rightExpr;

generator/parser/parser.cpp  view on Meta::CPAN

      UPDATE_POS(ast, start, _M_last_valid_token+1);
      node = ast;
    }

  return true;
}


bool Parser::parseAdditiveExpression(ExpressionAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  if (!parseMultiplicativeExpression(node))
    return false;

  while (session->token_stream->lookAhead() == '+' || session->token_stream->lookAhead() == '-')
    {
      std::size_t op = session->token_stream->cursor();
      advance();

      ExpressionAST *rightExpr = 0;
      if (!parseMultiplicativeExpression(rightExpr))
        return false;

      BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(session->mempool);
      ast->op = op;
      ast->left_expression = node;
      ast->right_expression = rightExpr;

      UPDATE_POS(ast, start, _M_last_valid_token+1);
      node = ast;
    }

  return true;
}

bool Parser::parseShiftExpression(ExpressionAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  if (!parseAdditiveExpression(node))
    return false;

  while (session->token_stream->lookAhead() == Token_shift)
    {
      std::size_t op = session->token_stream->cursor();
      advance();

      ExpressionAST *rightExpr = 0;
      if (!parseAdditiveExpression(rightExpr))
        return false;

      BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(session->mempool);
      ast->op = op;
      ast->left_expression = node;
      ast->right_expression = rightExpr;

      UPDATE_POS(ast, start, _M_last_valid_token+1);
      node = ast;
    }

  return true;
}

bool Parser::parseRelationalExpression(ExpressionAST *&node, bool templArgs)
{
  std::size_t start = session->token_stream->cursor();

  if (!parseShiftExpression(node))
    return false;

  while (session->token_stream->lookAhead() == '<'
         || (session->token_stream->lookAhead() == '>' && !templArgs)
         || session->token_stream->lookAhead() == Token_leq
         || session->token_stream->lookAhead() == Token_geq)
    {
      std::size_t op = session->token_stream->cursor();
      advance();

      ExpressionAST *rightExpr = 0;
      if (!parseShiftExpression(rightExpr))
        return false;

      BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(session->mempool);
      ast->op = op;
      ast->left_expression = node;
      ast->right_expression = rightExpr;

      UPDATE_POS(ast, start, _M_last_valid_token+1);
      node = ast;
    }

  return true;
}

bool Parser::parseEqualityExpression(ExpressionAST *&node, bool templArgs)
{
  std::size_t start = session->token_stream->cursor();

  if (!parseRelationalExpression(node, templArgs))
    return false;

  while (session->token_stream->lookAhead() == Token_eq
         || session->token_stream->lookAhead() == Token_not_eq)
    {
      std::size_t op = session->token_stream->cursor();
      advance();

      ExpressionAST *rightExpr = 0;
      if (!parseRelationalExpression(rightExpr, templArgs))
        return false;

      BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(session->mempool);
      ast->op = op;
      ast->left_expression = node;
      ast->right_expression = rightExpr;

      UPDATE_POS(ast, start, _M_last_valid_token+1);
      node = ast;
    }

  return true;
}

bool Parser::parseAndExpression(ExpressionAST *&node, bool templArgs)
{
  std::size_t start = session->token_stream->cursor();

  if (!parseEqualityExpression(node, templArgs))
    return false;

  while (session->token_stream->lookAhead() == '&')
    {
      std::size_t op = session->token_stream->cursor();
      advance();

      ExpressionAST *rightExpr = 0;
      if (!parseEqualityExpression(rightExpr, templArgs))
        return false;

      BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(session->mempool);
      ast->op = op;
      ast->left_expression = node;
      ast->right_expression = rightExpr;

      UPDATE_POS(ast, start, _M_last_valid_token+1);
      node = ast;
    }

  return true;
}

bool Parser::parseExclusiveOrExpression(ExpressionAST *&node, bool templArgs)
{
  std::size_t start = session->token_stream->cursor();

  if (!parseAndExpression(node, templArgs))
    return false;

  while (session->token_stream->lookAhead() == '^')
    {
      std::size_t op = session->token_stream->cursor();
      advance();

      ExpressionAST *rightExpr = 0;
      if (!parseAndExpression(rightExpr, templArgs))
        return false;

      BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(session->mempool);
      ast->op = op;
      ast->left_expression = node;
      ast->right_expression = rightExpr;

      UPDATE_POS(ast, start, _M_last_valid_token+1);
      node = ast;
    }

  return true;
}

bool Parser::parseInclusiveOrExpression(ExpressionAST *&node, bool templArgs)
{
  std::size_t start = session->token_stream->cursor();

  if (!parseExclusiveOrExpression(node, templArgs))
    return false;

  while (session->token_stream->lookAhead() == '|')
    {
      std::size_t op = session->token_stream->cursor();
      advance();

      ExpressionAST *rightExpr = 0;
      if (!parseExclusiveOrExpression(rightExpr, templArgs))
        return false;

      BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(session->mempool);
      ast->op = op;
      ast->left_expression = node;
      ast->right_expression = rightExpr;

      UPDATE_POS(ast, start, _M_last_valid_token+1);
      node = ast;
    }

  return true;
}

bool Parser::parseLogicalAndExpression(ExpressionAST *&node, bool templArgs)
{
  std::size_t start = session->token_stream->cursor();

  if (!parseInclusiveOrExpression(node, templArgs))
    return false;

  while (session->token_stream->lookAhead() == Token_and)
    {
      std::size_t op = session->token_stream->cursor();
      advance();

      ExpressionAST *rightExpr = 0;
      if (!parseInclusiveOrExpression(rightExpr, templArgs))
        return false;

      BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(session->mempool);
      ast->op = op;
      ast->left_expression = node;
      ast->right_expression = rightExpr;

      UPDATE_POS(ast, start, _M_last_valid_token+1);
      node = ast;
    }

  return true;
}

bool Parser::parseLogicalOrExpression(ExpressionAST *&node, bool templArgs)
{
  std::size_t start = session->token_stream->cursor();

  if (!parseLogicalAndExpression(node, templArgs))
    return false;

  while (session->token_stream->lookAhead() == Token_or)
    {
      std::size_t op = session->token_stream->cursor();
      advance();

      ExpressionAST *rightExpr = 0;
      if (!parseLogicalAndExpression(rightExpr, templArgs))
        return false;

      BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(session->mempool);
      ast->op = op;
      ast->left_expression = node;
      ast->right_expression = rightExpr;

      UPDATE_POS(ast, start, _M_last_valid_token+1);
      node = ast;
    }

  return true;
}

bool Parser::parseConditionalExpression(ExpressionAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  if (!parseLogicalOrExpression(node))
    return false;

  if (session->token_stream->lookAhead() == '?')
    {
      advance();

      ExpressionAST *leftExpr = 0;
      if (!parseExpression(leftExpr))

generator/parser/parser.cpp  view on Meta::CPAN


      UPDATE_POS(ast, start, _M_last_valid_token+1);
      node = ast;
    }

  return true;
}

bool Parser::parseAssignmentExpression(ExpressionAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  if(parseSignalSlotExpression(node))
    return true;
    //Parsed a signal/slot expression, fine

  if (session->token_stream->lookAhead() == Token_throw && !parseThrowExpression(node))
    return false;
  else if (!parseConditionalExpression(node))
    return false;

  while (session->token_stream->lookAhead() == Token_assign
         || session->token_stream->lookAhead() == '=')
    {
      std::size_t op = session->token_stream->cursor();
      advance();

      ExpressionAST *rightExpr = 0;
      if (!parseConditionalExpression(rightExpr))
        return false;

      BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(session->mempool);
      ast->op = op;
      ast->left_expression = node;
      ast->right_expression = rightExpr;

generator/parser/parser.cpp  view on Meta::CPAN

  return parseConditionalExpression(node);
}

bool Parser::parseExpression(ExpressionAST *&node)
{
  return parseCommaExpression(node);
}

bool Parser::parseSignalSlotExpression(ExpressionAST *&node) {
  if(session->token_stream->lookAhead() == Token___qt_sig_slot__) {
    std::size_t start = session->token_stream->cursor();
    CHECK(Token___qt_sig_slot__);
    CHECK('(');

    SignalSlotExpressionAST *ast = CreateNode<SignalSlotExpressionAST>(session->mempool);
    parseUnqualifiedName(ast->name, false);
    CHECK('(');

    if(ast->name)
      parseTemplateArgumentList(ast->name->template_arguments);

generator/parser/parser.cpp  view on Meta::CPAN

    node = ast;

    return true;
  }else{
    return false;
  }
}

bool Parser::parseCommaExpression(ExpressionAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  if (!parseAssignmentExpression(node))
    return false;

  while (session->token_stream->lookAhead() == ',')
    {
      std::size_t op = session->token_stream->cursor();
      advance();

      ExpressionAST *rightExpr = 0;
      if (!parseAssignmentExpression(rightExpr))
        return false;

      BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(session->mempool);
      ast->op = op;
      ast->left_expression = node;
      ast->right_expression = rightExpr;

      UPDATE_POS(ast, start, _M_last_valid_token+1);
      node = ast;
    }

  return true;
}

bool Parser::parseThrowExpression(ExpressionAST *&node)
{
  std::size_t start = session->token_stream->cursor();

  size_t pos = session->token_stream->cursor();

  CHECK(Token_throw);

  ThrowExpressionAST *ast = CreateNode<ThrowExpressionAST>(session->mempool);
  ast->throw_token = pos;

  parseAssignmentExpression(ast->expression);

  UPDATE_POS(ast, start, _M_last_valid_token+1);
  node = ast;

generator/parser/parser.h  view on Meta::CPAN

  // so that the same error is not reported twice for a token
  QSet<std::size_t> m_syntaxErrorTokens;

  // when _M_hold_errors is true, reported errors are held in m_pendingErrors
  // rather than being reported to the Control immediately.
  //
  // this is used, for example, when parsing ambiguous statements.
  struct PendingError
  {
   QString message;
   std::size_t cursor;
  };
  QQueue<PendingError> m_pendingErrors;

private:
  Parser(const Parser& source);
  void operator = (const Parser& source);
};

#endif

generator/parser/problem.h  view on Meta::CPAN

#ifndef PROBLEM_H
#define PROBLEM_H

#include "cppparser_export.h"
#include "simplecursor.h"

struct CPPPARSER_EXPORT Problem {
    enum Source {
        Source_Preprocessor,
        Source_Lexer,
        Source_Parser
    };
    
    Source source;
    QString description;

generator/parser/rpp/anchor.h  view on Meta::CPAN

  AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef ANCHOR_H
#define ANCHOR_H

#include <QtCore/Qt>

#include "../cppparser_export.h"
#include "../simplecursor.h"

namespace rpp {
/**
 * A SimpleCursor with additional boolean value whether the range opened by this anchor is collapsed.
 * If that value is true, it means that Everything behind the anchor until the next one is collapsed to the exact position of this anchor.
 * */
class CPPPARSER_EXPORT Anchor : public SimpleCursor {
public:
  Anchor() : collapsed(false) {
  }
  
  explicit Anchor(const SimpleCursor& cursor, bool _collapsed=false, SimpleCursor _macroExpansion=SimpleCursor::invalid()) : SimpleCursor(cursor), collapsed(_collapsed), macroExpansion(_macroExpansion) {
  }
  explicit Anchor(int line, int column, bool _collapsed=false, SimpleCursor _macroExpansion=SimpleCursor::invalid()) : SimpleCursor(line, column), collapsed(_collapsed), macroExpansion(_macroExpansion) {
  }

  bool collapsed;
  
  ///@todo create a sub-class that contains macroExpansion. It is only needed in the location-table and everything using not, not actually in the anchors.
  SimpleCursor macroExpansion; //Zero if this position was not transformed through a macro-expansion, else a number that identifies the expansion
};
}

generator/parser/rpp/pp-location.h  view on Meta::CPAN

*/

#ifndef PP_LOCATION_H
#define PP_LOCATION_H

#include <QMap>
#include <QVector>
#include <QPair>

#include "../cppparser_export.h"
#include "../simplecursor.h"

#include "anchor.h"

typedef QVector<unsigned int> PreprocessedContents;

namespace rpp {

class CPPPARSER_EXPORT LocationTable
{
  public:

generator/parser/rpp/pp-location.h  view on Meta::CPAN

      * Returns the nearest anchor before @param position, and the position of the anchor.
     * If the character is in a collapsed range, the collapsed member is true.
      @param collapseIfMacroExpansion When this is true, all ranges that come from macro-expansion will be 
                                      considered collapsed.(The returned anchor will also have the collapsed member set)
      * */
    AnchorInTable anchorForOffset(std::size_t position, bool collapseIfMacroExpansion = false) const;

    void dump() const;

    /**
     * Splits the given @param text using this location-table into sub-strings each assigned to a cursor where it starts.
     * @param textStartPosition must be given as the start-position, because the location-table might not contain an anchor
     * for the first character.
    * */
    void splitByAnchors(const PreprocessedContents& text, const Anchor& textStartPosition, QList<PreprocessedContents>& strings, QList<Anchor>& anchors) const;
  
  private:
    QMap<std::size_t, Anchor> m_offsetTable;
    mutable QMap<std::size_t, Anchor>::ConstIterator m_currentOffset;
};

generator/parser/rpp/pp-macro-expander.cpp  view on Meta::CPAN

        
        Anchor inputPosition = input.inputPosition();
        IndexedString name = IndexedString::fromIndex(skip_identifier (input));
        
        Anchor inputPosition2 = input.inputPosition();
        pp_actual actual = resolve_formal(name, input);
        if (actual.isValid()) {
          Q_ASSERT(actual.text.size() == actual.inputPosition.size());
          
          QList<PreprocessedContents>::const_iterator textIt = actual.text.constBegin();
          QList<Anchor>::const_iterator cursorIt = actual.inputPosition.constBegin();

          for( ; textIt != actual.text.constEnd(); ++textIt, ++cursorIt )
          {
            output.appendString(*cursorIt, *textIt);
          }
          output << ' '; //Insert a whitespace to omit implicit token merging
          output.mark(input.inputPosition());
          
          if(actual.text.isEmpty()) {
            int start = input.offset();
            
            skip_blanks(input, devnull());
            //Omit paste tokens behind empty used actuals, else we will merge with the previous text
            if(!input.atEnd() && input == '#' && !(++input).atEnd() && input == '#') {

generator/parser/rpp/pp-macro-expander.cpp.orig  view on Meta::CPAN

        
        Anchor inputPosition = input.inputPosition();
        IndexedString name = IndexedString::fromIndex(skip_identifier (input));
        
        Anchor inputPosition2 = input.inputPosition();
        pp_actual actual = resolve_formal(name, input);
        if (actual.isValid()) {
          Q_ASSERT(actual.text.size() == actual.inputPosition.size());
          
          QList<PreprocessedContents>::const_iterator textIt = actual.text.constBegin();
          QList<Anchor>::const_iterator cursorIt = actual.inputPosition.constBegin();

          for( ; textIt != actual.text.constEnd(); ++textIt, ++cursorIt )
          {
            output.appendString(*cursorIt, *textIt);
          }
          output << ' '; //Insert a whitespace to omit implicit token merging
          output.mark(input.inputPosition());
          
          if(actual.text.isEmpty()) {
            int start = input.offset();
            
            skip_blanks(input, devnull());
            //Omit paste tokens behind empty used actuals, else we will merge with the previous text
            if(input == '#' && (++input) == '#') {

generator/parser/rpp/pp-macro-expander.h  view on Meta::CPAN

#define PP_MACRO_EXPANDER_H

#include <QtCore/QList>
#include <QtCore/QHash>


#include "pp-macro.h"
#include "pp-stream.h"
#include "pp-scanner.h"
#include "anchor.h"
#include "../simplecursor.h"

namespace KDevelop {
  class IndexedString;
}

namespace rpp {

class pp;

//The value of a preprocessor function-like macro parameter

generator/parser/rpp/pp-stream.h  view on Meta::CPAN

  AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef STREAM_H
#define STREAM_H

#include <QtCore/QIODevice>

#include "../cppparser_export.h"
#include "../simplecursor.h"
#include "../indexedstring.h"
#include "anchor.h"
#include "chartools.h"

typedef QVector<unsigned int> PreprocessedContents;

namespace KDevelop {
  class IndexedString;
}

generator/parser/rpp/pp-stream.h  view on Meta::CPAN


    ///@warning Doesn't handle newlines correctly!
    Stream& operator--();

    ///Removes the last added item from the output, and returns it
    uint popLastOutput();
    
    ///Allows peeking at the items that were added to the output recently
    uint peekLastOutput(uint backOffset = 0) const;

    ///Returns the cursor that points to the current input position.
    Anchor inputPosition() const;
    ///If the input position is collapsed, the input position will be locked from now on. It will stay the same until a new one is set.
    void setInputPosition(const Anchor& position);

    ///Input-position that marks the start of the topmost currently expanding macro in the original document
    SimpleCursor originalInputPosition() const;
    void setOriginalInputPosition(const SimpleCursor& position);

    ///Used for output streams to mark stream positions with input position
    ///The macroExpansion member may have no effect if macroExpansion is set for this stream.

generator/parser/simplecursor.h  view on Meta::CPAN

 
 bool operator !=(const SimpleCursor& rhs) const {
     return !(*this == rhs);
 }

 SimpleCursor operator +(const SimpleCursor& rhs) const {
     return SimpleCursor(line + rhs.line, column + rhs.column);
 }
};

inline uint qHash(const SimpleCursor& cursor) {
    return cursor.line * 53 + cursor.column * 47;
}

#endif

generator/parser/tests/test_generator.cpp  view on Meta::CPAN

  TranslationUnitAST* parseGenerated(const QByteArray& unit)
  {
    Parser parser(&control);
    lastGeneratedSession = new ParseSession();
    lastGeneratedSession->setContentsAndGenerateLocationTable(tokenizeFromByteArray(unit));
    return  parser.parse(lastGeneratedSession);
  }

  void compareTokenStreams()
  {
    std::size_t cursor = 1;
    forever {
      QVERIFY(cursor < lastSession->token_stream->size());
      QVERIFY(cursor < lastGeneratedSession->token_stream->size());

      const Token& t1 = lastSession->token_stream->token( cursor );
      const Token& t2 = lastGeneratedSession->token_stream->token( cursor );

      QCOMPARE(t1, t2);
      if (t1.kind == Token_EOF)
        break;

      ++cursor;
    }
  }
};

#include "test_generator.moc"

QTEST_MAIN(TestGenerator)

smoke/qt/qtcore/tests/test.cpp  view on Meta::CPAN


int main(int argc, char ** argv)
{
  QApplication foo( argc, argv );
  foo.addLibraryPath( QString::null );
}

#endif

#ifdef TEST_QT_NO_CURSOR
#include "QtGui/qcursor.h"

int main(int argc, char ** argv)
{
  QCursor foo;
}

#endif

#ifdef TEST_QT_NO_DATASTREAM
#include "QtCore/qdatastream.h"



( run in 0.359 second using v1.01-cache-2.11-cpan-4d50c553e7e )