Beispiel #1
0
instruction_ptr Parser::parse_assignment()
{
    int start_line = current_lexeme().line();
    
    if (!match_current_lexeme(kId))
        return instruction_ptr();
    
    string name = current_lexeme().value();
    
    next_lexeme();
    
    if (!match_current_lexeme(kAssignment))
        return instruction_ptr();
    
    next_lexeme();
    
    instruction_ptr expression = parse_expression();
    
    if (!expression)
    {
        report_current_syntax_error();
        return instruction_ptr();
    }
    
    return instruction_ptr(new AssignmentInstruction(start_line, name, expression));
}
Beispiel #2
0
instruction_ptr Parser::parse_function_call()
{
    int start_line = current_lexeme().line();
    
    if (!match_current_lexeme(kId))
        return instruction_ptr();
    
    string name = current_lexeme().value();
    
    next_lexeme();
    
    if (!match_current_lexeme(kLeftBracket))
        return instruction_ptr(new Variable(start_line, name));
    
    next_lexeme();
    
    instructions parameters;
    if (!match_current_lexeme(kRightBracket))
    {
        while (true)
        {
            instruction_ptr parameter = parse_expression();
            if (!parameter)
            {
                report_current_syntax_error();
                {
                    report_current_syntax_error();
                    return instruction_ptr();
                }
            }
            
            parameters.push_back(parameter);
            if (!match_current_lexeme(kComma))
                break;
            else
                next_lexeme();
        }
        
        if (!match_current_lexeme(kRightBracket))
        {
            report_current_syntax_error();
            {
                report_current_syntax_error();
                return instruction_ptr();
            }
        }
    }
    
    next_lexeme();
    
    return instruction_ptr(new FunctionCallInstruction(start_line, name, parameters));
}
Beispiel #3
0
instruction_ptr Parser::parse_constant()
{
    int start_line = current_lexeme().line();
    
    if (!match_current_lexeme(kNumber))
        return instruction_ptr();
    
    string value = current_lexeme().value();
    
    next_lexeme();
    
    return instruction_ptr(new Constant(start_line, parse_number(value)));
}
Beispiel #4
0
instruction_ptr Parser::parse_condition()
{
    int start_line = current_lexeme().line();
    
    instruction_ptr left = parse_expression();
    
    if (!left)
    {
        report_current_syntax_error();
        return instruction_ptr();
    }
    
    if (!match_lexeme_logic(current_lexeme()))
    {
        report_current_syntax_error();
        return instruction_ptr();
    }
    
    Lexeme lexeme = current_lexeme();
    
    next_lexeme();
    
    instruction_ptr right = parse_expression();
    
    if (!right)
    {
        report_current_syntax_error();
        return instruction_ptr();
    }
    
    switch (lexeme.type())
    {
        case kEqualOperation:
            return instruction_ptr(new ConditionalInstruction(start_line, kEqual, left, right));
        case kNotEqualOperation:
            return instruction_ptr(new ConditionalInstruction(start_line, kNotEqual, left, right));
        case kLessOperation:
            return instruction_ptr(new ConditionalInstruction(start_line, kLess, left, right));
        case kGreaterOperation:
            return instruction_ptr(new ConditionalInstruction(start_line, kGreater, left, right));
        case kLessEqualOperation:
            return instruction_ptr(new ConditionalInstruction(start_line, kLessEqual, left, right));
        case kGreaterEqualOperation:
            return instruction_ptr(new ConditionalInstruction(start_line, kGreaterEqual, left, right));
        default:
        {
            report_current_syntax_error();
            return instruction_ptr();
        }
    }
}
Beispiel #5
0
program_ptr Parser::parse_program()
{
    int start_line = current_lexeme().line();
    instructions program_body;
    instructions functions;
    instruction_ptr instruction = instruction_ptr();
    
    while (match_current_lexeme(kEndofLine))
        next_line();
    
    while (!finished() && ErrorHandler::is_ok())
    {
        instruction = instruction_ptr();
        
        instruction = parse_function_definition();
        
        if (instruction)
        {
            functions.push_back(instruction);
            continue;
        }
        
        instruction = parse_instruction();
        
        if (!instruction)
        {
            report_current_syntax_error();
            return program_ptr();
        }
        
        program_body.push_back(instruction);
    }
    
    return program_ptr(new Program(start_line, program_body, functions));
}
Beispiel #6
0
Lexeme const& Parser::next_lexeme()
{
    if (!finished())
        return m_lexemes[++m_current_lexeme_index];
    
    return current_lexeme();
}
Beispiel #7
0
instruction_ptr Parser::parse_expression()
{
    int start_line = current_lexeme().line();
    
    instruction_ptr left = parse_term();
    
    if (!left)
        return instruction_ptr();
    
    while (match_current_lexeme_simple_arithmetic())
    {
        Lexeme lexeme = current_lexeme();
        
        next_lexeme();
        
        instruction_ptr right = parse_term();
        
        if (!right)
        {
            report_current_syntax_error();
            return instruction_ptr();
        }
        
        switch (lexeme.type())
        {
            case kAddition:
                left = instruction_ptr(new ArithmeticOperationInstruction(start_line, kAdd, left, right));
                break;
            case kSubtraction:
                left = instruction_ptr(new ArithmeticOperationInstruction(start_line, kSub, left, right));
                break;
            default:
            {
                report_current_syntax_error();
                return instruction_ptr();
            }
        }
    }
    
    return left;
}
Beispiel #8
0
instruction_ptr Parser::parse_read()
{
    int start_line = current_lexeme().line();
    
    if (!match_current_lexeme(kReadKeyword))
        return instruction_ptr();
    
    next_lexeme();
    
    if (!match_current_lexeme(kId))
    {
        report_current_syntax_error();
        return instruction_ptr();
    }
    
    string name = current_lexeme().value();
    
    next_lexeme();
    
    return instruction_ptr(new ReadInstruction(start_line, name));
}
Beispiel #9
0
instruction_ptr Parser::parse_term()
{
    int start_line = current_lexeme().line();
    
    instruction_ptr left = parse_value();
    
    if (!left)
        return instruction_ptr();
    
    while (match_current_lexeme_complex_arithmetic())
    {
        Lexeme lexeme = current_lexeme();
        
        next_lexeme();
        instruction_ptr right = parse_value();
        if (!right)
        {
            report_current_syntax_error();
            return instruction_ptr();
        }
        
        switch (lexeme.type())
        {
            case kMultiplication:
                left = instruction_ptr(new ArithmeticOperationInstruction(start_line, kMul, left, right));
                break;
            case kDivision:
                left = instruction_ptr(new ArithmeticOperationInstruction(start_line, kDiv, left, right));
                break;
            default:
            {
                report_current_syntax_error();
                return instruction_ptr();
            }
        }
    }
    return left;
}
Beispiel #10
0
instruction_ptr Parser::parse_while_block()
{
    int start_line = current_lexeme().line();
    
    if (!match_current_lexeme(kWhileKeyword))
        return instruction_ptr();
    
    next_lexeme();
    
    instruction_ptr condition = parse_condition();
    
    if(!condition)
    {
        report_current_syntax_error();
        return instruction_ptr();
    }
    
    if(!match_current_lexeme(kColon))
    {
        report_current_syntax_error();
        return instruction_ptr();
    }
    
    next_lexeme();
    
    next_line();
    
    instructions block;
    
    while (!match_current_lexeme(kEndKeyword))
    {
        instruction_ptr instruction = parse_instruction();
        
        if (!instruction)
        {
            report_current_syntax_error();
            return instruction_ptr();
        }
        
        block.push_back(instruction);
    }
    
    next_lexeme();
    return instruction_ptr(new WhileBlock(start_line, block, condition));
}
Beispiel #11
0
instruction_ptr Parser::parse_return()
{
    int start_line = current_lexeme().line();
    
    if (!match_current_lexeme(kReturnKeyword))
        return instruction_ptr();
    
    next_lexeme();
    
    instruction_ptr expression = parse_expression();
    
    if (!expression)
    {
        report_current_syntax_error();
        return instruction_ptr();
    }
    
    return instruction_ptr(new ReturnInstruction(start_line, expression));
}
Beispiel #12
0
char    *factor(void)
{
    char *tempvar=NULL;
    char *temp;
    if( match(ID) )
    {
	/* Print the assignment instruction. The %0.*s conversion is a form of
	 * %X.Ys, where X is the field width and Y is the maximum number of
	 * characters that will be printed (even if the string is longer). I'm
	 * using the %0.*s to print the string because it's not \0 terminated.
	 * The field has a default width of 0, but it will grow the size needed
	 * to print the string. The ".*" tells printf() to take the maximum-
	 * number-of-characters count from the next argument (yyleng).
	 */
        //printf("MOV %0.*s, %s\n",  yyleng, yytext ,tempvar=newname());
        fprintf(f,"MOVB %0.*s, %s \n",  yyleng, yytext ,tempvar=newname());
        temp = current_lexeme();
        add_to_table(temp);
        free(temp);
        advance();
    }
    else if (match(NUM)){
    	//printf("MOV $%0.*s, %s\n",  yyleng, yytext ,tempvar=newname());
        fprintf(f,"MOVB $%0.*s, %s\n",  yyleng, yytext ,tempvar=newname());
        advance();
    }
    else if( match(LP) )
    {
        advance();
        tempvar = expression();
        if( match(RP) )
            advance();
        else
            fprintf(stderr, "%d: Mismatched parenthesis\n", yylineno );
    }
    else
	fprintf( stderr, "%d: Number or identifier expected\n", yylineno );

    return tempvar;
}
Beispiel #13
0
instruction_ptr Parser::parse_value()
{
    int start_line = current_lexeme().line();
    
    if (match_current_lexeme(kSubtraction))
    {
        next_lexeme();
        
        instruction_ptr value = parse_value();
        if (!value)
        {
            report_current_syntax_error();
            return instruction_ptr();
        }
        
        return instruction_ptr(new ArithmeticOperationInstruction(start_line, kSub, instruction_ptr(new Constant(start_line, 0)), value));
    }
    
    if (match_current_lexeme(kLeftBracket))
    {
        next_lexeme();
        instruction_ptr expression = parse_expression();
        
        if (!match_current_lexeme(kRightBracket))
        {
            report_current_syntax_error();
            return instruction_ptr();
        }
        
        next_lexeme();
        
        return expression;
    }
    
    instruction_ptr value = parse_constant();
    if (!value)
        value = parse_function_call();
    
    return value;
}
Beispiel #14
0
statement()
{

    /*  statement -> expression SEMI
     *             |  expression SEMI statement
     */

/*
    expression();

    if( match( SEMI ) )
	advance();
    else
        fprintf( stderr, "%d: Inserting missing semicolon\n", yylineno );

    if( !match(EOI) )   
        statements();			// Do another statement.

*/
    if(match(ID)){
    	char *var1 = current_lexeme(), *var2;
        add_to_table(var1);
        advance();
        if(match(ASSIGN)){  
            advance();
            var2 = expression();
            if(!var2){
            	printf("%d: Expression expected\n", yylineno);
            	return;
            }
            //printf("%s = %s \n", var1,var2);
            //printf("MOV %s,%s\n", var2,var1);
            fprintf(f,"MOVB %s,%s\n", var2,var1);


            freename(var2);
            free(var1);	
        }
        else
            fprintf(stderr, "%d: Not a valid assignment\n",yylineno);
        
    }

    else if(match(IF)){
    	char *var1;
    	if_count++;
    	int temp_if_count = if_count;
        advance();
        var1 = expression();
        if(!var1){
        	fprintf(stderr, "%d: Invalid Expression\n",yylineno);
        	return;
        }
        //printf("CMP %s, $0\n",var1 );
        //printf("JLE Else%d\n",if_count);
        fprintf(f, "MOVB $0, %s \n", ACCUMULATOR);
        fprintf(f,"CMP %s, %s \n",ACCUMULATOR,var1);
        fprintf(f,"JLE Else%d\n",temp_if_count);
        if(match(THEN)){
        	//printf("if(%s){\n", var1);
        	
        	
        	freename(var1);

            advance();
            statement();
            //printf("Else%d:\n",if_count);
            fprintf(f,"Else%d:\n",temp_if_count);
            //printf("}\n");
        }
        else
            fprintf(stderr, "%d: Then expected after if\n", yylineno);
        
    }
    else if(match(WHILE)){
    	char *var;
    	while_count++;
    	int temp_while_count = while_count;
        advance();
        var = expression();
        if(!var){
        	fprintf(stderr, "%d: Invalid Expression\n",yylineno);
        	return;
        }
       // printf("While%d:\n",while_count);
       // printf("CMP %s, $0\n", var);
       // printf("JLE Exit%d\n", while_count);

        fprintf(f, "MOVB $0, %s \n", ACCUMULATOR);
        fprintf(f,"While%d:\n",temp_while_count);
        fprintf(f,"CMP %s, %s\n", ACCUMULATOR,var);
        fprintf(f,"JLE Exit%d\n", temp_while_count);

        if(match(DO)){
        	//printf("while\t(%s)\n", var);
        	//printf("do{\n");

            advance();
            statement();
            //printf("}\n");
            freename(var);
           // printf("JMP While%d\n",while_count);
           // printf("Exit%d:\n",while_count);
            fprintf(f,"JMP While%d\n",temp_while_count);
            fprintf(f,"Exit%d:\n",temp_while_count);
        }
        else
            fprintf(stderr, "%d: Do expected after while\n", yylineno);
    }

    else if(match(BEGIN)){
    	printf("begin\n");
        advance();
        opt_statements();
        if(match(END)){
            printf("end\n");
            advance();
        }
        else 
            fprintf(stderr, "%d End expected begin\n", yylineno);
    }
    
    else if(match(EOI)){
    //	printf("thu\n");
    	return;
    }

    else{
    	fprintf(stderr, "%d: Statement Expected\n", yylineno);
    	exit(1);
    }
    

}
Beispiel #15
0
bool Parser::match_current_lexeme(LexemeTypes type)
{
    return match_lexeme(type, current_lexeme());
}
Beispiel #16
0
bool Parser::match_current_lexeme_logic()
{
    return match_lexeme_logic(current_lexeme());
}
Beispiel #17
0
bool Parser::match_current_lexeme_complex_arithmetic()
{
    return match_lexeme_complex_arithmetic(current_lexeme());
}
Beispiel #18
0
bool Parser::match_lexeme_complex_arithmetic(Lexeme lexeme)
{
    return lexeme.type() == kMultiplication || current_lexeme().type() == kDivision;
}
Beispiel #19
0
instruction_ptr Parser::parse_function_definition()
{
    int start_line = current_lexeme().line();
    if (!match_current_lexeme(kDefKeyword))
        return instruction_ptr();
    
    next_lexeme();
    
    if (!match_current_lexeme(kId))
    {
        report_current_syntax_error();
        return instruction_ptr();
    }
    
    string name = current_lexeme().value();
    
    next_lexeme();
    
    if (!match_current_lexeme(kLeftBracket))
    {
        report_current_syntax_error();
        return instruction_ptr();
    }
    
    next_lexeme();
    
    vector<string> parameters;
    
    if (!match_current_lexeme(kRightBracket))
    {
        while (true)
        {
            if (!match_current_lexeme(kId))
            {
                report_current_syntax_error();
                return instruction_ptr();
            }
            
            parameters.push_back(current_lexeme().value());
            
            next_lexeme();
            
            if (!match_current_lexeme(kComma))
                break;
            
            next_lexeme();
        }
    }
    
    if (!match_current_lexeme(kRightBracket))
    {
        report_current_syntax_error();
        return instruction_ptr();
    }
    
    next_lexeme();
    
    if (!match_current_lexeme(kColon))
    {
        report_current_syntax_error();
        return instruction_ptr();
    }
    
    next_lexeme();
    
    next_line();
    
    instructions function_body;
    
    while (!match_current_lexeme(kEndKeyword))
    {
        instruction_ptr instruction = parse_instruction();
        if (!instruction)
        {
            report_current_syntax_error();
            return instruction_ptr();
        }
        
        function_body.push_back(instruction);
    }
    
    next_lexeme();
    
    next_line();
    
    return instruction_ptr(new Function(start_line, function_body, name, parameters));
}
Beispiel #20
0
bool Parser::match_lexeme_simple_arithmetic(Lexeme lexeme)
{
    return lexeme.type() == kAddition || current_lexeme().type() == kSubtraction;
}
Beispiel #21
0
void Parser::report_current_syntax_error()
{
    ErrorHandler::report_syntax_error(current_lexeme().line());
}