编译原理实验二
1.实验内容:
要完成Decaf编译器的语法分析工作,即用bison工具生成一个语法分析程序,对词法分析输出的单词符号串(终结符串)进行自底向上的分析,并依次输出用来进行归约的语法规则。
2.实验详解
-
定义优先级和结合性
由上到下优先级递增。%left表示左结合,%right表示右结合。由于减号和取负值的符号相同,所以取UMINUS为一个虚构终结符,遇到取负值时,在-号后加上%prec UMINUS,表示-为UMINUS的优先级。
-
完善parser.y中的规则和动作。
参照Decaf_language.rtf中的表达式。所有终结符都取小写字母,非终结符开头为大写字母。-
对于
x*
的规则,表示x出现0次或多次:采用递归表达。
例如StmtBlock ::= { Stmt* }
。创造新的非终结符StmtList代表Stmt*,然后将StmtList构造为StmtList Stmt | epsilon
。书写规则如下
-
对于
<x>
的规则,表示x出现0次或一次:
例如ClassDefn ::= class identifier <extends identifier >{ Field* }
。创造新的非终结符OptExtends代表<extends identifier >
,然后将OptExtends构造为T_Extends T_Identifier | epsilon
。书写规则如下
-
对于
x+
,规则,表示x出现1次或多次:
例如Formals ::= Variable+, | epsilon
。书写规则如下
-
-
经测试,所有样例通过
3.代码参考
parse.y文件
/*parser.y
*
*bison输入文件,用于产生parser
*
*pp2:你的任务只是输出parser的规约动作,即只需要验证输入文件是否符合
*decaf语言的文法,并把规约动作输出。
*
*/
%{
/*
*同flex一样,第一个%{ %}内部的程序将被直接copy到parser_tab.h/c中
*所以可以将要include的头文件和全局变量放到这儿。
*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <process.h>
#include "scanner.h"
%}
/*
*在这儿,你可以定义tokens,types,precedence 和 associativity等。
*/
/*
*从program开始规约
*/
%start Program
/*
*yylval
*------
*这儿定义全局变量yylval,你可以添加自己的非终结符。
*/
%union { /*bison可以从这个定义中产生yylval的定义*/
int integerConstant;
int boolConstant;
const char *stringConstant;
double doubleConstant;
char identifier[128];
}
/*Tokens
*------
*这儿我们告诉bison所要用到的token类型。
*bison可以给这些类型定义唯一的数字并输出#define 到parser_tab.h文件中。
*/
%token T_Void T_Bool T_Int T_D