Lab. 4 四代编译器实验完整版

抓紧时间啦

文件夹下共6个文件。

四代编译器将一种语法类似 C 语言的语句序列翻译为等价的汇编程序,所输出的汇编程序符合 X86 汇编语言格式要求,可以在 Linux 环境下正常运行。词法分析和语法分析部分,可以使用类似 Flex 和 Bison 的工具实现,也可以手工实现。

compilerlab3.cpp(忽略命名,lab3之后没改名)

#include <iostream>
#include "driver.h"
using namespace std;



int main(int argc, char *argv[]){
    // 程序入口,可根据需要修改

	printf(".intel_syntax noprefix\n");

	printf(".global main \n");
	printf(".extern printf\n");
	printf(".data\n");
	printf("format_str:\n");
	printf(".asciz \"%%d\\n\"\n");
	printf(".text\n");
    Driver driver(argv[1]);
    int res = driver.parse();
    return res;
}

driver.h

#ifndef DRIVER_H
#define DRIVER_H
#include <string>
#include<iostream>
// 可以根据需要引入数据结构头文件
#include <map>
#include "parser.hpp"
#include <sstream>
#include <string>
#include <vector>

// 为了让词法分析器能够访问到Driver类,需要在这里声明一下
# define YY_DECL \
  yy::parser::symbol_type yylex (Driver& drv)
YY_DECL;
class Driver
{
public:
    yy::location m_loc;
    // 在这里可以声明一些需要全局使用的变量
    std::map<std::string, int> variables;
    std::map<std::string, int> functionArgsTable;
    std::map<std::string, int> identifierTable;
    int functionArgsCount;
    int identifierCount;
    int ifCount;
    int whileCount;
    int result;
    std::vector<std::string> if_vector;
    std::vector<std::string> while_vector;
    std::vector<std::string> break_vector;
    std::vector<std::string> continue_vector;


// 声明一个外部的字符串缓冲区
    Driver();
    Driver(std::string fileName);
    ~Driver();
    int parse();
    void scan_begin();
    void scan_end();
   



private:
    std::string m_file;
};
#endif

driver.cpp

#include "driver.h"
#include "parser.hpp"
using namespace std;

std::ostringstream buffer;
Driver::Driver(){
}

Driver::Driver(string fileName){
    m_file = fileName;
}



Driver::~Driver(){
}

int Driver::parse(){
    m_loc.initialize(&m_file);
    scan_begin(); // 初始化词法分析器
    yy::parser parser(*this);
    parser.set_debug_level(false);
    int res = parser.parse();

    scan_end();
    return res;
}

parser.y

%skeleton "lalr1.cc"

%defines
%define api.token.constructor
%define api.value.type variant
%define parse.assert

%code requires {
  class Driver;
}

%param { Driver& drv } // 传递一个Driver对象给bison,随后就可以使用对象中的数据成员和方法

%locations

%define parse.trace
%define parse.error verbose


