Example #1
0
bool ParseFunctionCall(FunctionEvent *FnEvent, CallExpr *Call,
                       vector<ValueDecl*>& References,
                       ASTContext& Ctx) {
#ifndef NDEBUG
  auto Predicate = Call->getDirectCallee();
  assert(Predicate != NULL);
  assert(Predicate->getName() == "__tesla_call");
#endif

  if (Call->getNumArgs() != 1) {
    Report("TESLA predicate should have one (boolean) argument",
        Call->getLocStart(), Ctx)
      << Call->getSourceRange();
    return false;
  }

  auto Bop = dyn_cast<BinaryOperator>(Call->getArg(0)->IgnoreImplicit());
  if (!Bop || (Bop->getOpcode() != BO_EQ)) {
    Report("A TESLA predicate should be of the form foo(x) == y",
        Call->getLocStart(), Ctx)
      << Call->getSourceRange();
    return false;
  }

  return ParseFunctionCall(FnEvent, Bop, References, Ctx);
}
Example #2
0
		bool PassParser::Parse(Lexer* lexer, const boost::filesystem::path& dir)
		{
			m_rootDir = dir;

			Token token = lexer->CurToken();

			if(token.type != Token::token_id)
			{
				Error(token.line, "unexpected token: '" + token.str + "'");
				return false;
			}

			m_name = token.str;

			if(FindSymbol(m_name, true) != nullptr)
			{
				Error(token.line, "object '" + m_name + "' already defined.");
				return false;
			}

			token = lexer->NextToken();

			if(token.str != "{")
			{
				Error(token.line, "unexpected token: '" + token.str + "'");
				return false;
			}

			token = lexer->NextToken();

			while(true)
			{
				if(ParseFunctionCall(lexer) == false)
				{
					return false;
				}

				if(lexer->CurToken().str == "}")
				{
					break;
				}
			}

			token = lexer->NextToken();
			if(token.str == ";")
			{
				lexer->SkipToken(token);
			}

			return true;
		}
