Fixed bug "Parser error when calling a macro with arguments".

This commit is contained in:
Liza Sakellari 2015-03-31 10:14:48 +02:00 committed by sftnight
parent d38891b490
commit 19ce2d03b6
4 changed files with 46 additions and 15 deletions

View File

@ -44,8 +44,10 @@ namespace cling {
Tok.startToken(curPos);
char C = *curPos++;
switch (C) {
case '[': case ']': case '(': case ')': case '{': case '}': case '"':
case '\'': case '\\': case ',': case '.': case '!': case '?': case '>':
case '"': case '\'':
return LexQuotedStringAndAdvance(--curPos, Tok);
case '[': case ']': case '(': case ')': case '{': case '}':
case '\\': case ',': case '.': case '!': case '?': case '>':
case '&': case '#': case '@':
// INTENTIONAL FALL THROUGHs
return LexPunctuator(C, Tok);
@ -146,20 +148,21 @@ namespace cling {
// Tok must be the starting quote (single or double), and we will
// lex until the next one or the end of the line.
const char* const start = curPos;
LexPunctuator(*curPos++, Tok); // '"' or "'"
assert( (Tok.getKind() >= tok::quote && Tok.getKind() <= tok::apostrophe) );
tok::TokenKind EndTokKind = Tok.getKind();
Tok.setKind(tok::raw_ident);
char start = '\0';
if (Tok.is(tok::quote)) start = '"';
else if (Tok.is(tok::apostrophe)) start = '\'';
Tok.startToken(curPos);
//consuming the string
while (true) {
bool escape = false;
while ( (escape || *curPos != start)
&& *curPos != '\0' && *curPos != '\r' && *curPos != '\n') {
// "AB\"foo \0x12 \012 \n"
/* bool escape = false;
while ( (escape || *curPos != *start) && *curPos != '\0' && *curPos != '\r' && *curPos != '\n') {
escape = ( (*curPos) == '\\' );
++curPos;
}
}*/
if (*curPos == '\0') {
Tok.setBufStart(curPos);
Tok.setKind(tok::eof);
@ -167,8 +170,10 @@ namespace cling {
return;
}
MetaLexer::LexPunctuator(*curPos++, Tok);
if (Tok.isNot(tok::unknown))
if (Tok.is(EndTokKind)) {
Tok.setLength(curPos - start + 1);
return;
}
}
}

View File

@ -49,7 +49,25 @@ namespace cling {
lookAhead(0);
}
void MetaParser::consumeToken_string(Token &tok) {
if (m_TokenCache.size())
m_TokenCache.erase(m_TokenCache.begin());
tok = lookAhead(0);
}
void MetaParser::consumeAnyStringToken(tok::TokenKind stopAt/*=tok::space*/) {
//this token is needed in order to check if we have reached the end of the string
//Token tok_is_quote;
//consumeToken_string(tok_is_quote);
//if the token tok_is_quote is of kind "quote"
//tok_is_quote.is(tok::quote){
//it means we have reached the end of the string
//}
consumeToken();
// we have to merge the tokens from the queue until we reach eof token or
// space token
@ -61,12 +79,14 @@ namespace cling {
|| MergedTok.is(tok::comment))
return;
//look ahead for the next token without consuming it
Token Tok = lookAhead(1);
Token PrevTok = Tok;
while (Tok.isNot(stopAt) && Tok.isNot(tok::eof)){
//MergedTok.setLength(MergedTok.getLength() + Tok.getLength());
m_TokenCache.erase(m_TokenCache.begin() + 1);
PrevTok = Tok;
//look ahead for the next token without consuming it
Tok = lookAhead(1);
}
MergedTok.setKind(tok::raw_ident);

View File

@ -75,6 +75,7 @@ namespace cling {
///\brief Consume the current 'peek' token.
///
void consumeToken();
void consumeToken_string(Token &tok);
void consumeAnyStringToken(tok::TokenKind stopAt = tok::space);
const Token& lookAhead(unsigned Num);
void skipWhitespace();

View File

@ -6,12 +6,17 @@
// LICENSE.TXT for details.
//------------------------------------------------------------------------------
// RUN: %cling %s "args(42)" 2>&1 | FileCheck %s
// RUN: %cling %s 'args(42,"")' 2>&1 | FileCheck %s
//CHECK-NOT: {{.*error|note:.*}}
//CHECK: warning: function 'args' cannot be called with no arguments.
extern "C" int printf(const char* fmt, ...);
void args(int I, const char* S = "ArgString") {
void args(int I, const char* R, const char* S = "ArgString") {
printf("I=%d\n", I); // CHECK: I=42
printf("S=%s\n", S); // CHECK: S=ArgString
printf("R=%s\n", R);
}