%code {
#include "driver.h"
using namespace std;

int JJ = 0;
int CC = 0;
int FF = 0;
int DD = 0;

extern ostringstream buffer;

int fib(int n) {
	if (n < 2)  return n;
	int dp[n + 1];  
    dp[0] = 0;  
    dp[1] = 1; 
    for (int i = 2; i <= n; i++) {  
        dp[i] = dp[i - 1] + dp[i - 2];  
    }  
	return   dp[n];
}

int jjj(int n){
	int i = 0;
	i = n+2;
	return fib(i);
}

int ccc(int n){
	if (n == 0)
		return 0;
	else {
		return n + ccc(n-1);
	}
}

int jc(int n,int m){
	if (m == 0){
		return ccc(n);
	}
	else if (m == 1){
		return fib(n);
	}
	else {
		return n;
	}
}

void pop2() {
    JJ = jjj(3);
		CC = jjj(3);
		FF = jjj(3);
		DD = jjj(3);

    buffer << "pop ebx\n";
    JJ = jc(3,2);
		CC = jc(3,2);
		FF = jc(3,2);
		DD = jc(3,2);

    buffer << "pop eax\n";
    JJ = jc(3,0);
		CC = jc(3,0);
		FF = jc(3,0);
		DD = jc(3,0);

}

void neg() {
    JJ = jc(3,1);
		CC = jc(3,1);
		FF = jc(3,1);
		DD = jc(3,1);

    buffer << "pop eax\n";
    JJ = jc(3,1);
		CC = jc(3,1);
		FF = jc(3,1);
		DD = jc(3,1);

    buffer << "neg eax\n";
    JJ = jc(3,1);
		CC = jc(3,1);
		FF = jc(3,1);
		DD = jc(3,1);

    buffer << "push eax\n";
    JJ = jc(3,1);
		CC = jc(3,1);
		FF = jc(3,1);
		DD = jc(3,1);

}

void not1() {
      JJ = ccc(4);
			CC = ccc(4);
			FF = ccc(4);
			DD = ccc(4);

     buffer << " pop eax" << endl;
     JJ = ccc(4);
			CC = ccc(4);
			FF = ccc(4);
			DD = ccc(4);
      buffer << " cmp eax, 0" << endl;
      JJ = ccc(4);
			CC = ccc(4);
			FF = ccc(4);
			DD = ccc(4);
      buffer << " sete al" << endl;
      JJ = ccc(4);
			CC = ccc(4);
			FF = ccc(4);
			DD = ccc(4);
      buffer << " movzx eax, al" << endl;
      JJ = ccc(4);
			CC = ccc(4);
			FF = ccc(4);
			DD = ccc(4);
      buffer << " push eax" << endl;
      JJ = ccc(4);
			CC = ccc(4);
			FF = ccc(4);
			DD = ccc(4);
}

void bitnot() {
    JJ = fib(7);
		CC = fib(7);
		FF = fib(7);
		DD = fib(7);

    buffer << "pop eax\n";
    JJ = fib(7);
		CC = fib(7);
		FF = fib(7);
		DD = fib(7);
    buffer << "not eax\n";
    JJ = fib(7);
		CC = fib(7);
		FF = fib(7);
		DD = fib(7);
    buffer << "push eax\n";
    JJ = fib(7);
		CC = fib(7);
		FF = fib(7);
		DD = fib(7);
}

void mul() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    pop2();
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "imul eax, ebx\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "push eax\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
}

void div() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    pop2();
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "cdq\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "idiv ebx\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "push eax\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
}

void mod() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    pop2();
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "cdq\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "idiv ebx\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "push edx\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
}

void add() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    pop2();
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "add eax, ebx\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "push eax\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
}

void sub() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    pop2();
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "sub eax, ebx\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "push eax\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
}

void compare(int cmp) {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    pop2();
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "cmp eax, ebx\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    switch (cmp) {
        case 1:
            buffer << "setl al\n";
            JJ = ccc(4);
		        CC = ccc(4);
		        FF = ccc(4);
		        DD = ccc(4);
            break;
        case 2:
            buffer << "setle al\n";
            JJ = ccc(4);
		        CC = ccc(4);
		        FF = ccc(4);
		        DD = ccc(4);
            break;
        case 3:
            buffer << "setg al\n";
            JJ = ccc(4);
		        CC = ccc(4);
		        FF = ccc(4);
		        DD = ccc(4);
            break;
        case 4:
            buffer << "setge al\n";
            JJ = ccc(4);
		        CC = ccc(4);
		        FF = ccc(4);
		        DD = ccc(4);
            break;
        case 5:
            buffer << "sete al\n";
            JJ = ccc(4);
		        CC = ccc(4);
		        FF = ccc(4);
		        DD = ccc(4);
            break;
        case 6:
            buffer << "setne al\n";
            JJ = ccc(4);
		        CC = ccc(4);
		        FF = ccc(4);
		        DD = ccc(4);
            break;
    }
    buffer << "movzx eax, al\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "push eax\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
}

void less_than() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    pop2();
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "cmp eax, ebx\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "setl al\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "movzx eax, al\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "push eax\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
}