Expresion* Sintactico::ParseFactor()
{
	
	if ( proximo_token.GetTipo() == punt_parentizq )
	{
		proximo_token = analizador_lexico->ObtenerSiguienteToken();
		Expresion* expr = ParseExpression();

		if ( proximo_token.GetTipo() == punt_parentder )
		{
			proximo_token = analizador_lexico->ObtenerSiguienteToken();
		}
		else
			throw SyntaxException("Falta un parentesis derecho: produccion Factor",analizador_lexico->GetLineaActual());

		return expr;
	}
	else if ( proximo_token.GetTipo() == lit_int || proximo_token.GetTipo() == lit_float || proximo_token.GetTipo() == lit_string || proximo_token.GetTipo() == lit_boolean || proximo_token.GetTipo() == lit_caracter )
	{
		return ParseLiteralConstant();
	}
	else if ( proximo_token.GetTipo() == op_suma || proximo_token.GetTipo() == op_resta || proximo_token.GetTipo() == kw_not )
	{
		//Utilizamos Primeros ( unary-expression )
		return ParseUnaryExpression();
	}
	else if ( proximo_token.GetTipo() == id )
	{
		string identificador = proximo_token.GetLexema();

		proximo_token = analizador_lexico->ObtenerSiguienteToken();

		if ( proximo_token.GetTipo() == punt_parentizq )
		{

			list<Expresion*>args = ParseFunctionCall();
			FunctionCall* func = new FunctionCall(identificador,args);
			return func;

		}
		else
		{
			 list<Qualifier*> qualifier_list = ParseQualifiers();
			 Identificador* id = new Identificador(identificador,qualifier_list);
			 return id;
		}
	}
	else
		throw SyntaxException("No se encontro un token correcto...factor",analizador_lexico->GetLineaActual() );
}
Example #4
0
AST* ParseObject(ParserState* parser) {
	if(parser->currentToken.type == TOKEN_OBJECT) {
		Match(parser, TOKEN_OBJECT);

		return CreateASTNode(SEM_OBJECT, VALUE_EMPTY);
	} else {
		Match(parser, TOKEN_NEW);

		AST* constructor_call = ParseFunctionCall(parser);

		AST* ast = CreateASTNode(SEM_NEW, VALUE_EMPTY);
		AddASTChild(ast, constructor_call);

		return ast;
	}
}
Example #5
0
AST* ParseValue(ParserState* parser) {
	AST* node;
	if(parser->currentToken.type == TOKEN_NUMBER || parser->currentToken.type == TOKEN_STRING) {
		node =  CreateASTNode(SEM_CONSTANT, parser->currentToken.value);
		Match(parser, parser->currentToken.type);
	} else {
		if(parser->nextToken.type == TOKEN_LEFTBRACKET)
			return ParseFunctionCall(parser);

		Value *id = Match(parser, TOKEN_ID);

		/* XXX: Factor this out */
		if(parser->currentToken.type == TOKEN_LEFT_SQUARE_BRACKET) {
			Match(parser, TOKEN_LEFT_SQUARE_BRACKET);
			AST* size = ParseExpression(parser);
			Match(parser, TOKEN_RIGHT_SQUARE_BRACKET);

			node = CreateASTNode(SEM_INDEX,  id);
			AddASTChild(node, size);
		} else if(parser->currentToken.type == TOKEN_DOT) { 
			Match(parser, TOKEN_DOT);
			Value* field_name = Match(parser, TOKEN_FIELD);
			if(parser->currentToken.type == TOKEN_LEFTBRACKET) {
				node = CreateASTNode(SEM_METHOD_CALL, VALUE_EMPTY);

				AST* field_node = CreateASTNode(SEM_FIELD, id);
				AddASTChild(field_node, CreateASTNode(SEM_CONSTANT, field_name));

				AddASTChild(node, field_node);

				Match(parser, TOKEN_LEFTBRACKET);
				AddASTChild(node, ParseArgumentList(parser)); Match(parser, TOKEN_RIGHTBRACKET); } else {
				node = CreateASTNode(SEM_FIELD, id);
				AddASTChild(node, CreateASTNode(SEM_CONSTANT, field_name));
			}
		} else {
			node =  CreateASTNode(SEM_ID, id);
		}
	}

	return node;
}
asCScriptNode *asCParser::ParseExprPostOp()
{
	asCScriptNode *node = new asCScriptNode(snExprPostOp);

	sToken t;
	GetToken(&t);
	if( !IsPostOperator(t.type) )
	{
		Error(TXT_EXPECTED_POST_OPERATOR, &t);
		return node;
	}

	node->SetToken(&t);
	node->UpdateSourcePos(t.pos, t.length);

	if( t.type == ttDot )
	{
		sToken t1, t2;
		GetToken(&t1);
		GetToken(&t2);
		RewindTo(&t1);
		if( t2.type == ttOpenParanthesis )
			node->AddChildLast(ParseFunctionCall());
		else
			node->AddChildLast(ParseIdentifier());
	}
	else if( t.type == ttOpenBracket )
	{
		node->AddChildLast(ParseAssignment());

		GetToken(&t);
		if( t.type != ttCloseBracket )
		{
			ExpectedToken("]");
			return node;
		}

		node->UpdateSourcePos(t.pos, t.length);
	}

	return node;
}
Example #7
0
AST* ParseOperator(ParserState* parser) {
	AST* ast;
	switch(parser->currentToken.type) {
		case TOKEN_BEGIN:
			return ParseBlock(parser);
		case TOKEN_ID:
			ast = parser->nextToken.type == TOKEN_LEFTBRACKET ? ParseFunctionCall(parser) : ParseAssignment(parser);
			Match(parser, TOKEN_SEMICOLON);
			return ast;
		case TOKEN_LOCAL:
			ast = ParseAssignment(parser);
			Match(parser, TOKEN_SEMICOLON);
			return ast;
		case TOKEN_WHILE:
			return ParseWhileCycle(parser);
		case TOKEN_IF:
			return ParseIfStatement(parser);
		case TOKEN_FUNCTION:
			return ParseFunctionDefinition(parser);
		case TOKEN_RETURN:
			ast = ParseReturn(parser);
			Match(parser, TOKEN_SEMICOLON);
			return ast;
		case TOKEN_PRINT:
			ast =  ParsePrint(parser);
			Match(parser, TOKEN_SEMICOLON);
			return ast;
		case TOKEN_INCLUDE:
			return ParseInclude(parser);
		case TOKEN_LOAD:
			ast = ParseLoad(parser);
			Match(parser, TOKEN_SEMICOLON);
			return ast; /** TODO: Factor common parts out of switch */
	}

	FailWithUnexpectedToken(parser, parser->currentToken.type, TOKEN_ID);

	return NULL;
}
asCScriptNode *asCParser::ParseExprValue()
{
	asCScriptNode *node = new asCScriptNode(snExprValue);

	sToken t1;
	GetToken(&t1);
	RewindTo(&t1);

	if( t1.type == ttIdentifier || IsRealType(t1.type) )
	{
		if( IsFunctionCall() )
			node->AddChildLast(ParseFunctionCall());
		else
			node->AddChildLast(ParseIdentifier());
	}
	else if( t1.type == ttCast )
		node->AddChildLast(ParseCast());
	else if( IsConstant(t1.type) )
		node->AddChildLast(ParseConstant());
	else if( t1.type == ttOpenParanthesis )
	{
		GetToken(&t1);
		node->UpdateSourcePos(t1.pos, t1.length);

		node->AddChildLast(ParseAssignment());
		if( isSyntaxError ) return node;

		GetToken(&t1);
		if( t1.type != ttCloseParanthesis )
			Error(ExpectedToken(")").AddressOf(), &t1);

		node->UpdateSourcePos(t1.pos, t1.length);
	}
	else
		Error(TXT_EXPECTED_EXPRESSION_VALUE, &t1);

	return node;
}
Example #9
0
/*
==============
Expression
==============
*/
def_t *Compiler::Expression( int priority )
{
	opcode_t	*op;
	opcode_t	*oldop;
	def_t		*e;
	def_t		*e2;
	etype_t	type_a;
	etype_t	type_b;
	char		*name;
	
	if ( priority == 0 )
	{
		return Term();
	}
	
	e = Expression( priority - 1 );
	
	while( 1 )
	   {
		if ( priority == FUNCTION_PRIORITY )
		{
			if ( lex.Check( "(" ) )
            {
				return ParseFunctionCall( e );
            }
			else if ( ( ( e->type->type == ev_entity ) || 
				( ( e->type->type == ev_void ) && ( e->ofs < OFS_END ) ) ) && 
				( lex.Check( "." ) ) )
            {
				if ( lex.pr_token_type != tt_name )
				{
					lex.ParseError( "Expecting function call" );
				}
				
				name = lex.ParseName();
				
				// look through the defs
				e2 = program.GetDef( NULL, name, pr_scope, false, &lex );
				if ( !e2 )
				{
					lex.ParseError( "Unknown value \"%s\"", name );
				}
				else if ( e2->type->type != ev_function )
				{
					lex.ParseError( "\"%s\" is not a valid function name", name );
				}
				
				return ParseObjectCall( e2, e );
            }
			
			//else if ( lex.Check( ";" ) )
			//{
			//	lex.ParseError( "Invalid command - %s", e->name.c_str() );
			//}
		}
		
		for( op = pr_opcodes; op->name; op++ )
		{
			if ( op->priority != priority )
            {
				continue;
            }
			
			if ( !lex.Check( op->name ) )
            {
				continue;
            }
			
			if ( op->type_b == &def_void )
            {
				e = Statement( op, e, 0 );
				return e;
            }
			
			if ( op->right_associative )
			{
				e2 = Expression( priority );
			}
			else
            {
				e2 = Expression( priority - 1 );
            }
			
			// type check
			type_a = e->type->type;
			type_b = e2->type->type;
			
			oldop = op;
			while( ( type_a != op->type_a->type->type ) ||
				( type_b != op->type_b->type->type ) )
			{
				op++;
				if ( !op->name || strcmp( op->name, oldop->name ) )
				{
					lex.ParseError( "type mismatch for %s", oldop->name );
				}
			}
			
			if ( op->right_associative )
            {
				e = Statement( op, e2, e );
            }
			else
            {
				e = Statement( op, e, e2 );
            }
			break;
		}
		
		if ( !op->name )
		{
			// next token isn't at this priority level
			break;
		}
	}
	
	return e;
}
Example #10
0
bool ParseEvent(Event *Ev, Expr *E, Assertion *A,
                vector<ValueDecl*>& References, ASTContext& Ctx) {

  E = E->IgnoreImplicit();

  if (auto Ref = dyn_cast<DeclRefExpr>(E)) {
    auto D = Ref->getDecl();
    assert(D);

    // The __tesla_ignore "event" helps TESLA assertions look like ISO C.
    if (D->getName() == "__tesla_ignore") {
      Ev->set_type(Event::IGNORE);
      return true;
    }

    // The only other static __tesla_event is the "now" event.
    if (D->getName() != "__tesla_now") {
      Report("TESLA static reference must be __tesla_ignore or __tesla_now",
             E->getLocStart(), Ctx)
        << E->getSourceRange();
      return false;
    }

    Ev->set_type(Event::NOW);
    *Ev->mutable_now()->mutable_location() = A->location();
    return true;
  } else if (auto Bop = dyn_cast<BinaryOperator>(E)) {
    // This is a call-and-return like "foo(x) == y".
    Ev->set_type(Event::FUNCTION);
    return ParseFunctionCall(Ev->mutable_function(), Bop, References, Ctx);
  }

  // Otherwise, it's a call to a TESLA "function" like __tesla_predicate().
  auto Call = dyn_cast<CallExpr>(E);
  if (!Call) {
    Report("Event should look like a function call", E->getLocStart(), Ctx)
      << E->getSourceRange();
    return false;
  }

  auto Callee = Call->getDirectCallee();
  if (!Callee) {
    Report("TESLA event referenced indirectly", Call->getLocStart(), Ctx)
      << Call->getSourceRange();
    return false;
  }

  if (Callee->getName() == "__tesla_repeat") {
    Ev->set_type(Event::REPETITION);
    return ParseRepetition(Ev->mutable_repetition(), Call, A, References, Ctx);
  }

  typedef bool (*FnEventParser)(FunctionEvent*, CallExpr*, vector<ValueDecl*>&,
                                ASTContext&);

  FnEventParser Parser = llvm::StringSwitch<FnEventParser>(Callee->getName())
    .Case("__tesla_entered", &ParseFunctionEntry)
    .Case("__tesla_leaving", &ParseFunctionExit)
    .Case("__tesla_call",    &ParseFunctionCall)
    .Default(NULL);

  if (!Parser) {
    Report("Unknown TESLA event", E->getLocStart(), Ctx)
      << E->getSourceRange();
    return false;
  }

  Ev->set_type(Event::FUNCTION);
  return Parser(Ev->mutable_function(), Call, References, Ctx);
}