view release on metacpan or search on metacpan
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"