void greater_than() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    pop2();
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "cmp eax, ebx\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "setg al\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "movzx eax, al\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "push eax\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
}

void lessequ() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    compare(2);
}



void greaterequ() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    compare(4);
}

void equ() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    compare(5);
}

void notequ() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    compare(6);
}

void bitand1() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    pop2();
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "and eax, ebx\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "push eax\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
}

void bitor1() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    pop2();
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "or eax, ebx\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "push eax\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
}

void bitxor() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    pop2();
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "xor eax, ebx\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    buffer << "push eax\n";
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
}

void and1() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    pop2();
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
      buffer << " and eax, ebx" << endl;
      JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
      buffer << " setne al" << endl;
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
      buffer << " movzx eax, al" << endl;
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
      buffer << " push eax" << endl;
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
}

void or1() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    pop2();
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
      buffer << " or eax, ebx" << endl;
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
      buffer << " setne al" << endl;
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
      buffer << " movzx eax, al" << endl;
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
      buffer << " push eax" << endl;
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
}


void printBuffer() {
    JJ = ccc(4);
		CC = ccc(4);
		FF = ccc(4);
		DD = ccc(4);
    cout << buffer.str();
}

}

%define api.token.prefix {T_}
%token 
  END 0 "end of file"
  LPAREN  "("
  RPAREN  ")"
  COMMA ","
  SEMICOLON ";"
  LAND "&&"
  LOR "||"
  LNOT "!"
  PLUS "+"
  MINUS "-"
  TIMES "*"
  DIVIDE "/"
  MOD "%"
  LT "<"
  LE "<="
  GT ">"
  GE ">="
  EQ "=="
  NE "!="
  BAND "&"
  BOR "|"
  BXOR "^"
  ASSIGN "="
  LBRACE "{"
  RBRACE "}"
  BITNOT "~"

%token VOID "void" INT "int" RETURN "return" MAIN "main"  WHILE "while" IF "if" ELSE "else" CONTINUE "continue" BREAK "break" 

%token <std::string> IDENTIFIER "identifier"
%token <int> INTEGER "number"
// 在这里指定运算符的优先级和结合性,left为左结合,right为右结合,越靠下优先级越高
%precedence THEN//解决嵌套循环
%precedence ELSE
%left "||"
%left "&&"
%left "|"
%left "^"
%left "&"
%left "==" "!="
%left "<" ">" "<=" ">="
%left "+" "-"
%left "*" "/" "%"
%left UMINUS
%right "!" "~"



%nterm <int>  list_param list_parameter list_parameters

%nterm <int> parameters // 函数调用参数个数
%nterm <int> parameter body_function bodys_function
%nterm call_f// 非终结符类型也需要指定,这个与下面的例子适配,可以删除或根据需要添加,如果不需要属性文法也可以不指定类型
%type  assignment_s return_s declaration_s variables variable 
%type   value_type
%type  function  main_function normal_function 

%%
// 在这里写文法规则和动作
%start program; // 文法开始符号

program: 
%empty {}
|program function 

function://其中一个函数
main_function
//main函数
|normal_function//普通函数

//普通函数
normal_function:
value_type "identifier" {
    drv.functionArgsTable.clear();
    drv.functionArgsCount = 0;
}"(" list_parameters{
    drv.identifierTable.clear();
    drv.identifierCount = 0;
} ")" "{" bodys_function {
    cout << $2 << ":" << endl;
      cout << " push ebp" << endl;
      cout << " mov ebp, esp" << endl;
      if(drv.identifierCount > 0)
        cout << " sub esp, " << drv.identifierCount * 4 << endl;
      printBuffer();
      buffer.str("");
      if(!$9){//没有return语句
        if(drv.identifierCount > 0)
          cout << " add esp, " << drv.identifierCount * 4 << endl;
        cout << " leave" << endl;
        cout << " ret" << endl;
      }
}"}"

value_type:
  VOID             
| INT              

list_parameters:
%empty {$$=0;}
|list_param{$$=$1;}

