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)); }
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)); }
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))); }
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(); } } }
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)); }
Lexeme const& Parser::next_lexeme() { if (!finished()) return m_lexemes[++m_current_lexeme_index]; return current_lexeme(); }
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; }
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)); }
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; }
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)); }
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)); }
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; }
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; }
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); } }
bool Parser::match_current_lexeme(LexemeTypes type) { return match_lexeme(type, current_lexeme()); }
bool Parser::match_current_lexeme_logic() { return match_lexeme_logic(current_lexeme()); }
bool Parser::match_current_lexeme_complex_arithmetic() { return match_lexeme_complex_arithmetic(current_lexeme()); }
bool Parser::match_lexeme_complex_arithmetic(Lexeme lexeme) { return lexeme.type() == kMultiplication || current_lexeme().type() == kDivision; }
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)); }
bool Parser::match_lexeme_simple_arithmetic(Lexeme lexeme) { return lexeme.type() == kAddition || current_lexeme().type() == kSubtraction; }
void Parser::report_current_syntax_error() { ErrorHandler::report_syntax_error(current_lexeme().line()); }