Beispiel #1
0
void PHPSourceFile::ReadImplements(wxArrayString& impls)
{
    wxString type;
    phpLexerToken token;
    while(NextToken(token)) {
        switch(token.type) {
        case kPHP_T_IDENTIFIER:
        case kPHP_T_NS_SEPARATOR:
            type << token.text;
            break;
        case ',':
            // More to come
            if(!type.IsEmpty()) {
                wxString fullyQualifiedType = MakeIdentifierAbsolute(type);
                if(impls.Index(fullyQualifiedType) == wxNOT_FOUND) {
                    impls.Add(fullyQualifiedType);
                }
                type.clear();
            }
            break;
        default:
            // unexpected token
            if(!type.IsEmpty()) {
                wxString fullyQualifiedType = MakeIdentifierAbsolute(type);
                if(impls.Index(fullyQualifiedType) == wxNOT_FOUND) {
                    impls.Add(fullyQualifiedType);
                }
                type.clear();
            }
            UngetToken(token);
            return;
        }
    }
}
Beispiel #2
0
bool PHPSourceFile::ReadCommaSeparatedIdentifiers(int delim, wxArrayString& list)
{
    phpLexerToken token;
    wxString temp;
    while(NextToken(token)) {
        if(token.IsAnyComment()) continue;
        if(token.type == delim) {
            if(!temp.IsEmpty() && list.Index(temp) == wxNOT_FOUND) {
                list.Add(MakeIdentifierAbsolute(temp));
            }
            UngetToken(token);
            return true;
        }

        switch(token.type) {
        case ',':
            if(list.Index(temp) == wxNOT_FOUND) {
                list.Add(MakeIdentifierAbsolute(temp));
            }
            temp.clear();
            break;
        default:
            temp << token.text;
            break;
        }
    }
    return false;
}
Beispiel #3
0
wxString PHPSourceFile::ReadType()
{
    bool cont = true;
    wxString type;
    phpLexerToken token;

    while(cont && NextToken(token)) {
        switch(token.type) {
        case kPHP_T_IDENTIFIER:
            type << token.text;
            break;

        case kPHP_T_NS_SEPARATOR:
            type << token.text;
            break;
        default:
            // restore the token so next call to NextToken
            // will pick it up again
            UngetToken(token);
            cont = false;
            break;
        }
    }

    type = MakeIdentifierAbsolute(type);
    return type;
}
Beispiel #4
0
/*foreach (array_expression as $value)
    statement
foreach (array_expression as $key => $value)
    statement*/