list_param:
list_parameter{$$=1;}
|list_param "," list_parameter{$$=$1+1;}

list_parameter:
"int" "identifier"{
    drv.functionArgsTable[$2] = ++drv.functionArgsCount;
    
}


main_function:
value_type "main"{
    drv.functionArgsTable.clear();
    drv.functionArgsCount = 0;
}"(" list_parameters{
    drv.identifierTable.clear();
    drv.identifierCount = 0;
} ")" "{"bodys_function {
    cout << "main" << ":" << endl;
      cout << " push ebp" << endl;
      cout << " mov ebp, esp" << endl;
      if(drv.identifierCount > 0)
        cout << " sub esp, " << drv.identifierCount * 4 << endl;
      printBuffer();
      buffer.str("");
      
} "}"

bodys_function:
%empty {$$=0;}
|bodys_function body_function  {$$=$2;}
 // 不确定有多少行

body_function:
declaration_s{$$=0;}
|assignment_s{$$=0;}
|return_s{$$=1;}
|call_f ";"{$$=0;}
|if_else{$$=0;}
|while_s{$$=0;}
| "continue" ";"
    {
      buffer << " jmp " << drv.continue_vector.back() << endl;
    }
| "break" ";"
    {
      buffer << " jmp " << drv.break_vector.back() << endl;
    };

if_else:
IF "(" exp ")"
    {
      drv.ifCount++;
      buffer << " pop eax" << endl;
      buffer << " cmp eax, 0" << endl;
      buffer << " je " << ".L_if_end_" << drv.ifCount << endl;
      drv.if_vector.push_back(".L_else_end_" + to_string(drv.ifCount));
      drv.if_vector.push_back(".L_if_end_" + to_string(drv.ifCount));
    }
    "{"bodys_function"}" else_s
    
else_s:
  %empty %prec THEN
    {
      buffer << drv.if_vector.back() << ":" << endl;
      drv.if_vector.pop_back();
      drv.if_vector.pop_back();
    }
| ELSE
    {
      string tmp = drv.if_vector.back();
      drv.if_vector.pop_back();
      buffer << " jmp " << drv.if_vector.back() << endl;
      buffer << tmp << ":" << endl;
    } 
  "{"bodys_function"}"
    {
      buffer<< drv.if_vector.back() << ":" << endl;
      drv.if_vector.pop_back();
    
    }

while_s:
  WHILE "(" 
    {
      drv.whileCount++;
      buffer<< ".L_while_cond_" << drv.whileCount << ":" << endl;
      drv.continue_vector.push_back(".L_while_cond_" + to_string(drv.whileCount));
      drv.break_vector.push_back(".L_while_end_" + to_string(drv.whileCount));
    }
  exp
    {
      buffer << " pop eax" << endl;
      buffer << " cmp eax, 0" << endl;
      buffer << " je " << drv.break_vector.back() << endl;
    }
  ")" "{"bodys_function
    {
      buffer << " jmp " << drv.continue_vector.back() << endl;
      buffer << drv.break_vector.back() << ":" << endl;
      drv.continue_vector.pop_back();
      drv.break_vector.pop_back();
    
    }"}"
//定义语句
declaration_s: "int" variables  ";"

variables:
%empty{}
|variables variable


variable: 
"identifier" {
    drv.identifierTable[$1] = ++drv.identifierCount;
    buffer << " mov DWORD PTR [ebp-" << drv.identifierTable[$1] * 4 << "], 0" << endl;
    
}
|","
|"identifier" "=" exp{
    drv.identifierTable[$1] = ++drv.identifierCount;
    buffer << " pop eax" << endl;
    buffer << " mov DWORD PTR [ebp-" << drv.identifierTable[$1] * 4 << "], eax" << endl;
}

//赋值语句
assignment_s:
"identifier" "=" exp ";"{
      buffer << " pop eax" << endl;
      if(drv.functionArgsTable.count($1)){
        buffer << " mov DWORD PTR [ebp+" << 8 + 4 * (drv.functionArgsCount - drv.functionArgsTable[$1]) << "], eax" << endl;
      }
      else if(drv.identifierTable.count($1)){
        buffer << " mov DWORD PTR [ebp-" << drv.identifierTable[$1] * 4 << "], eax" << endl;
      }
};


