aptx1231 / BUAA_Compiler

2017级北航计算机学院编译技术 C0文法编译器 生成mips代码 2019秋季学期

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

BUAA Complier

北航计算机学院编译技术课程设计

简单C0文法的编译器

使用语言:C++

GramOrign/ 目录下为未优化的版本

根目录下为优化后的版本

C0文法及其语义说明:

加法运算符> ::= +-乘法运算符>  ::= *|/
<关系运算符>  ::=  <|<=|>|>=|!===字母>   ::= _|a|...|zA|...|Z数字>   ::= 0|<非零数字>
<非零数字>  ::= 1|...|9
<字符>    ::=  '<加法运算符>'|'<乘法运算符'|'字母'|'数字>'
<字符串>   ::=  "{十进制编码为32,33,35-126的ASCII字符}"程序>    ::= [<常量说明>][<变量说明>]{<有返回值函数定义>|<无返回值函数定义>}<主函数>
<常量说明> ::=  const常量定义>;{ const常量定义>;}
<常量定义>   ::=   int标识符>=<整数>{,<标识符>=<整数>}
                  | char标识符>=<字符>{,<标识符>=<字符>}
<无符号整数>  ::=非零数字>{<数字>}| 0整数>        ::= [+|-]<无符号整数>
<标识符>    ::=字母>{<字母>|<数字>}  //标识符和保留字都区分大小写声明头部>   ::=  int标识符> |char标识符>
<变量说明>  ::=变量定义>;{<变量定义>;}
<变量定义>  ::=类型标识符>(<标识符>|<标识符'['无符号整数']'){,(<标识符>|<标识符'['无符号整数']' )} 
                 //<无符号整数>表示数组元素的个数,其值需大于0
                 //变量没有初始化的情况下没有初值  类型标识符>      ::=  int | char有返回值函数定义>  ::=声明头部'('参数表')' '{'复合语句'}'无返回值函数定义>  ::= void标识符'('参数表')''{'复合语句'}'复合语句>   ::=  [<常量说明>][<变量说明>]<语句列>
<参数表>    ::=类型标识符><标识符>{,<类型标识符><标识符>}| <>
<主函数>    ::= void main‘(’‘)’ ‘{’<复合语句>‘}’
<表达式>    ::= [+|-]<>{<加法运算符><>}   //[+|-]只作用于第一个<项>>     ::=因子>{<乘法运算符><因子>}
<因子>    ::=标识符>|<标识符'['表达式']'|'('表达式')'|<整数>|<字符>|<有返回值函数调用语句//char 类型的变量或常量,用字符的ASCII 码对应的整数参加运算 
     //<标识符>'['<表达式>']'中的<表达式>只能是整型,下标从0开始
    //单个<标识符>不包括数组名,即数组不能整体参加运算,数组元素可以参加运算语句>    ::=条件语句>|<循环语句>| '{'语句列'}'| <有返回值函数调用语句>; 
                           |<无返回值函数调用语句>;|<赋值语句>;|<读语句>;|<写语句>;|<>;|<返回语句>;
<赋值语句>   ::=标识符>=<表达式>|<标识符'['表达式']'=表达式//<标识符>=<表达式>中的<标识符>不能为常量名和数组名条件语句>  ::= if '('条件')'语句>[else语句>]
<条件>    ::=表达式><关系运算符><表达式>|<表达式//表达式需均为整数类型才能进行比较,第二个侯选式中表达式为0条件为假,否则为真循环语句>   ::=  while '('条件')'语句>| do语句while '('条件')' |for'('标识符>=<表达式>;<条件>;<标识符>=<标识符>(+|-)<步长')'语句//for语句先进行条件判断,符合条件再进入循环体步长>::=无符号整数>  
<有返回值函数调用语句> ::=标识符'('值参数表')'无返回值函数调用语句> ::=标识符'('值参数表')'值参数表>   ::=表达式>{,<表达式>}|<//实参的表达式不能是数组名,可以是数组元素
              //实参的计算顺序,要求生成的目标码运行结果与Clang8.0.0 编译器运行的结果一致语句列>   ::= {<语句>}
<读语句>    ::=  scanf '('标识符>{,<标识符>}')'  
               //从标准输入获取<标识符>的值,该标识符不能是常量名和数组名
               //生成PCODE代码的情况:需要处理为一个scanf语句中,若有多个<标识符>,无论标识符的类型是char还是int,每输入一项均需回车
              //生成MIPS汇编的情况:按照syscall指令的用法使用即可写语句>    ::= printf '('字符串>,<表达式')'| printf '('字符串')'| printf '('表达式')'  
			//printf '(' <字符串>,<表达式> ')'
              //printf '(' <字符串>,<表达式> ')'输出时,先输出字符串的内容,再输出表达式的值,两者之间无空格
              //表达式为字符型时,输出字符;为整型时输出整数
              //<字符串>原样输出(不存在转义)
              //每个printf语句的内容输出到一行,按结尾有换行符\n处理返回语句>   ::=  return['('表达式')']    
		//无返回值的函数中可以没有return语句,也可以有形如return;的语句
         //有返回值的函数只要出现一条带返回值的return语句即可,不用检查每个分支是否有带返回值的return语句
                                        
关于类型和类型转换的约定1. 表达式类型为char型有以下三种情况1表达式由<标识符>标识符'['表达式>']构成<标识符>的类型为char即char类型的常量和变量char类型的数组元素2表达式仅由一个<字符>构成即字符字面量3表达式仅由一个有返回值的函数调用构成且该被调用的函数返回值为char型
  除此之外的所有情况<表达式>的类型都是int
2. 只在表达式计算中有类型转换字符型一旦参与运算则转换成整型包括小括号括起来的字符型也算参与了运算例如(‘c’)的结果是整型3. 其他情况例如赋值函数传参if/while条件语句中关系比较要求类型完全匹配并且条件中的关系比较只能是整型之间比不能是字符型if ‘(’<条件>‘)’和while ‘(’<条件>‘)’里边如果<条件>是单个表达式则必须是整型

About

2017级北航计算机学院编译技术 C0文法编译器 生成mips代码 2019秋季学期


Languages

Language:C++ 100.0%