void PHPSourceFile::OnForEach()
{
    // read until the "as" keyword
    phpLexerToken token;
    if(!ReadUntilFound(kPHP_T_AS, token)) return;

    // Found the "as" key word and consumed it
    if(!NextToken(token)) return;

    phpLexerToken peekToken;
    if(!NextToken(peekToken)) return;

    // Ensure we got a variable
    if(token.type != kPHP_T_VARIABLE) return;

    // Check to see if we are using the syntax of:
    // foreach (array_expression as $key => $value)
    if(peekToken.type == kPHP_T_DOUBLE_ARROW) {
        if(!NextToken(token) || token.type != kPHP_T_VARIABLE) {
            return;
        }
    } else {
        UngetToken(peekToken);
    }

    // Create a new variable
    PHPEntityBase::Ptr_t var(new PHPEntityVariable());
    var->SetFullName(token.text);
    var->SetFilename(m_filename.GetFullPath());
    var->SetLine(token.lineNumber);

    if(!CurrentScope()->FindChild(var->GetFullName(), true)) {
        CurrentScope()->AddChild(var);
    }
}
Beispiel #5
0
bool PHPSourceFile::ReadVariableInitialization(PHPEntityBase::Ptr_t var)
{
    phpLexerToken token;
    if(!NextToken(token)) {
        return false;
    }

    if(token.type != '=') {
        // restore the token
        UngetToken(token);
        return false;
    }

    wxString expr;
    if(!ReadExpression(expr)) {
        return false; // EOF
    }

    // Optimize 'new ClassName(..)' expression
    if(expr.StartsWith("new")) {
        expr = expr.Mid(3);
        expr.Trim().Trim(false);
        expr = expr.BeforeFirst('(');
        expr.Trim().Trim(false);
        var->Cast<PHPEntityVariable>()->SetTypeHint(MakeIdentifierAbsolute(expr));

    } else {
        // keep the expression
        var->Cast<PHPEntityVariable>()->SetExpressionHint(expr);
    }
    return true;
}
Beispiel #6
0
Stmt *ParseIfStmt(int (*ParseDetails)(Stmt **stmt))
{
	Stmt *stmt;
	IfData *id;
	if((stmt = NewStmt()) != NULL)
	{
		if((id = (IfData *)calloc(1, sizeof(IfData))) != NULL)
		{
			stmt->procs = &if_stmt_procs;
			stmt->data = (void *)id;
			if((id->expr = ExprParse()) != NULL)
			{
				id->block = ParseBlock("if", ParseDetails);
				if(GetToken() == TK_ELSE)
				{
					id->elseblock = ParseBlock("else", ParseDetails);
				}
				else
				{
					UngetToken();
					id->elseblock = NULL;
				}
				return stmt;
			}
		}
		else
			LogMemError("if");
	}
	DeleteStmt(stmt);
	return NULL;
}
Beispiel #7
0
static FORMAT_PTR Enum_Format(Format_Parse_Ptr parser, BOOLEAN *error)
{ 
  TokenPtr Token;
  FORMAT_PTR Form, subform;
  LIST_PTR format_list;
  int num_formats, i, maxVal;
  
  num_formats = 0;
  Token = NextToken(parser);
  if (Token->Type == COLON_TOK) {
    Token = NextToken(parser);
    if (Token->Type != INT_TOK) {
      *error = TRUE;
      ParserError(Token, parser, "an integer");
      return NULL;
    } else {
      maxVal = Token->value.num;
    }
  } else {
    format_list = x_ipc_listCreate();
    do {
      if (num_formats > 0) Token = NextToken(parser);
      if (Token->Type != STR_TOK) {
	*error = TRUE;
	ParserError(Token, parser, "a string");
	return NULL;
      } else {
	Form = new_n_formatter(Token->value.str);
	/* More efficient for Lisp if all enum format names are upper case */
	LOCK_M_MUTEX;
	if (IS_LISP_MODULE()) {
	  upcase(Form->formatter.name);
	}
	UNLOCK_M_MUTEX;
	x_ipc_listInsertItem((char *)Form, format_list);
	num_formats++;
      }
      Token = NextToken(parser);
    } while (Token->Type == COMMA_TOK);
    UngetToken(parser, Token);
    maxVal = num_formats - 1;
  }
  
  Form = new_a_formatter(EnumFMT, num_formats+2);
  Form->formatter.a[1].i = maxVal;
  if (num_formats > 0) {
    /* Index from high to low since "format_list" 
       has formatters in reverse order */
    subform = (FORMAT_PTR)x_ipc_listFirst(format_list);
    for(i=num_formats;i>0;i--) {
      Form->formatter.a[i+1].f = subform;
      subform = (FORMAT_PTR)x_ipc_listNext(format_list);
    }
    x_ipc_listFree(&format_list);
  }
  return Form;
}
bool FBaseParser::PeekIdentifier( const TCHAR* Match )
{
	FToken Token;
	if (!GetToken(Token, true))
	{
		return false;
	}
	UngetToken(Token);
	return Token.TokenType==TOKEN_Identifier && FCString::Stricmp(Token.Identifier,Match)==0;
}
//
// Peek ahead and see if an identifier follows in the stream.
//
bool FBaseParser::PeekIdentifier( FName Match )
{
	FToken Token;
	if (!GetToken(Token, true))
	{
		return false;
	}
	UngetToken(Token);
	return Token.TokenType==TOKEN_Identifier && Token.TokenName==Match;
}
//------------------------------------------------------------------------------
bool FBasicTokenParser::PeekSymbol(TCHAR const* Match)
{
	FBasicToken Token;
	if (!GetToken(Token, true))
	{
		return false;
	}
	UngetToken(Token);

	return Token.TokenType == FBasicToken::TOKEN_Symbol && FCString::Stricmp(Token.Identifier, Match) == 0;
}
Beispiel #11
0
bool PHPSourceFile::ReadExpression(wxString& expression)
{
    expression.clear();
    phpLexerToken token;
    int depth(0);
    while(NextToken(token)) {
        if(token.type == ';') {
            return true;

        } else if(token.type == '{') {
            UngetToken(token);
            return true;
        }

        switch(token.type) {
        case kPHP_T_REQUIRE:
        case kPHP_T_REQUIRE_ONCE:
            expression.clear();
            return false;

        case kPHP_T_STRING_CAST:
        case kPHP_T_CONSTANT_ENCAPSED_STRING:
        case kPHP_T_C_COMMENT:
        case kPHP_T_CXX_COMMENT:
            // skip comments and strings
            break;
        case '(':
            depth++;
            expression << "(";
            break;
        case ')':
            depth--;
            if(depth == 0) {
                expression << ")";
            }
            break;
        case kPHP_T_NEW:
            if(depth == 0) {
                expression << token.text << " ";
            }
            break;
        default:
            if(depth == 0) {
                expression << token.text;
            }
            break;
        }
    }
    // reached EOF
    return false;
}
Beispiel #12
0
wxString PHPSourceFile::ReadExtends()
{
    wxString type;
    phpLexerToken token;
    while(NextToken(token)) {
        if(token.type == kPHP_T_IDENTIFIER || token.type == kPHP_T_NS_SEPARATOR) {
            type << token.text;
        } else {
            UngetToken(token);
            break;
        }
    }
    type = MakeIdentifierAbsolute(type);
    return type;
}
Beispiel #13
0
/*************************************************************************
*
*  ExprParse - Parses and contructs an expression parse tree.
*
*  Returns a pointer to top of expr tree or NULL if there's no
*    expr or an error occurred.
*
*************************************************************************/
Expr *ExprParse(void)
{
	Expr *expr;
	int errcnt = error_count;
	token = GetToken();
	vector_closing = 0;
	expr = Term1();
	UngetToken();
	if(error_count > errcnt)
	{
		ExprDelete(expr);
		return NULL;
	}
	return expr;
}
//
// Get an identifier token, return 1 if gotten, 0 if not.
//
bool FBaseParser::GetIdentifier( FToken& Token, bool bNoConsts )
{
	if (!GetToken(Token, bNoConsts))
	{
		return false;
	}

	if (Token.TokenType == TOKEN_Identifier)
	{
		return true;
	}

	UngetToken(Token);
	return false;
}
//
// Get a symbol token, return 1 if gotten, 0 if not.
//
bool FBaseParser::GetSymbol( FToken& Token )
{
	if (!GetToken(Token))
	{
		return false;
	}

	if( Token.TokenType == TOKEN_Symbol )
	{
		return true;
	}

	UngetToken(Token);
	return false;
}
//
// Get a specific identifier and return 1 if gotten, 0 if not.
// This is used primarily for checking for required symbols during compilation.
//
bool FBaseParser::MatchIdentifier( FName Match )
{
	FToken Token;
	if (!GetToken(Token))
	{
		return false;
	}

	if ((Token.TokenType == TOKEN_Identifier) && (Token.TokenName == Match))
	{
		return true;
	}

	UngetToken(Token);
	return false;
}
bool FBaseParser::MatchIdentifier( const TCHAR* Match )
{
	FToken Token;
	if (GetToken(Token))
	{
		if( Token.TokenType==TOKEN_Identifier && FCString::Stricmp(Token.Identifier,Match)==0 )
		{
			return true;
		}
		else
		{
			UngetToken(Token);
		}
	}
	
	return false;
}
Beispiel #18
0
bool FBaseParser::MatchSymbol( const TCHAR* Match )
{
	FToken Token;

	if (GetToken(Token, /*bNoConsts=*/ true))
	{
		if (Token.TokenType==TOKEN_Symbol && !FCString::Stricmp(Token.Identifier, Match))
		{
			return true;
		}
		else
		{
			UngetToken(Token);
		}
	}

	return false;
}
bool FBaseParser::MatchSymbol( const TCHAR* Match, ESymbolParseOption bParseTemplateClosingBracket/*=ESymbolParseOption::Normal*/ )
{
	FToken Token;

	if (GetToken(Token, /*bNoConsts=*/ true, bParseTemplateClosingBracket))
	{
		if (Token.TokenType==TOKEN_Symbol && !FCString::Stricmp(Token.Identifier, Match))
		{
			return true;
		}
		else
		{
			UngetToken(Token);
		}
	}

	return false;
}
Beispiel #20
0
Stmt *ParseLoadImageMapStmt(void)
{
	LoadImageMapStmtData *sd;
	int token;
	Stmt *stmt = NewStmt();
	if(stmt == NULL)
	{
		LogMemError("load_image_map");
		return NULL;
	}
	sd = (LoadImageMapStmtData *)calloc(1, sizeof(LoadImageMapStmtData));
	if(sd == NULL)
	{
		DeleteStmt(stmt);
		LogMemError("load_image_map");
		return NULL;
	}
	stmt->procs = &loadimagemap_stmt_procs;
	stmt->data = (void *)sd;

	token = GetNewIdentifier();
	if(token == TK_UNKNOWN_ID)
	{
		sd->name = (char *)malloc(strlen(token_buffer) + 1);
		if(sd->name == NULL)
		{
			DeleteStmt(stmt);
			LogMemError("load_color_map");
			return NULL;
		}
		strcpy(sd->name, token_buffer);
	}
	else
	{
		LogError("load_image_map: Expecting an unused identifier name.");
		LogError("  Found '%s'.", token_buffer);
		PrintFileAndLineNumber();
		UngetToken();
		DeleteStmt(stmt);
		return NULL;
	}

	return stmt;
}
//------------------------------------------------------------------------------
bool FBasicTokenParser::GetConstInt(int32& Result, TCHAR const* ErrorContext)
{
	FBasicToken Token;
	if (GetToken(Token))
	{
		if (Token.GetConstInt(Result))
		{
			return true;
		}
		else
		{
			UngetToken(Token);
		}
	}

	if (ErrorContext != NULL)
	{
		FText ErrorDesc = FText::Format(LOCTEXT("ContextualNoInt", "{0}: Missing expected integer constant"), FText::FromString(ErrorContext));
		SetError(FErrorState::ParseError, ErrorDesc);
	}
	return false;
}
bool FBaseParser::GetConstInt(int32& Result, const TCHAR* Tag)
{
	FToken Token;
	if (GetToken(Token))
	{
		if (Token.GetConstInt(Result))
		{
			return true;
		}
		else
		{
			UngetToken(Token);
		}
	}

	if (Tag != NULL)
	{
		FError::Throwf(TEXT("%s: Missing constant integer"), Tag );
	}

	return false;
}
Beispiel #23
0
//
// Check an identifier (atom) to see if it is a macro that should be expanded.
// If it is, and defined, push a tInput that will produce the appropriate expansion
// and return 1.
// If it is, but undefined, and expandUndef is requested, push a tInput that will 
// expand to 0 and return -1.
// Otherwise, return 0 to indicate no expansion, which is not necessarily an error.
//
int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool newLineOkay)
{
    ppToken->space = false;
    switch (atom) {
    case PpAtomLineMacro:
        ppToken->ival = parseContext.getCurrentLoc().line;
        sprintf(ppToken->name, "%d", ppToken->ival);
        UngetToken(PpAtomConstInt, ppToken);
        return 1;

    case PpAtomFileMacro: {
        if (parseContext.getCurrentLoc().name)
            parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based __FILE__");
        ppToken->ival = parseContext.getCurrentLoc().string;
        sprintf(ppToken->name, "%s", ppToken->loc.getStringNameOrNum().c_str());
        UngetToken(PpAtomConstInt, ppToken);
        return 1;
    }

    case PpAtomVersionMacro:
        ppToken->ival = parseContext.version;
        sprintf(ppToken->name, "%d", ppToken->ival);
        UngetToken(PpAtomConstInt, ppToken);
        return 1;

    default:
        break;
    }

    Symbol *sym = LookUpSymbol(atom);
    int token;
    int depth = 0;

    // no recursive expansions
    if (sym && sym->mac.busy)
        return 0;

    // not expanding undefined macros
    if ((! sym || sym->mac.undef) && ! expandUndef)
        return 0;

    // 0 is the value of an undefined macro
    if ((! sym || sym->mac.undef) && expandUndef) {
        pushInput(new tZeroInput(this));
        return -1;
    }

    tMacroInput *in = new tMacroInput(this);

    TSourceLoc loc = ppToken->loc;  // in case we go to the next line before discovering the error
    in->mac = &sym->mac;
    if (sym->mac.args) {
        token = scanToken(ppToken);
        if (newLineOkay) {
            while (token == '\n')                
                token = scanToken(ppToken);
        }
        if (token != '(') {
            parseContext.ppError(loc, "expected '(' following", "macro expansion", GetAtomString(atom));
            UngetToken(token, ppToken);
            ppToken->atom = atom;

            delete in;
            return 0;
        }
        in->args.resize(in->mac->argc);
        for (int i = 0; i < in->mac->argc; i++)
            in->args[i] = new TokenStream;
        int arg = 0;
        bool tokenRecorded = false;
        do {
            depth = 0;
            while (1) {
                token = scanToken(ppToken);
                if (token == EndOfInput) {
                    parseContext.ppError(loc, "End of input in macro", "macro expansion", GetAtomString(atom));
                    delete in;
                    return 0;
                }
                if (token == '\n') {
                    if (! newLineOkay) {
                        parseContext.ppError(loc, "End of line in macro substitution:", "macro expansion", GetAtomString(atom));
                        delete in;
                        return 0;
                    }
                    continue;
                }
                if (token == '#') {
                    parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", GetAtomString(atom));
                    delete in;
                    return 0;
                }
                if (in->mac->argc == 0 && token != ')')
                    break;
                if (depth == 0 && (token == ',' || token == ')'))
                    break;
                if (token == '(')
                    depth++;
                if (token == ')')
                    depth--;
                RecordToken(in->args[arg], token, ppToken);
                tokenRecorded = true;
            }
            if (token == ')') {
                if (in->mac->argc == 1 && tokenRecorded == 0)
                    break;
                arg++;
                break;
            }
            arg++;
        } while (arg < in->mac->argc);

        if (arg < in->mac->argc)
            parseContext.ppError(loc, "Too few args in Macro", "macro expansion", GetAtomString(atom));
        else if (token != ')') {
            depth=0;
            while (token != EndOfInput && (depth > 0 || token != ')')) {
                if (token == ')')
                    depth--;
                token = scanToken(ppToken);
                if (token == '(')
                    depth++;
            }

            if (token == EndOfInput) {
                parseContext.ppError(loc, "End of input in macro", "macro expansion", GetAtomString(atom));
                delete in;
                return 0;
            }
            parseContext.ppError(loc, "Too many args in macro", "macro expansion", GetAtomString(atom));
        }
        for (int i = 0; i < in->mac->argc; i++)
            in->args[i] = PrescanMacroArg(in->args[i], ppToken, newLineOkay);
    }

    pushInput(in);
    sym->mac.busy = 1;
    RewindTokenStream(sym->mac.body);

    return 1;
}
Beispiel #24
0
int MacroExpand(int atom, yystypepp * yylvalpp)
{
    Symbol              *sym = LookUpSymbol(macros, atom);
    MacroInputSrc       *in;
    int i,j, token, depth=0;
    const char *message;
	if (atom == __LINE__Atom) {
        yylvalpp->sc_int = GetLineNumber();
        snprintf(yylvalpp->symbol_name, MAX_SYMBOL_NAME_LEN+1, "%d", yylvalpp->sc_int);
        UngetToken(CPP_INTCONSTANT, yylvalpp);
        return 1;
    }
    if (atom == __FILE__Atom) {
        yylvalpp->sc_int = GetStringNumber();
        snprintf(yylvalpp->symbol_name, MAX_SYMBOL_NAME_LEN+1, "%d", yylvalpp->sc_int);
        UngetToken(CPP_INTCONSTANT, yylvalpp);
        return 1;
    }
	if (atom == __VERSION__Atom) {
        strcpy(yylvalpp->symbol_name,ESSL_VERSION_STRING);
        yylvalpp->sc_int = atoi(yylvalpp->symbol_name);
        UngetToken(CPP_INTCONSTANT, yylvalpp);
        return 1;
    }
    if (!sym || sym->details.mac.undef) return 0;
    if (sym->details.mac.busy) return 0;        // no recursive expansions
    in = malloc(sizeof(*in));
    memset(in, 0, sizeof(*in));
    in->base.scan = (void *)macro_scan;
    in->base.line = cpp->currentInput->line;
    in->base.name = cpp->currentInput->name;
    in->mac = &sym->details.mac;
    if (sym->details.mac.args) {
        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
		if (token != '(') {
            UngetToken(token, yylvalpp);
            yylvalpp->sc_ident = atom;
            return 0;
        }
        in->args = malloc(in->mac->argc * sizeof(TokenStream *));
        for (i=0; i<in->mac->argc; i++)
            in->args[i] = NewTokenStream("macro arg", 0);
		i=0;j=0;
        do{
            depth = 0;
			while(1) {
                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
                if (token <= 0) {
                    StoreStr("EOF in Macro ");
                    StoreStr(GetStringOfAtom(atable,atom));
                    message=GetStrfromTStr();
                    CPPShInfoLogMsg(message);
                    ResetTString();
                    return 1;
                }
                if((in->mac->argc==0) && (token!=')')) break;
                if (depth == 0 && (token == ',' || token == ')')) break;
                if (token == '(') depth++;
                if (token == ')') depth--;
                RecordToken(in->args[i], token, yylvalpp);
                j=1;
			}
            if (token == ')') {
                if((in->mac->argc==1) &&j==0)
                    break;
                i++;
                break;
            }
            i++;
		}while(i < in->mac->argc);

        if (i < in->mac->argc) {
            StoreStr("Too few args in Macro ");
            StoreStr(GetStringOfAtom(atable,atom));
            message=GetStrfromTStr();
            CPPShInfoLogMsg(message);
            ResetTString();
        } else if (token != ')') {
            depth=0;
			while (token >= 0 && (depth > 0 || token != ')')) {
                if (token == ')') depth--;
                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
                if (token == '(') depth++;
            }
			
            if (token <= 0) {
                StoreStr("EOF in Macro ");
                StoreStr(GetStringOfAtom(atable,atom));
                message=GetStrfromTStr();
                CPPShInfoLogMsg(message);
                ResetTString();
                return 1;
            }
            StoreStr("Too many args in Macro ");
            StoreStr(GetStringOfAtom(atable,atom));
            message=GetStrfromTStr();
            CPPShInfoLogMsg(message);
            ResetTString();
		}
		for (i=0; i<in->mac->argc; i++) {
            in->args[i] = PrescanMacroArg(in->args[i], yylvalpp);
        }
    }
#if 0
    printf("  <%s:%d>found macro %s\n", GetAtomString(atable, loc.file),
           loc.line, GetAtomString(atable, atom));
    for (i=0; i<in->mac->argc; i++) {
        printf("\targ %s = '", GetAtomString(atable, in->mac->args[i]));
        DumpTokenStream(stdout, in->args[i]);
        printf("'\n");
    }
#endif
	/*retain the input source*/
    in->base.prev = cpp->currentInput;
    sym->details.mac.busy = 1;
    RewindTokenStream(sym->details.mac.body);
    cpp->currentInput = &in->base;
    return 1;
} // MacroExpand
Beispiel #25
0
/* "within_struct_flag" is TRUE if the enclosing format is "{...}" */
static FORMAT_PTR Parse(Format_Parse_Ptr parser, int32 within_struct_flag,
			BOOLEAN *error)
{ 
  TokenPtr Token;
  FORMAT_PTR ReturnForm=NULL;
  
  Token = NextToken(parser);
  
  switch(Token->Type) {
  case LBRACE_TOK:
    Token = NextToken(parser);
    if (Token->Type == STR_TOK && !strcmp(Token->value.str, "enum")) {
      ReturnForm = Enum_Format(parser, error);
    } else {
      UngetToken(parser, Token);
      ReturnForm = Struct_Format(parser, error);
    }
    Token = NextToken(parser);
    if (Token->Type != RBRACE_TOK) {
      ParserError(Token, parser, "'}'");
      *error = TRUE;
      return NULL;
    }
    break;
  case LBRACK_TOK:
    ReturnForm = Fixed_Array_Format(parser, error);
    break;
  case LT_TOK:
    if (!within_struct_flag) {
      ParserError(Token, parser,
		  "var array format '<..>' not embedded within a structure '{..}'");
      *error = TRUE;
      return NULL;
    } else {
      ReturnForm = Var_Array_Format(parser, error);
    }
    break;
  case STAR_TOK:
    if (parser->TokenList->Type == BANG_TOK) {
      Token = NextToken(parser);	/* eat BANG_TOK */ 
      if (!within_struct_flag) {
	ParserError(Token, parser, 
		    "self pointer '*!' embedded within a structure '{..}'");
	*error = TRUE;
	return NULL;
      } else {
	ReturnForm = SelfPtr_Format();
      }
    }
    else
      ReturnForm = Ptr_Format(parser, error);
    break;
  case INT_TOK:
    ReturnForm = Length_Format(Token);
    break;
  case STR_TOK:
    ReturnForm = Named_Format(parser, Token);
    if (ReturnForm->type == BadFormatFMT) {
      *error = TRUE;
      return NULL;
    }
    break;
  case PRIMITIVE_TOK:
    ReturnForm = Primitive_Format(parser, Token);
    if (ReturnForm->type == BadFormatFMT) {
      *error = TRUE;
      return NULL;
    }
    break;
  case EOS_TOK: 
    ParserError(Token, parser, 
		"additional tokens; premature end of string encountered");
    *error = TRUE;
    return NULL;
    break;

  default:
    ParserError(Token, parser, "a different token type");
    *error = TRUE;
    return NULL;
  }
  
  cacheFormatterAttributes(ReturnForm);

  return ReturnForm;
}
Beispiel #26
0
void PHPSourceFile::ParseFunctionBody()
{
    m_lookBackTokens.clear();

    // when we reach the current depth-1 -> leave
    int exitDepth = m_depth - 1;
    phpLexerToken token;
    PHPEntityBase::Ptr_t var(NULL);
    while(NextToken(token)) {
        switch(token.type) {
        case '{':
            m_lookBackTokens.clear();
            break;
        case '}':
            m_lookBackTokens.clear();
            if(m_depth == exitDepth) {
                return;
            }
            break;
        case ';':
            m_lookBackTokens.clear();
            break;
        case kPHP_T_CATCH:
            OnCatch();
            break;
        case kPHP_T_VARIABLE: {
            var.Reset(new PHPEntityVariable());
            var->SetFullName(token.text);
            var->SetFilename(m_filename.GetFullPath());
            var->SetLine(token.lineNumber);
            CurrentScope()->AddChild(var);

            // Peek at the next token
            if(!NextToken(token)) return; // EOF
            if(token.type != '=') {
                m_lookBackTokens.clear();
                var.Reset(NULL);
                UngetToken(token);

            } else {

                wxString expr;
                if(!ReadExpression(expr)) return; // EOF

                // Optimize 'new ClassName(..)' expression
                if(expr.StartsWith("new")) {
                    expr = expr.Mid(3);
                    expr.Trim().Trim(false);
                    expr = expr.BeforeFirst('(');
                    expr.Trim().Trim(false);
                    var->Cast<PHPEntityVariable>()->SetTypeHint(MakeIdentifierAbsolute(expr));

                } else {
                    // keep the expression
                    var->Cast<PHPEntityVariable>()->SetExpressionHint(expr);
                }
            }
        } break;
        default:
            break;
        }
    }
}
Beispiel #27
0
/* MacroExpand
** Check an identifier (atom) to see if it is a macro that should be expanded.
** If it is, push an InputSrc that will produce the appropriate expansion
** and return 1.
** If it is, but undefined, it should expand to 0, push an InputSrc that will 
** expand to 0 and return -1.
** Otherwise, return 0.
*/
int TPpContext::MacroExpand(int atom, TPpToken* yylvalpp, int expandUndef)
{
    Symbol *sym = LookUpSymbol(macros, atom);
    MacroInputSrc *in;
    int i, j, token;
    int depth = 0;

    if (atom == __LINE__Atom) {
        yylvalpp->ival = parseContext.currentLoc.line;
        sprintf(yylvalpp->name, "%d", yylvalpp->ival);
        UngetToken(CPP_INTCONSTANT, yylvalpp);

        return 1;
    }

    if (atom == __FILE__Atom) {
        yylvalpp->ival = parseContext.currentLoc.string;
        sprintf(yylvalpp->name, "%d", yylvalpp->ival);
        UngetToken(CPP_INTCONSTANT, yylvalpp);

        return 1;
    }

    if (atom == __VERSION__Atom) {
        yylvalpp->ival = parseContext.version;
        sprintf(yylvalpp->name, "%d", yylvalpp->ival);
        UngetToken(CPP_INTCONSTANT, yylvalpp);

        return 1;
    }

    // no recursive expansions
    if (sym && sym->details.mac.busy)
        return 0;

    // not expanding of undefined symbols
    if ((! sym || sym->details.mac.undef) && ! expandUndef)
        return 0;

    in = (MacroInputSrc*)malloc(sizeof(*in));
    memset(in, 0, sizeof(*in));
    in->base.line = currentInput->line;
    in->base.name = currentInput->name;

    if ((! sym || sym->details.mac.undef) && expandUndef) {
        // push input
        in->base.scan = zero_scan;
        in->base.prev = currentInput;
        currentInput = &in->base;

        return -1;
    }

    in->base.scan = macro_scan;
    in->mac = &sym->details.mac;
    if (sym->details.mac.args) {
        token = currentInput->scan(this, currentInput, yylvalpp);
        if (token != '(') {
            UngetToken(token, yylvalpp);
            yylvalpp->atom = atom;

            return 0;
        }
        in->args = (TokenStream**)malloc(in->mac->argc * sizeof(TokenStream *));
        for (i = 0; i < in->mac->argc; i++)
            in->args[i] = NewTokenStream("macro arg", 0);
        i = 0;
        j = 0;
        do {
            depth = 0;
            while (1) {
                token = currentInput->scan(this, currentInput, yylvalpp);
                if (token <= 0) {
                    parseContext.error(yylvalpp->loc, "EOF in macro", "preprocessor", GetStringOfAtom(&atomTable, atom));

                    return 1;
                }
                if ((in->mac->argc==0) && (token!=')')) break;
                if (depth == 0 && (token == ',' || token == ')')) break;
                if (token == '(') depth++;
                if (token == ')') depth--;
                RecordToken(in->args[i], token, yylvalpp);
                j=1;
            }
            if (token == ')') {
                if ((in->mac->argc==1) &&j==0)
                    break;
                i++;
                break;
            }
            i++;
        } while (i < in->mac->argc);

        if (i < in->mac->argc)
            parseContext.error(yylvalpp->loc, "Too few args in Macro", "preprocessor", GetStringOfAtom(&atomTable, atom));
        else if (token != ')') {
            depth=0;
            while (token >= 0 && (depth > 0 || token != ')')) {
                if (token == ')')
                    depth--;
                token = currentInput->scan(this, currentInput, yylvalpp);
                if (token == '(')
                    depth++;
            }

            if (token <= 0) {
                parseContext.error(yylvalpp->loc, "EOF in macro", "preprocessor", GetStringOfAtom(&atomTable, atom));

                return 1;
            }
            parseContext.error(yylvalpp->loc, "Too many args in Macro", "preprocessor", GetStringOfAtom(&atomTable, atom));
        }
        for (i = 0; i<in->mac->argc; i++) {
            in->args[i] = PrescanMacroArg(in->args[i], yylvalpp);
        }
    }
#if 0
    printf("  <%s:%d>found macro %s\n", GetAtomString(atable, loc.file),
        loc.line, GetAtomString(atable, atom));
    for (i = 0; i<in->mac->argc; i++) {
        printf("\targ %s = '", GetAtomString(atable, in->mac->args[i]));
        DumpTokenStream(stdout, in->args[i]);
        printf("'\n");
    }
#endif
    /*retain the input source*/
    in->base.prev = currentInput;
    sym->details.mac.busy = 1;
    RewindTokenStream(sym->details.mac.body);
    currentInput = &in->base;

    return 1;
} // MacroExpand
Beispiel #28
0
void PHPSourceFile::Parse(int exitDepth)
{
    int retDepth = exitDepth;
    phpLexerToken token;
    while(NextToken(token)) {
        switch(token.type) {
        case '=':
            m_lookBackTokens.clear();
            break;
        case '{':
            m_lookBackTokens.clear();
            break;
        case '}':
            m_lookBackTokens.clear();
            if(m_depth == retDepth) {
                return;
            }
            break;
        case ';':
            m_lookBackTokens.clear();
            break;
        case kPHP_T_VARIABLE:
            if(!CurrentScope()->Is(kEntityTypeClass)) {
                // A global variable
                OnVariable(token);
            }
            break;
        case kPHP_T_CATCH:
            // found 'catch (...)'
            OnCatch();
            break;
        case kPHP_T_PUBLIC:
        case kPHP_T_PRIVATE:
        case kPHP_T_PROTECTED: {
            int visibility = token.type;
            PHPEntityClass* cls = CurrentScope()->Cast<PHPEntityClass>();
            if(cls) {
                /// keep the current token
                m_lookBackTokens.push_back(token);

                // Now we have a small problem here:
                // public can be a start for a member or a function
                // we let the lexer run forward until it finds kPHP_T_VARIABLE (for variable)
                // or kPHP_T_IDENTIFIER
                int what = ReadUntilFoundOneOf(kPHP_T_VARIABLE, kPHP_T_FUNCTION, token);
                if(what == kPHP_T_VARIABLE) {
                    // A variable
                    PHPEntityBase::Ptr_t member(new PHPEntityVariable());
                    member->SetFilename(m_filename.GetFullPath());
                    member->Cast<PHPEntityVariable>()->SetVisibility(visibility);
                    member->Cast<PHPEntityVariable>()->SetFullName(token.text);
                    size_t flags = LookBackForVariablesFlags();
                    member->Cast<PHPEntityVariable>()->SetFlag(kVar_Member);
                    member->Cast<PHPEntityVariable>()->SetFlag(kVar_Const, flags & kVar_Const);
                    member->Cast<PHPEntityVariable>()->SetFlag(kVar_Static, flags & kVar_Static);
                    member->Cast<PHPEntityVariable>()->SetLine(token.lineNumber);
                    CurrentScope()->AddChild(member);

                    // Handle member assignment
                    // public $memberVar = new Something();
                    // for such cases, assign $memberVar type of Something()
                    phpLexerToken t;
                    if(!NextToken(t)) {
                        // EOF
                        return;
                    }

                    if(t.type == '=') {
                        // assignment
                        wxString expr;
                        if(!ReadExpression(expr)) {
                            return;
                        }

                        // Optimize 'new ClassName(..)' expression
                        if(expr.StartsWith("new")) {
                            expr = expr.Mid(3);
                            expr.Trim().Trim(false);
                            expr = expr.BeforeFirst('(');
                            expr.Trim().Trim(false);
                            member->Cast<PHPEntityVariable>()->SetTypeHint(MakeIdentifierAbsolute(expr));

                        } else {
                            // keep the expression
                            member->Cast<PHPEntityVariable>()->SetExpressionHint(expr);
                        }

                    } else {
                        // restore the token
                        UngetToken(t);
                        if(!ConsumeUntil(';')) return;
                    }

                } else if(what == kPHP_T_FUNCTION) {
                    // A function...
                    OnFunction();
                    m_lookBackTokens.clear();
                }
            }
            break;
        }
        case kPHP_T_DEFINE:
            // Define statement
            OnDefine(token);
            break;
        case kPHP_T_CONST:
            OnConstant(token);
            break;
        case kPHP_T_REQUIRE:
        case kPHP_T_REQUIRE_ONCE:
        case kPHP_T_INCLUDE:
        case kPHP_T_INCLUDE_ONCE:
            // Handle include files
            m_lookBackTokens.clear();
            break;
        case kPHP_T_FOREACH:
            // found "foreach" statement
            OnForEach();
            m_lookBackTokens.clear();
            break;
        case kPHP_T_USE:
            // Found outer 'use' statement - construct the alias table
            if(Class()) {
                // inside a class, this means that this is a 'use <trait>;'
                OnUseTrait();
            } else {
                // alias table
                OnUse();
            }
            m_lookBackTokens.clear();
            break;
        case kPHP_T_CLASS:
        case kPHP_T_INTERFACE:
        case kPHP_T_TRAIT:
            // Found class
            OnClass(token);
            m_lookBackTokens.clear();
            break;
        case kPHP_T_NAMESPACE:
            // Found a namespace
            OnNamespace();
            m_lookBackTokens.clear();
            break;
        case kPHP_T_FUNCTION:
            // Found function
            OnFunction();
            m_lookBackTokens.clear();
            break;
        default:
            // Keep the token
            break;
        }
    }
    PhaseTwo();
}
Beispiel #29
0
/*
** Check an identifier (atom) to see if it is a macro that should be expanded.
** If it is, push an InputSrc that will produce the appropriate expansion
** and return 1.
** If it is, but undefined, it should expand to 0, push an InputSrc that will 
** expand to 0 and return -1.
** Otherwise, return 0.
*/
int TPpContext::MacroExpand(int atom, TPpToken* ppToken, int expandUndef)
{
    Symbol *sym = LookUpSymbol(atom);
    MacroInputSrc *in;
    int token;
    int depth = 0;

    if (atom == __LINE__Atom) {
        ppToken->ival = parseContext.getCurrentLoc().line;
        sprintf(ppToken->name, "%d", ppToken->ival);
        UngetToken(CPP_INTCONSTANT, ppToken);

        return 1;
    }

    if (atom == __FILE__Atom) {
        ppToken->ival = parseContext.getCurrentLoc().string;
        sprintf(ppToken->name, "%d", ppToken->ival);
        UngetToken(CPP_INTCONSTANT, ppToken);

        return 1;
    }

    if (atom == __VERSION__Atom) {
        ppToken->ival = parseContext.version;
        sprintf(ppToken->name, "%d", ppToken->ival);
        UngetToken(CPP_INTCONSTANT, ppToken);

        return 1;
    }

    // no recursive expansions
    if (sym && sym->mac.busy)
        return 0;

    // not expanding of undefined symbols
    if ((! sym || sym->mac.undef) && ! expandUndef)
        return 0;

    in = new MacroInputSrc;

    if ((! sym || sym->mac.undef) && expandUndef) {
        // push input
        in->scan = zero_scan;
        in->prev = currentInput;
        currentInput = in;

        return -1;
    }

    TSourceLoc loc = ppToken->loc;  // in case we go to the next line before discovering the error
    in->scan = macro_scan;
    in->mac = &sym->mac;
    if (sym->mac.args) {
        token = currentInput->scan(this, currentInput, ppToken);
        if (token != '(') {
            UngetToken(token, ppToken);
            ppToken->atom = atom;

            return 0;
        }
        in->args.resize(in->mac->argc);
        for (int i = 0; i < in->mac->argc; i++)
            in->args[i] = new TokenStream;
        int arg = 0;
        bool tokenRecorded = false;
        do {
            depth = 0;
            while (1) {
                token = currentInput->scan(this, currentInput, ppToken);
                if (token <= 0) {
                    parseContext.error(loc, "EOF in macro", "macro expansion", GetAtomString(atom));
                    return 1;
                }
                if (token == '\n') {
                    // TODO: Preprocessor functionality:  Correctly handle new line and escaped new line, for expansions that are both in and not in another preprocessor directive

                    //if (in a pp line) {
                    //    parseContext.error(loc, "missing ')':", "macro expansion", GetAtomString(atom));
                    //    return 1;
                    //}
                    continue;
                }
                if (token == '#') {
                    parseContext.error(ppToken->loc, "unexpected '#'", "macro expansion", GetAtomString(atom));
                    return 1;
                }
                if (in->mac->argc == 0 && token != ')')
                    break;
                if (depth == 0 && (token == ',' || token == ')'))
                    break;
                if (token == '(')
                    depth++;
                if (token == ')')
                    depth--;
                RecordToken(in->args[arg], token, ppToken);
                tokenRecorded = true;
            }
            if (token == ')') {
                if (in->mac->argc == 1 && tokenRecorded == 0)
                    break;
                arg++;
                break;
            }
            arg++;
        } while (arg < in->mac->argc);

        if (arg < in->mac->argc)
            parseContext.error(loc, "Too few args in Macro", "macro expansion", GetAtomString(atom));
        else if (token != ')') {
            depth=0;
            while (token >= 0 && (depth > 0 || token != ')')) {
                if (token == ')')
                    depth--;
                token = currentInput->scan(this, currentInput, ppToken);
                if (token == '(')
                    depth++;
            }

            if (token <= 0) {
                parseContext.error(loc, "EOF in macro", "macro expansion", GetAtomString(atom));
                return 1;
            }
            parseContext.error(loc, "Too many args in macro", "macro expansion", GetAtomString(atom));
        }
        for (int i = 0; i < in->mac->argc; i++)
            in->args[i] = PrescanMacroArg(in->args[i], ppToken);
    }

    /*retain the input source*/
    in->prev = currentInput;
    sym->mac.busy = 1;
    RewindTokenStream(sym->mac.body);
    currentInput = in;

    return 1;
}
Beispiel #30
0
//
// =======================================================================================================================
//    Map_ImportFile Timo 09/01/99:: called by CXYWnd::Paste & Map_ImportFile if Map_ImportFile ( prefab ), the buffer
//    may contain brushes in old format ( conversion needed )
// =======================================================================================================================
//
void Map_ImportBuffer(char *buf, bool renameEntities) {
	entity_t	*ent;
	brush_t		*b = NULL;
	CPtrArray	ptrs;

	Select_Deselect();

	Undo_Start("import buffer");

	g_qeglobals.d_parsed_brushes = 0;
	if (buf) {
		CMapStringToString	mapStr;
		StartTokenParsing(buf);
		g_qeglobals.d_num_entities = 0;

		//
		// Timo will be used in Entity_Parse to detect if a conversion between brush
		// formats is needed
		//
		g_qeglobals.bNeedConvert = false;
		g_qeglobals.bOldBrushes = false;
		g_qeglobals.bPrimitBrushes = false;
		g_qeglobals.mapVersion = 1.0;

		if (GetToken(true)) {
			if (stricmp(token, "Version") == 0) {
				GetToken(false);
				g_qeglobals.mapVersion = atof(token);
				common->Printf("Map version: %1.2f\n", g_qeglobals.mapVersion);
			} else {
				UngetToken();
			}
		}

		idDict RemappedNames;	// since I can't use "map <string, string>"... sigh. So much for STL...

		while (1) {
			//
			// use the selected brushes list as it's handy ent = Entity_Parse (false,
			// &selected_brushes);
			//
			ent = Entity_Parse(false, &active_brushes);
			if (!ent) {
				break;
			}

			// end entity for undo
			Undo_EndEntity(ent);

			// end brushes for undo
			for (b = ent->brushes.onext; b && b != &ent->brushes; b = b->onext) {
				Undo_EndBrush(b);
			}

			if (!strcmp(ValueForKey(ent, "classname"), "worldspawn")) {
				// world brushes need to be added to the current world entity
				b = ent->brushes.onext;
				while (b && b != &ent->brushes) {
					brush_t *bNext = b->onext;
					Entity_UnlinkBrush(b);
					Entity_LinkBrush(world_entity, b);
					ptrs.Add(b);
					b = bNext;
				}
			}
			else {
				// the following bit remaps conflicting target/targetname key/value pairs
				CString str = ValueForKey(ent, "target");
				CString strKey;
				CString strTarget("");
				if (str.GetLength() > 0) {
					if (FindEntity("target", str.GetBuffer(0))) {
						if (!mapStr.Lookup(str, strKey)) {
							idStr key;
							UniqueTargetName(key);
							strKey = key;
							mapStr.SetAt(str, strKey);
						}

						strTarget = strKey;
						SetKeyValue(ent, "target", strTarget.GetBuffer(0));
					}
				}

				/*
				 * str = ValueForKey(ent, "name"); if (str.GetLength() > 0) { if
				 * (FindEntity("name", str.GetBuffer(0))) { if (!mapStr.Lookup(str, strKey)) {
				 * UniqueTargetName(strKey); mapStr.SetAt(str, strKey); } Entity_SetName(ent,
				 * strKey.GetBuffer(0)); } }
				 */
				CString cstrNameOld = ValueForKey(ent, "name");
				Entity_Name(ent, renameEntities);
				CString cstrNameNew = ValueForKey(ent, "name");
				if (cstrNameOld != cstrNameNew)
				{
					RemappedNames.Set(cstrNameOld, cstrNameNew);
				}
				//
				// if (strTarget.GetLength() > 0) SetKeyValue(ent, "target",
				// strTarget.GetBuffer(0));
				// add the entity to the end of the entity list
				//
				ent->next = &entities;
				ent->prev = entities.prev;
				entities.prev->next = ent;
				entities.prev = ent;
				g_qeglobals.d_num_entities++;

				for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) {
					ptrs.Add(b);
				}
			}
		}

		// now iterate through the remapped names, and see if there are any target-connections that need remaking...
		//
		// (I could probably write this in half the size with STL, but WTF, work with what we have...)
		//
		int iNumKeyVals = RemappedNames.GetNumKeyVals();
		for (int iKeyVal=0; iKeyVal < iNumKeyVals; iKeyVal++)
		{
			const idKeyValue *pKeyVal = RemappedNames.GetKeyVal( iKeyVal );

			LPCSTR psOldName = pKeyVal->GetKey().c_str();
			LPCSTR psNewName = pKeyVal->GetValue().c_str();

			entity_t *pEntOld = FindEntity("name", psOldName);	// original ent we cloned from
			entity_t *pEntNew = FindEntity("name", psNewName);	// cloned ent

			if (pEntOld && pEntNew)
			{
				CString cstrTargetNameOld = ValueForKey(pEntOld, "target");
				if (!cstrTargetNameOld.IsEmpty())
				{
					// ok, this ent was targeted at another ent, so it's clone needs updating to point to
					//	the clone of that target, so...
					//
					entity_t *pEntOldTarget = FindEntity("name", cstrTargetNameOld);
					if ( pEntOldTarget )
					{
						LPCSTR psNewTargetName = RemappedNames.GetString( cstrTargetNameOld );
						if (psNewTargetName && psNewTargetName[0])
						{
							SetKeyValue(pEntNew, "target", psNewTargetName);
						}
					}
				}
			}
		}
	}

	//
	// ::ShowWindow(g_qeglobals.d_hwndEntity, FALSE);
	// ::LockWindowUpdate(g_qeglobals.d_hwndEntity);
	//
	g_bScreenUpdates = false;
	for (int i = 0; i < ptrs.GetSize(); i++) {
		Brush_Build(reinterpret_cast < brush_t * > (ptrs[i]), true, false);
		Select_Brush(reinterpret_cast < brush_t * > (ptrs[i]), true, false);
	}

	// ::LockWindowUpdate(NULL);
	g_bScreenUpdates = true;

	ptrs.RemoveAll();

	//
	// reset the "need conversion" flag conversion to the good format done in
	// Map_BuildBrushData
	//
	g_qeglobals.bNeedConvert = false;

	Sys_UpdateWindows(W_ALL);

	// Sys_MarkMapModified();
	mapModified = 1;

	Undo_End();
}