//return语句
return_s:
RETURN ";"{
      if(drv.identifierCount > 0){
        buffer << " add esp, " << drv.identifierCount * 4 << endl;
      }
      buffer << " leave" << endl;
      buffer << " ret" << endl;
}
|"return" exp ";"{
    buffer << " pop eax" << endl;// 返回值
      if(drv.identifierCount > 0)
        buffer << " add esp, " << drv.identifierCount * 4 << endl;
      buffer << " leave" << endl;
      buffer << " ret" << endl;
}


exp:
    IDENTIFIER{
        if(drv.functionArgsTable.count($1)){// 函数参数
        buffer << " mov eax, " << "DWORD PTR [ebp+" << 8 + 4 * (drv.functionArgsCount - drv.functionArgsTable[$1]) << "]" << endl;
        buffer << " push eax" << endl;
      }
      else if(drv.identifierTable.count($1)){// 局部变量
        buffer << " mov eax, " << "DWORD PTR [ebp-" << drv.identifierTable[$1] * 4 << "]" << endl;
        buffer << " push eax" << endl;
      }
    }
    |call_f{
      buffer << " push eax" << endl; // 只有当函数调用作为表达式时才处理函数返回值
    }
    | INTEGER
    {
      buffer << " push " << $1 << endl;
    }
    | exp PLUS exp {  add(); }
    | exp MINUS exp { sub(); }
    | exp TIMES exp { mul(); }
    | exp DIVIDE exp { div(); }
    | exp MOD exp {  mod(); }
    | exp LT exp {  less_than(); }
    | exp LE exp {  lessequ(); }
    | exp GT exp {  greater_than(); }
    | exp GE exp {  greaterequ(); }
    | exp "=="exp {  equ(); }
    | exp "!=" exp { notequ(); }
    | exp "&&" exp { and1(); }
    | exp "&" exp { bitand1(); }
    | exp "|" exp { bitor1(); }
    | exp "^" exp { bitxor(); }
    | exp "||" exp {  or1(); }
    | "~" exp {   bitnot();    }
    | "!" exp {  not1(); }
    | "-" exp %prec UMINUS { neg(); }
    | LPAREN exp RPAREN 
;
call_f:

    IDENTIFIER "(" parameters ")"
    {
      if($1 == "println_int"){
        buffer << " push offset format_str" << endl;
        buffer << " call printf" << endl;
        buffer << " add esp, 8" << endl;
      }
      else{
        buffer << " call " << $1 << endl;
        buffer << " add esp, " << $3 * 4 << endl; // 释放参数空间
      }
    };

parameters:
%empty 
    {
      $$ = 0;
    }
| parameter
    {
      $$ = $1;
    };

parameter:
  exp
    {
      $$ = 1;
    }
| parameter "," exp
    {
      $$ = $1 + 1;
    };


%%

void yy::parser::error (const location_type& l, const std::string& m)
{
  std::cerr << l << ": " << m << '\n';
}

scanner.l

%{
  #include <iostream>
  #include "driver.h"
  #include "parser.hpp"
%}

%option noyywrap nounput noinput batch debug

%{
  # define YY_USER_ACTION  loc.columns (yyleng);
%}


id [_a-zA-Z][_a-zA-Z0-9]*
int [0-9]+
blank [ \t\r]

%%
%{
  /* 开启了bison提供的location功能 */
  yy::location& loc = drv.m_loc;
  loc.step ();
%}
{blank}           loc.step();                           /* 跳过空白字符 */
\n+               loc.lines(yyleng); loc.step();        /* 处理换行符 */
"int"            { return yy::parser::make_INT(loc); }     /* 关键字 int */
"return"         { return yy::parser::make_RETURN(loc); }  /* 关键字 return */
"void"           { return yy::parser::make_VOID(loc); }    /* 关键字 void */
"main"           { return yy::parser::make_MAIN(loc); }    /* 关键字 main */
"while"          { return yy::parser::make_WHILE(loc); }   /* 关键字 while */
"if"             { return yy::parser::make_IF(loc); }      /* 关键字 if */
"else"           { return yy::parser::make_ELSE(loc); }    /* 关键字 else */
"continue"       { return yy::parser::make_CONTINUE(loc); }/* 关键字 continue */
"break"          { return yy::parser::make_BREAK(loc); }   /* 关键字 break */
"="               return yy::parser::make_ASSIGN(loc);  /* 赋值操作符 */
"&&"              return yy::parser::make_LAND(loc);    /* 逻辑与 */
"||"              return yy::parser::make_LOR(loc);     /* 逻辑或 */
"!"               return yy::parser::make_LNOT(loc);    /* 逻辑非 */
"+"               return yy::parser::make_PLUS(loc);    /* 加号 */
"-"               return yy::parser::make_MINUS(loc);   /* 减号 */
"*"               return yy::parser::make_TIMES(loc);   /* 乘号 */
"/"               return yy::parser::make_DIVIDE(loc);  /* 除号 */
"%"               return yy::parser::make_MOD(loc);     /* 取模 */
"<"               return yy::parser::make_LT(loc);      /* 小于 */
"<="              return yy::parser::make_LE(loc);      /* 小于等于 */
">"               return yy::parser::make_GT(loc);      /* 大于 */
">="              return yy::parser::make_GE(loc);      /* 大于等于 */
"=="              return yy::parser::make_EQ(loc);      /* 等于 */
"!="              return yy::parser::make_NE(loc);      /* 不等于 */
"&"               return yy::parser::make_BAND(loc);    /* 按位与 */
"|"               return yy::parser::make_BOR(loc);     /* 按位或 */
"^"               return yy::parser::make_BXOR(loc);    /* 按位异或 */
"~"               return yy::parser::make_BITNOT(loc);  /* 按位非 */
"("               return yy::parser::make_LPAREN(loc);  /* 左圆括号 */
")"               return yy::parser::make_RPAREN(loc);  /* 右圆括号 */
"{"               return yy::parser::make_LBRACE(loc);  /* 左大括号 */
"}"               return yy::parser::make_RBRACE(loc);  /* 右大括号 */
";"               return yy::parser::make_SEMICOLON(loc); /* 分号 */
","               return yy::parser::make_COMMA(loc);    /* 逗号 */
{id}              return yy::parser::make_IDENTIFIER(yytext, loc); /* 标识符 */
{int}             return yy::parser::make_INTEGER(std::stoi(yytext), loc); /* 整数 */
<<EOF>>           return yy::parser::make_END(loc);      /* 文件结束 */


 

%%

void Driver::scan_begin()
{
  // 关闭flex的debug信息
  yy_flex_debug = 0;
  yyin = fopen(m_file.c_str(), "r");
}

void Driver::scan_end()
{
  fclose(yyin);
}

CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.16)
project(Compilerlab4)
set(CMAKE_CXX_STANDARD 14)
add_compile_options(-pedantic)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_BINARY_DIR})
include(FindFLEX)
if(FLEX_FOUND)
 message("Info: flex found!")
else()
 message("Error: flex not found!")
endif()
FLEX_TARGET(Scanner scanner.l ${CMAKE_CURRENT_BINARY_DIR}/scanner.cpp)
include(FindBISON)
if(BISON_FOUND)
 message("Info: bison found!")
else()
 message("Error: bison not found!")
endif()
BISON_TARGET(Parser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp
    DEFINES_FILE ${CMAKE_CURRENT_BINARY_DIR}/parser.hpp)
add_executable(Compilerlab4
    ${FLEX_Scanner_OUTPUTS}
    ${BISON_Parser_OUTPUTS}
    driver.cpp
    compilerlab3.cpp
)
target_compile_features(Compilerlab4 PRIVATE cxx_std_14)
target_link_libraries(Compilerlab4 PUBLIC -lm)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值