commit
22647d3898
@ -0,0 +1,10 @@
|
|||||||
|
objs=parser.o lexer.o ast.o display.o
|
||||||
|
CC=gcc
|
||||||
|
|
||||||
|
parser:$(objs)
|
||||||
|
$(CC) -o parser ${objs}
|
||||||
|
%.o:%.c
|
||||||
|
$(CC) -c $<
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm parser $(objs) parser.c lexer.c parser.h -f
|
@ -0,0 +1,716 @@
|
|||||||
|
#include "ast.h"
|
||||||
|
#include "parser.h" //由bison根据parser.y生成
|
||||||
|
#define DEBUG 1
|
||||||
|
#define INTEGER_MINVALUE -2147483647
|
||||||
|
#define ARRAYCALL 123456789
|
||||||
|
int LEV=0;
|
||||||
|
int main_flag = 0;
|
||||||
|
int call_flag = 0;
|
||||||
|
int main_call = 0;
|
||||||
|
int current_offset = 0;
|
||||||
|
char break_label[30];
|
||||||
|
char continue_label[30];
|
||||||
|
char case_temp[30];
|
||||||
|
char case_label[30];
|
||||||
|
char array_name[30];
|
||||||
|
char struct_name[33];
|
||||||
|
int struct_width = 0;
|
||||||
|
int struct_flag = 0;
|
||||||
|
int array_index = 0;
|
||||||
|
int struct_var_flag = 0;
|
||||||
|
int rtn, flag = 0;
|
||||||
|
int rtn2, op;
|
||||||
|
int return_flag = 0;
|
||||||
|
struct ASTNode* left;
|
||||||
|
struct ASTNode* right;
|
||||||
|
char tokens[200][200]; //用来存储TAC语句信息
|
||||||
|
const char spState[8][20] = { "FUNCTION", "GOTO", "CALL", "PARAM", "LABEL", "ARG", "RETURN","BLOCK" };
|
||||||
|
|
||||||
|
int varlen = 0; //记录当前变量长度
|
||||||
|
int lineNo = 0; //记录行号
|
||||||
|
ASTNode *new_node(node_type type, ASTNode *left, ASTNode *mid, ASTNode *right, int int_val, float float_val, char *symbol, node_type d_type) {
|
||||||
|
ASTNode *n = (ASTNode *)malloc(sizeof(ASTNode));
|
||||||
|
n->type = type;
|
||||||
|
n->left = left;
|
||||||
|
n->mid = mid;
|
||||||
|
n->right = right;
|
||||||
|
n->int_val = int_val;
|
||||||
|
n->float_val = float_val;
|
||||||
|
n->symbol = symbol;
|
||||||
|
n->d_type = d_type;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int targetNum[1024];
|
||||||
|
int currentNum[1024];
|
||||||
|
int currentLayer = 0;
|
||||||
|
int handle_next_display = 1;
|
||||||
|
|
||||||
|
int getBranchNum(ASTNode* T)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
if(T->right)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
if(T->mid)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printVarType(node_type type)
|
||||||
|
{
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case Int:
|
||||||
|
printf("int");
|
||||||
|
break;
|
||||||
|
case Float:
|
||||||
|
printf("float");
|
||||||
|
break;
|
||||||
|
case Void:
|
||||||
|
printf("void");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("unknown");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gapProcess()
|
||||||
|
{
|
||||||
|
for(int i=1;i<=currentLayer;i++)
|
||||||
|
{
|
||||||
|
if(i < currentLayer)
|
||||||
|
{
|
||||||
|
if(currentNum[i] <= targetNum[i])
|
||||||
|
{
|
||||||
|
printf("| ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(currentNum[i] < targetNum[i])
|
||||||
|
{
|
||||||
|
printf("|--");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("`--");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gapManage(ASTNode* T, int reverse)
|
||||||
|
{
|
||||||
|
currentNum[currentLayer]++;
|
||||||
|
currentLayer++;
|
||||||
|
targetNum[currentLayer] = getBranchNum(T);
|
||||||
|
currentNum[currentLayer] = 1;
|
||||||
|
if(reverse)
|
||||||
|
{
|
||||||
|
nextDisplayReverse(T);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nextDisplay(T);
|
||||||
|
}
|
||||||
|
currentLayer--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sameGapManage(ASTNode* T, int reverse)
|
||||||
|
{
|
||||||
|
currentNum[currentLayer]++;
|
||||||
|
currentLayer++;
|
||||||
|
targetNum[currentLayer] = getBranchNum(T) - 1;
|
||||||
|
currentNum[currentLayer] = 1;
|
||||||
|
if(T->right)
|
||||||
|
{
|
||||||
|
display(T->right);
|
||||||
|
}
|
||||||
|
currentLayer--;
|
||||||
|
display(T->left);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nextDisplay(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
display(T->left);
|
||||||
|
}
|
||||||
|
if(T->mid)
|
||||||
|
{
|
||||||
|
display(T->mid);
|
||||||
|
}
|
||||||
|
if(T->right)
|
||||||
|
{
|
||||||
|
display(T->right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nextDisplayReverse(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->right)
|
||||||
|
{
|
||||||
|
display(T->right);
|
||||||
|
}
|
||||||
|
if(T->mid)
|
||||||
|
{
|
||||||
|
display(T->mid);
|
||||||
|
}
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
display(T->left);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_root(ASTNode* T)
|
||||||
|
{
|
||||||
|
gapProcess();
|
||||||
|
printf("CompUnit\n");
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_comp_unit(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
currentNum[currentLayer]--;
|
||||||
|
}
|
||||||
|
handle_next_display = 0;
|
||||||
|
switch(T->right->type)
|
||||||
|
{
|
||||||
|
case ConstDecl:
|
||||||
|
print_const_decl(T->right);
|
||||||
|
break;
|
||||||
|
case VarDecl:
|
||||||
|
print_var_decl(T->right);
|
||||||
|
break;
|
||||||
|
case FuncDef:
|
||||||
|
print_func_def(T->right);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
currentLayer++;
|
||||||
|
targetNum[currentLayer] = getBranchNum(T) - 1;
|
||||||
|
currentNum[currentLayer] = 1;
|
||||||
|
currentLayer--;
|
||||||
|
display(T->left);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_const_decl(ASTNode* T)
|
||||||
|
{
|
||||||
|
gapProcess();
|
||||||
|
printf("ConstDecl ");
|
||||||
|
printVarType(T->d_type);
|
||||||
|
printf("\n");
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_const_def(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
currentNum[currentLayer]--;
|
||||||
|
}
|
||||||
|
gapProcess();
|
||||||
|
printf("ConstDef %s\n", T->symbol);
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
sameGapManage(T, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_const_exp_array(ASTNode* T)
|
||||||
|
{
|
||||||
|
gapProcess();
|
||||||
|
printf("ConstExpArray\n");
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_const_init_val(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->right && T->right->type == ConstExp)
|
||||||
|
{
|
||||||
|
handle_next_display = 0;
|
||||||
|
print_const_exp(T->right);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gapProcess();
|
||||||
|
printf("ConstInitVal {}\n");
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_const_exp(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->int_val == 0)
|
||||||
|
{
|
||||||
|
handle_next_display = 0;
|
||||||
|
print_mul_exp(T->right);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gapProcess();
|
||||||
|
printf("ConstExp ");
|
||||||
|
if(T->d_type == PLUS)
|
||||||
|
{
|
||||||
|
printf("+\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("-\n");
|
||||||
|
}
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_var_decl(ASTNode* T)
|
||||||
|
{
|
||||||
|
gapProcess();
|
||||||
|
printf("VarDecl ");
|
||||||
|
printVarType(T->d_type);
|
||||||
|
printf("\n");
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_var_def(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
currentNum[currentLayer]--;
|
||||||
|
}
|
||||||
|
gapProcess();
|
||||||
|
printf("VarDef %s\n", T->symbol);
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
sameGapManage(T, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_init_val(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->int_val == Exp)
|
||||||
|
{
|
||||||
|
handle_next_display = 0;
|
||||||
|
print_exp(T->right);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(T->right)
|
||||||
|
{
|
||||||
|
handle_next_display = 0;
|
||||||
|
print_init_vals(T->right);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gapProcess();
|
||||||
|
printf("Null Init Vals\n");
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_init_vals(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
currentNum[currentLayer]--;
|
||||||
|
}
|
||||||
|
gapProcess();
|
||||||
|
printf("InitVals\n");
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
sameGapManage(T, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_func_def(ASTNode* T)
|
||||||
|
{
|
||||||
|
gapProcess();
|
||||||
|
printf("FuncDef ");
|
||||||
|
printVarType(T->d_type);
|
||||||
|
printf(" %s\n", T->symbol);
|
||||||
|
gapManage(T, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_func_f_param(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
currentNum[currentLayer]--;
|
||||||
|
}
|
||||||
|
gapProcess();
|
||||||
|
printf("FuncFParams ");
|
||||||
|
printVarType(T->d_type);
|
||||||
|
printf(" %s\n", T->symbol);
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
sameGapManage(T, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_block(ASTNode* T)
|
||||||
|
{
|
||||||
|
gapProcess();
|
||||||
|
printf("Block\n");
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_block_item(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
currentNum[currentLayer]--;
|
||||||
|
}
|
||||||
|
handle_next_display = 0;
|
||||||
|
switch(T->right->type)
|
||||||
|
{
|
||||||
|
case ConstDecl:
|
||||||
|
print_const_decl(T->right);
|
||||||
|
break;
|
||||||
|
case VarDecl:
|
||||||
|
print_var_decl(T->right);
|
||||||
|
break;
|
||||||
|
case Stmt:
|
||||||
|
print_stmt(T->right);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
currentLayer++;
|
||||||
|
targetNum[currentLayer] = getBranchNum(T) - 1;
|
||||||
|
currentNum[currentLayer] = 1;
|
||||||
|
currentLayer--;
|
||||||
|
display(T->left);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_stmt(ASTNode* T)
|
||||||
|
{
|
||||||
|
switch (T->int_val)
|
||||||
|
{
|
||||||
|
case BlankStmt:
|
||||||
|
gapProcess();
|
||||||
|
printf("Blank Statement\n");
|
||||||
|
gapManage(T, 0);
|
||||||
|
break;
|
||||||
|
case ExpStmt:
|
||||||
|
handle_next_display = 0;
|
||||||
|
print_exp(T->right);
|
||||||
|
break;
|
||||||
|
case AssignStmt:
|
||||||
|
gapProcess();
|
||||||
|
printf("Assign Statement\n");
|
||||||
|
gapManage(T, 0);
|
||||||
|
break;
|
||||||
|
case Block:
|
||||||
|
handle_next_display = 0;
|
||||||
|
print_block(T->right);
|
||||||
|
break;
|
||||||
|
case IfStmt:
|
||||||
|
gapProcess();
|
||||||
|
printf("If Statement\n");
|
||||||
|
gapManage(T, 0);
|
||||||
|
break;
|
||||||
|
case IfElseStmt:
|
||||||
|
gapProcess();
|
||||||
|
printf("If-Else Statement\n");
|
||||||
|
gapManage(T, 0);
|
||||||
|
break;
|
||||||
|
case WhileStmt:
|
||||||
|
gapProcess();
|
||||||
|
printf("While Statement\n");
|
||||||
|
gapManage(T, 0);
|
||||||
|
break;
|
||||||
|
case BreakStmt:
|
||||||
|
gapProcess();
|
||||||
|
printf("Break Statement\n");
|
||||||
|
gapManage(T, 0);
|
||||||
|
break;
|
||||||
|
case ContinueStmt:
|
||||||
|
gapProcess();
|
||||||
|
printf("Continue Statement\n");
|
||||||
|
gapManage(T, 0);
|
||||||
|
break;
|
||||||
|
case BlankReturnStmt:
|
||||||
|
gapProcess();
|
||||||
|
printf("Blank Return Statement\n");
|
||||||
|
gapManage(T, 0);
|
||||||
|
break;
|
||||||
|
case ReturnStmt:
|
||||||
|
gapProcess();
|
||||||
|
printf("Return Statement\n");
|
||||||
|
gapManage(T, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
gapProcess();
|
||||||
|
printf("Unknown Statement\n");
|
||||||
|
gapManage(T, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_exp(ASTNode* T)
|
||||||
|
{
|
||||||
|
handle_next_display = 0;
|
||||||
|
print_add_exp(T->right);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_add_exp(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->int_val == MUL)
|
||||||
|
{
|
||||||
|
handle_next_display = 0;
|
||||||
|
print_mul_exp(T->right);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gapProcess();
|
||||||
|
printf("AddExp");
|
||||||
|
if(T->int_val == PLUS)
|
||||||
|
{
|
||||||
|
printf(" +\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf(" -\n");
|
||||||
|
}
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_mul_exp(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->int_val == UnaryExp)
|
||||||
|
{
|
||||||
|
handle_next_display = 0;
|
||||||
|
print_unary_exp(T->right);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gapProcess();
|
||||||
|
printf("MulExp");
|
||||||
|
if(T->int_val == MUL)
|
||||||
|
{
|
||||||
|
printf(" *\n");
|
||||||
|
}
|
||||||
|
else if(T->int_val == DIV)
|
||||||
|
{
|
||||||
|
printf(" /\n");
|
||||||
|
}
|
||||||
|
else if(T->int_val == MOD)
|
||||||
|
{
|
||||||
|
printf(" %%\n");
|
||||||
|
}
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_unary_exp(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->int_val == PrimaryExp)
|
||||||
|
{
|
||||||
|
handle_next_display = 0;
|
||||||
|
print_primary_exp(T->right);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gapProcess();
|
||||||
|
printf("UnaryExp ");
|
||||||
|
switch (T->int_val)
|
||||||
|
{
|
||||||
|
case FuncRParams:
|
||||||
|
printf("%s()\n", T->symbol);
|
||||||
|
break;
|
||||||
|
case Plus:
|
||||||
|
printf("+\n");
|
||||||
|
break;
|
||||||
|
case Minus:
|
||||||
|
printf("-\n");
|
||||||
|
break;
|
||||||
|
case NOT:
|
||||||
|
printf("NOT\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_func_r_params(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
currentNum[currentLayer]--;
|
||||||
|
}
|
||||||
|
gapProcess();
|
||||||
|
printf("FuncRParams\n");
|
||||||
|
if(T->left)
|
||||||
|
{
|
||||||
|
sameGapManage(T, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_primary_exp(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->d_type == NonType)
|
||||||
|
{
|
||||||
|
handle_next_display = 0;
|
||||||
|
if(T->int_val == Exp)
|
||||||
|
{
|
||||||
|
print_exp(T->right);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print_lv_al(T->right);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gapProcess();
|
||||||
|
printf("PrimaryExp ");
|
||||||
|
if(T->d_type == Int)
|
||||||
|
{
|
||||||
|
printf("IntLiteral %d\n", T->int_val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("FloatLiteral %f\n", T->float_val);
|
||||||
|
}
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_lv_al(ASTNode* T)
|
||||||
|
{
|
||||||
|
gapProcess();
|
||||||
|
//printVarType(T->d_type);
|
||||||
|
printf("LVal %s\n", T->symbol);
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_cond(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->int_val == 0 && T->right->type == Cond)
|
||||||
|
{
|
||||||
|
handle_next_display = 0;
|
||||||
|
print_cond(T->right);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gapProcess();
|
||||||
|
printf("Cond");
|
||||||
|
if(T->int_val == OR)
|
||||||
|
{
|
||||||
|
printf(" OR\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_l_and_exp(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->int_val == 0)
|
||||||
|
{
|
||||||
|
handle_next_display = 0;
|
||||||
|
print_eq_exp(T->right);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gapProcess();
|
||||||
|
printf("LAndExp AND\n");
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_eq_exp(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->int_val == 0)
|
||||||
|
{
|
||||||
|
handle_next_display = 0;
|
||||||
|
print_rel_exp(T->right);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gapProcess();
|
||||||
|
printf("EqExp");
|
||||||
|
if(T->int_val == EQ)
|
||||||
|
{
|
||||||
|
printf(" ==\n");
|
||||||
|
}
|
||||||
|
else if(T->int_val == NE)
|
||||||
|
{
|
||||||
|
printf(" !=\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_rel_exp(ASTNode* T)
|
||||||
|
{
|
||||||
|
if(T->int_val == 0)
|
||||||
|
{
|
||||||
|
handle_next_display = 0;
|
||||||
|
print_add_exp(T->right);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gapProcess();
|
||||||
|
printf("RelExp ");
|
||||||
|
if(T->int_val == LT)
|
||||||
|
{
|
||||||
|
printf("<\n");
|
||||||
|
}
|
||||||
|
else if(T->int_val == GT)
|
||||||
|
{
|
||||||
|
printf(">\n");
|
||||||
|
}
|
||||||
|
else if(T->int_val == LE)
|
||||||
|
{
|
||||||
|
printf("<=\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf(">=\n");
|
||||||
|
}
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_exp_array(ASTNode* T)
|
||||||
|
{
|
||||||
|
gapProcess();
|
||||||
|
printf("ExpArray []\n");
|
||||||
|
gapManage(T, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_unknown(ASTNode* T)
|
||||||
|
{
|
||||||
|
currentNum[currentLayer]++;
|
||||||
|
gapProcess();
|
||||||
|
printf("Unknown\n");
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
bison -d parser.y -o parser.c
|
||||||
|
flex -o lexer.c lexer.l
|
@ -0,0 +1,101 @@
|
|||||||
|
#include "ast.h"
|
||||||
|
extern int targetNum[1024];
|
||||||
|
extern int currentNum[1024];
|
||||||
|
extern int currentLayer;
|
||||||
|
extern int handle_next_display;
|
||||||
|
|
||||||
|
void display(ASTNode* T)
|
||||||
|
{
|
||||||
|
handle_next_display = 1;
|
||||||
|
switch (T->type)
|
||||||
|
{
|
||||||
|
case Root:
|
||||||
|
print_root(T);
|
||||||
|
break;
|
||||||
|
case CompUnit:
|
||||||
|
print_comp_unit(T);
|
||||||
|
break;
|
||||||
|
case ConstDecl:
|
||||||
|
print_const_decl(T);
|
||||||
|
break;
|
||||||
|
case ConstDef:
|
||||||
|
print_const_def(T);
|
||||||
|
break;
|
||||||
|
case ConstExpArray:
|
||||||
|
print_const_exp_array(T);
|
||||||
|
break;
|
||||||
|
case ConstInitVal:
|
||||||
|
print_const_init_val(T);
|
||||||
|
break;
|
||||||
|
case ConstExp:
|
||||||
|
print_const_exp(T);
|
||||||
|
break;
|
||||||
|
case VarDecl:
|
||||||
|
print_var_decl(T);
|
||||||
|
break;
|
||||||
|
case VarDef:
|
||||||
|
print_var_def(T);
|
||||||
|
break;
|
||||||
|
case InitVal:
|
||||||
|
print_init_val(T);
|
||||||
|
break;
|
||||||
|
case InitVals:
|
||||||
|
print_init_vals(T);
|
||||||
|
break;
|
||||||
|
case FuncDef:
|
||||||
|
print_func_def(T);
|
||||||
|
break;
|
||||||
|
case FuncFParam:
|
||||||
|
print_func_f_param(T);
|
||||||
|
break;
|
||||||
|
case Block:
|
||||||
|
print_block(T);
|
||||||
|
break;
|
||||||
|
case BlockItem:
|
||||||
|
print_block_item(T);
|
||||||
|
break;
|
||||||
|
case Stmt:
|
||||||
|
print_stmt(T);
|
||||||
|
break;
|
||||||
|
case Exp:
|
||||||
|
print_exp(T);
|
||||||
|
break;
|
||||||
|
case AddExp:
|
||||||
|
print_add_exp(T);
|
||||||
|
break;
|
||||||
|
case MulExp:
|
||||||
|
print_mul_exp(T);
|
||||||
|
break;
|
||||||
|
case UnaryExp:
|
||||||
|
print_unary_exp(T);
|
||||||
|
break;
|
||||||
|
case FuncRParams:
|
||||||
|
print_func_r_params(T);
|
||||||
|
break;
|
||||||
|
case PrimaryExp:
|
||||||
|
print_primary_exp(T);
|
||||||
|
break;
|
||||||
|
case LVal:
|
||||||
|
print_lv_al(T);
|
||||||
|
break;
|
||||||
|
case Cond:
|
||||||
|
print_cond(T);
|
||||||
|
break;
|
||||||
|
case LAndExp:
|
||||||
|
print_l_and_exp(T);
|
||||||
|
break;
|
||||||
|
case EqExp:
|
||||||
|
print_eq_exp(T);
|
||||||
|
break;
|
||||||
|
case RelExp:
|
||||||
|
print_rel_exp(T);
|
||||||
|
break;
|
||||||
|
case ExpArray:
|
||||||
|
print_exp_array(T);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
handle_next_display = 0;
|
||||||
|
print_unknown(T);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,94 @@
|
|||||||
|
%option noyywrap
|
||||||
|
%option yylineno
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "ast.h"
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
int line_cnt = 1;
|
||||||
|
%}
|
||||||
|
|
||||||
|
MultilineComment "/*"([^\*]|(\*)*[^\*/])*(\*)*"*/"
|
||||||
|
SingleLineComment "//"[^\n]+
|
||||||
|
Lex_err [1-9][0-9]*[a-zA-Z]+[0-9]*|0[0-7]*[8-9a-zA-Z_]+[0-9a-zA-Z_]*
|
||||||
|
|
||||||
|
%%
|
||||||
|
"//".* { }
|
||||||
|
"/*"([^\*]|(\*)*[^\*/])*(\*)*"*/" {
|
||||||
|
int len = strlen(yytext);
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
if(yytext[i] == '\n')
|
||||||
|
line_cnt++;
|
||||||
|
}
|
||||||
|
"\n" { line_cnt++; }
|
||||||
|
[ \t] { }
|
||||||
|
"int" { return INT; }
|
||||||
|
"float" { return FLOAT; }
|
||||||
|
"void" { return VOID; }
|
||||||
|
"const" { return CONST; }
|
||||||
|
"return" { return RETURN; }
|
||||||
|
"if" { return IF; }
|
||||||
|
"else" { return ELSE; }
|
||||||
|
"while" { return WHILE; }
|
||||||
|
"break" { return BREAK; }
|
||||||
|
"continue" { return CONTINUE; }
|
||||||
|
"(" { return LP; }
|
||||||
|
")" { return RP; }
|
||||||
|
"[" { return LB; }
|
||||||
|
"]" { return RB; }
|
||||||
|
"{" { return LC; }
|
||||||
|
"}" { return RC; }
|
||||||
|
"," { return COMMA; }
|
||||||
|
";" { return SEMICOLON; }
|
||||||
|
"+" { return PLUS; }
|
||||||
|
"-" { return MINUS; }
|
||||||
|
"!" { return NOT; }
|
||||||
|
"=" { return ASSIGN; }
|
||||||
|
"*" { return MUL; }
|
||||||
|
"/" { return DIV; }
|
||||||
|
"%" { return MOD; }
|
||||||
|
"&&" { return AND; }
|
||||||
|
"||" { return OR; }
|
||||||
|
"==" { return EQ; }
|
||||||
|
"!=" { return NE; }
|
||||||
|
"<" { return LT; }
|
||||||
|
"<=" { return LE; }
|
||||||
|
">" { return GT; }
|
||||||
|
">=" { return GE; }
|
||||||
|
0[xX][0-9a-fA-F]* {
|
||||||
|
int val = 0;
|
||||||
|
int len = strlen(yytext);
|
||||||
|
for (int i = 2; i < len; i++) {
|
||||||
|
val <<= 4;
|
||||||
|
if (isdigit(yytext[i]))
|
||||||
|
val += yytext[i] - '0';
|
||||||
|
else
|
||||||
|
val += yytext[i] - 'a' + 10;
|
||||||
|
}
|
||||||
|
yylval.int_val = val;
|
||||||
|
return INT_LIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
[a-zA-Z_][a-zA-Z0-9_]* {
|
||||||
|
yylval.str_val = (char *)malloc(strlen(yytext) + 1);
|
||||||
|
strcpy(yylval.str_val, yytext);
|
||||||
|
yylval.str_val[strlen(yytext)] = '\0';
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
[0-9]*\.[0-9]+f?|[0-9]+e-?[0-9]+f? { yylval.float_val = atof(yytext); return FLOAT_LIT; }
|
||||||
|
{Lex_err} { return LEX_ERR; }
|
||||||
|
[1-9][0-9]*|0 { yylval.int_val = atoi(yytext); return INT_LIT; }
|
||||||
|
0[0-7]+ {
|
||||||
|
int val = 0;
|
||||||
|
int len = strlen(yytext);
|
||||||
|
for (int i = 1; i < len; i++)
|
||||||
|
val = (val << 3) + yytext[i] - '0';
|
||||||
|
yylval.int_val = val;
|
||||||
|
return INT_LIT;
|
||||||
|
}
|
||||||
|
. { }
|
||||||
|
%%
|
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,139 @@
|
|||||||
|
/* A Bison parser, made by GNU Bison 3.8.2. */
|
||||||
|
|
||||||
|
/* Bison interface for Yacc-like parsers in C
|
||||||
|
|
||||||
|
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
|
||||||
|
Inc.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* As a special exception, you may create a larger work that contains
|
||||||
|
part or all of the Bison parser skeleton and distribute that work
|
||||||
|
under terms of your choice, so long as that work isn't itself a
|
||||||
|
parser generator using the skeleton or a modified version thereof
|
||||||
|
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||||
|
the parser skeleton itself, you may (at your option) remove this
|
||||||
|
special exception, which will cause the skeleton and the resulting
|
||||||
|
Bison output files to be licensed under the GNU General Public
|
||||||
|
License without this special exception.
|
||||||
|
|
||||||
|
This special exception was added by the Free Software Foundation in
|
||||||
|
version 2.2 of Bison. */
|
||||||
|
|
||||||
|
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
|
||||||
|
especially those whose name start with YY_ or yy_. They are
|
||||||
|
private implementation details that can be changed or removed. */
|
||||||
|
|
||||||
|
#ifndef YY_YY_PARSER_H_INCLUDED
|
||||||
|
# define YY_YY_PARSER_H_INCLUDED
|
||||||
|
/* Debug traces. */
|
||||||
|
#ifndef YYDEBUG
|
||||||
|
# define YYDEBUG 0
|
||||||
|
#endif
|
||||||
|
#if YYDEBUG
|
||||||
|
extern int yydebug;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Token kinds. */
|
||||||
|
#ifndef YYTOKENTYPE
|
||||||
|
# define YYTOKENTYPE
|
||||||
|
enum yytokentype
|
||||||
|
{
|
||||||
|
YYEMPTY = -2,
|
||||||
|
YYEOF = 0, /* "end of file" */
|
||||||
|
YYerror = 256, /* error */
|
||||||
|
YYUNDEF = 257, /* "invalid token" */
|
||||||
|
ID = 258, /* ID */
|
||||||
|
INT_LIT = 259, /* INT_LIT */
|
||||||
|
FLOAT_LIT = 260, /* FLOAT_LIT */
|
||||||
|
INT = 261, /* INT */
|
||||||
|
FLOAT = 262, /* FLOAT */
|
||||||
|
VOID = 263, /* VOID */
|
||||||
|
CONST = 264, /* CONST */
|
||||||
|
RETURN = 265, /* RETURN */
|
||||||
|
IF = 266, /* IF */
|
||||||
|
ELSE = 267, /* ELSE */
|
||||||
|
WHILE = 268, /* WHILE */
|
||||||
|
BREAK = 269, /* BREAK */
|
||||||
|
CONTINUE = 270, /* CONTINUE */
|
||||||
|
LP = 271, /* LP */
|
||||||
|
RP = 272, /* RP */
|
||||||
|
LB = 273, /* LB */
|
||||||
|
RB = 274, /* RB */
|
||||||
|
LC = 275, /* LC */
|
||||||
|
RC = 276, /* RC */
|
||||||
|
COMMA = 277, /* COMMA */
|
||||||
|
SEMICOLON = 278, /* SEMICOLON */
|
||||||
|
MINUS = 279, /* MINUS */
|
||||||
|
NOT = 280, /* NOT */
|
||||||
|
ASSIGN = 281, /* ASSIGN */
|
||||||
|
PLUS = 282, /* PLUS */
|
||||||
|
MUL = 283, /* MUL */
|
||||||
|
DIV = 284, /* DIV */
|
||||||
|
MOD = 285, /* MOD */
|
||||||
|
AND = 286, /* AND */
|
||||||
|
OR = 287, /* OR */
|
||||||
|
EQ = 288, /* EQ */
|
||||||
|
NE = 289, /* NE */
|
||||||
|
LT = 290, /* LT */
|
||||||
|
LE = 291, /* LE */
|
||||||
|
GT = 292, /* GT */
|
||||||
|
GE = 293, /* GE */
|
||||||
|
LEX_ERR = 294, /* LEX_ERR */
|
||||||
|
THEN = 295 /* THEN */
|
||||||
|
};
|
||||||
|
typedef enum yytokentype yytoken_kind_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Value type. */
|
||||||
|
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||||
|
union YYSTYPE
|
||||||
|
{
|
||||||
|
#line 25 "parser.y"
|
||||||
|
|
||||||
|
int int_val;
|
||||||
|
float float_val;
|
||||||
|
char *str_val;
|
||||||
|
struct ASTNode *node_val;
|
||||||
|
|
||||||
|
#line 111 "parser.h"
|
||||||
|
|
||||||
|
};
|
||||||
|
typedef union YYSTYPE YYSTYPE;
|
||||||
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
|
# define YYSTYPE_IS_DECLARED 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Location type. */
|
||||||
|
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
|
||||||
|
typedef struct YYLTYPE YYLTYPE;
|
||||||
|
struct YYLTYPE
|
||||||
|
{
|
||||||
|
int first_line;
|
||||||
|
int first_column;
|
||||||
|
int last_line;
|
||||||
|
int last_column;
|
||||||
|
};
|
||||||
|
# define YYLTYPE_IS_DECLARED 1
|
||||||
|
# define YYLTYPE_IS_TRIVIAL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
extern YYSTYPE yylval;
|
||||||
|
extern YYLTYPE yylloc;
|
||||||
|
|
||||||
|
int yyparse (void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !YY_YY_PARSER_H_INCLUDED */
|
Binary file not shown.
@ -0,0 +1,201 @@
|
|||||||
|
%define parse.error verbose
|
||||||
|
%locations
|
||||||
|
%{
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "ast.h"
|
||||||
|
|
||||||
|
ASTNode *root;
|
||||||
|
|
||||||
|
extern FILE *yyin;
|
||||||
|
extern int line_cnt;
|
||||||
|
extern int yylineno;
|
||||||
|
extern char *yytext;
|
||||||
|
extern int yylex();
|
||||||
|
extern int yyparse();
|
||||||
|
//extern void yyerror(char *msg);
|
||||||
|
void yyerror(const char* fmt, ...);
|
||||||
|
int syntax_error = 0;
|
||||||
|
char filename[100];
|
||||||
|
%}
|
||||||
|
|
||||||
|
%union {
|
||||||
|
int int_val;
|
||||||
|
float float_val;
|
||||||
|
char *str_val;
|
||||||
|
struct ASTNode *node_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
%type <node_val> CompUnit ConstDecl VarDecl FuncDef ConstDef ConstInitVal VarDef InitVal FuncFParam ConstExpArray Block
|
||||||
|
%type <node_val> Root BlockItem Stmt LVal PrimaryExp UnaryExp FuncRParams MulExp Exp RelExp EqExp LAndExp LNotExp Cond ConstExp
|
||||||
|
%type <node_val> ExpArray AddExp LOrExp InitVals
|
||||||
|
//ForList
|
||||||
|
|
||||||
|
%token <str_val> ID
|
||||||
|
%token <int_val> INT_LIT
|
||||||
|
%token <float_val> FLOAT_LIT
|
||||||
|
|
||||||
|
%token <int_val> INT FLOAT VOID CONST RETURN IF ELSE WHILE BREAK CONTINUE LP RP LB RB LC RC COMMA SEMICOLON
|
||||||
|
%token <int_val> MINUS NOT ASSIGN PLUS MUL DIV MOD AND OR EQ NE LT LE GT GE LEX_ERR
|
||||||
|
//FOR INC DEC THEN
|
||||||
|
|
||||||
|
%nonassoc THEN
|
||||||
|
%nonassoc ELSE
|
||||||
|
|
||||||
|
%start Root
|
||||||
|
|
||||||
|
%%
|
||||||
|
Root: CompUnit { root = new_node(Root, NULL, NULL, $1, 0, 0, NULL, NonType); };
|
||||||
|
CompUnit: ConstDecl { $$ = new_node(CompUnit, NULL, NULL, $1, 0, 0, NULL, NonType); }
|
||||||
|
| VarDecl { $$ = new_node(CompUnit, NULL, NULL, $1, 0, 0, NULL, NonType); }
|
||||||
|
| FuncDef { $$ = new_node(CompUnit, NULL, NULL, $1, 0, 0, NULL, NonType); }
|
||||||
|
| ConstDecl CompUnit { $$ = new_node(CompUnit, $2, NULL, $1, 0, 0, NULL, NonType); }
|
||||||
|
| VarDecl CompUnit { $$ = new_node(CompUnit, $2, NULL, $1, 0, 0, NULL, NonType); }
|
||||||
|
| FuncDef CompUnit { $$ = new_node(CompUnit, $2, NULL, $1, 0, 0, NULL, NonType); };
|
||||||
|
|
||||||
|
ConstDecl: CONST INT ConstDef SEMICOLON { $$ = new_node(ConstDecl, NULL, NULL, $3, 0, 0, NULL, Int); }
|
||||||
|
| CONST FLOAT ConstDef SEMICOLON { $$ = new_node(ConstDecl, NULL, NULL, $3, 0, 0, NULL, Float); };
|
||||||
|
ConstDef: ID ConstExpArray ASSIGN ConstInitVal { $$ = new_node(ConstDef, NULL, $2, $4, 0, 0, $1, NonType); }
|
||||||
|
| ID ConstExpArray ASSIGN ConstInitVal COMMA ConstDef { $$ = new_node(ConstDef, $6, $2, $4, 0, 0, $1, NonType); };
|
||||||
|
ConstExpArray: { $$ = NULL; }
|
||||||
|
| LB ConstExp RB ConstExpArray { $$ = new_node(ConstExpArray, $4, NULL, $2, 0, 0, NULL, NonType); };
|
||||||
|
ConstInitVal: ConstExp { $$ = new_node(ConstInitVal, NULL, NULL, $1, 0, 0, NULL, NonType); }
|
||||||
|
| LC RC { $$ = new_node(ConstInitVal, NULL, NULL, NULL, 0, 0, NULL, NonType); }
|
||||||
|
| LC ConstInitVal RC { $$ = new_node(ConstInitVal, NULL, NULL, $2, 0, 0, NULL, NonType); }
|
||||||
|
| LC ConstInitVal COMMA ConstInitVal RC { $$ = new_node(ConstInitVal, $4, NULL, $2, 0, 0, NULL, NonType); };
|
||||||
|
ConstExp: MulExp { $$ = new_node(ConstExp, NULL, NULL, $1, 0, 0, NULL, NonType); }
|
||||||
|
| MulExp PLUS Exp { $$ = new_node(ConstExp, $3, NULL, $1, PLUS, 0, NULL, NonType); }
|
||||||
|
| MulExp MINUS Exp { $$ = new_node(ConstExp, $3, NULL, $1, MINUS, 0, NULL, NonType); };
|
||||||
|
|
||||||
|
VarDecl: INT VarDef SEMICOLON { $$ = new_node(VarDecl, NULL, NULL, $2, 0, 0, NULL, Int); }
|
||||||
|
| FLOAT VarDef SEMICOLON { $$ = new_node(VarDecl, NULL, NULL, $2, 0, 0, NULL, Float); };
|
||||||
|
VarDef: ID ConstExpArray { $$ = new_node(VarDef, NULL, $2, NULL, 0, 0, $1, NonType); }
|
||||||
|
| ID ConstExpArray ASSIGN InitVal { $$ = new_node(VarDef, NULL, $2, $4, 0, 0, $1, NonType); }
|
||||||
|
| ID ConstExpArray COMMA VarDef { $$ = new_node(VarDef, $4, $2, NULL, 0, 0, $1, NonType); }
|
||||||
|
| ID ConstExpArray ASSIGN InitVal COMMA VarDef { $$ = new_node(VarDef, $6, $2, $4, 0, 0, $1, NonType); };
|
||||||
|
InitVal: Exp { $$ = new_node(InitVal, NULL, NULL, $1, Exp, 0, NULL, NonType); }
|
||||||
|
| LC RC { $$ = new_node(InitVal, NULL, NULL, NULL, InitVals, 0, NULL, NonType); }
|
||||||
|
| LC InitVals RC { $$ = new_node(InitVal, NULL, NULL, $2, InitVals, 0, NULL, NonType); };
|
||||||
|
InitVals: InitVal { $$ = new_node(InitVals, NULL, NULL, $1, 0, 0, NULL, NonType); }
|
||||||
|
| InitVal COMMA InitVals { $$ = new_node(InitVals, $3, NULL, $1, 0, 0, NULL, NonType); };
|
||||||
|
|
||||||
|
FuncDef: INT ID LP RP Block { $$ = new_node(FuncDef, NULL, NULL, $5, 0, 0, $2, Int); }
|
||||||
|
| FLOAT ID LP RP Block { $$ = new_node(FuncDef, NULL, NULL, $5, 0, 0, $2, Float); }
|
||||||
|
| VOID ID LP RP Block { $$ = new_node(FuncDef, NULL, NULL, $5, 0, 0, $2, Void); }
|
||||||
|
| INT ID LP FuncFParam RP Block { $$ = new_node(FuncDef, NULL, $4, $6, 0, 0, $2, Int); }
|
||||||
|
| FLOAT ID LP FuncFParam RP Block { $$ = new_node(FuncDef, NULL, $4, $6, 0, 0, $2, Float); }
|
||||||
|
| VOID ID LP FuncFParam RP Block { $$ = new_node(FuncDef, NULL, $4, $6, 0, 0, $2, Void); };;
|
||||||
|
FuncFParam: INT ID { $$ = new_node(FuncFParam, NULL, NULL, NULL, 0, 0, $2, Int); }
|
||||||
|
| FLOAT ID { $$ = new_node(FuncFParam, NULL, NULL, NULL, 0, 0, $2, Float); }
|
||||||
|
| INT ID LB RB ExpArray { $$ = new_node(FuncFParam, NULL, NULL, $5, 0, 0, $2, Int); }
|
||||||
|
| FLOAT ID LB RB ExpArray { $$ = new_node(FuncFParam, NULL, NULL, $5, 0, 0, $2, Float); }
|
||||||
|
| INT ID COMMA FuncFParam { $$ = new_node(FuncFParam, $4, NULL, NULL, 0, 0, $2, Int); }
|
||||||
|
| FLOAT ID COMMA FuncFParam { $$ = new_node(FuncFParam, $4, NULL, NULL, 0, 0, $2, Float); }
|
||||||
|
| INT ID LB RB ExpArray COMMA FuncFParam { $$ = new_node(FuncFParam, $7, NULL, $5, 0, 0, $2, Int); }
|
||||||
|
| FLOAT ID LB RB ExpArray COMMA FuncFParam { $$ = new_node(FuncFParam, $7, NULL, $5, 0, 0, $2, Float); };
|
||||||
|
|
||||||
|
Block: LC BlockItem RC { $$ = new_node(Block, NULL, NULL, $2, 0, 0, NULL, NonType); };
|
||||||
|
BlockItem: { $$ = NULL; }
|
||||||
|
| ConstDecl BlockItem { $$ = new_node(BlockItem, $2, NULL, $1, 0, 0, NULL, NonType); }
|
||||||
|
| VarDecl BlockItem { $$ = new_node(BlockItem, $2, NULL, $1, 0, 0, NULL, NonType); }
|
||||||
|
| Stmt BlockItem { $$ = new_node(BlockItem, $2, NULL, $1, 0, 0, NULL, NonType); };
|
||||||
|
|
||||||
|
// 以下是你需要完成的语法规则和语义计算规则
|
||||||
|
//Stmt → LVal '=' Exp ';' | [Exp] ';' | Block
|
||||||
|
//| 'if' '(' Cond ')' Stmt [ 'else' Stmt ]
|
||||||
|
//| 'while' '(' Cond ')' Stmt
|
||||||
|
//| 'break' ';' | 'continue' ';'
|
||||||
|
//| 'return' [Exp] ';'
|
||||||
|
Stmt: LVal ASSIGN Exp SEMICOLON{$$ = new_node(Stmt,$1,NULL,$3,0,0,NULL,NonType);}
|
||||||
|
| Exp SEMICOLON {$$ = new_node(Stmt,NULL,NULL,$1,0,0,NULL,NonType);}
|
||||||
|
| SEMICOLON {$$ = NULL;}
|
||||||
|
| Block{$$ = new_node(Stmt,NULL,NULL,$1,0,0,NULL,NonType);}
|
||||||
|
| IF LP Cond RP Stmt {$$ = new_node(Stmt,$3,NULL,$5,0,0,NULL,NonType);}
|
||||||
|
| IF LP Cond RP Stmt ELSE Stmt {$$ = new_node(Stmt,$3,$7,$5,0,0,NULL,NonType);}
|
||||||
|
| WHILE LP Cond RP Stmt {$$ = new_node(Stmt,$3,NULL,$5,0,0,NULL,NonType);}
|
||||||
|
| BREAK SEMICOLON {$$ = NULL;}
|
||||||
|
| CONTINUE SEMICOLON {$$ = NULL;}
|
||||||
|
| RETURN SEMICOLON {$$ = NULL;}
|
||||||
|
| RETURN Exp SEMICOLON {$$ = new_node(Stmt,NULL,NULL,$2,0,0,NULL,NonType);}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Exp: AddExp { $$ = new_node(Exp, NULL, NULL, $1, 0, 0, NULL, NonType); };
|
||||||
|
AddExp: MulExp { $$ = new_node(AddExp, NULL, NULL, $1, MUL, 0, NULL, NonType); }
|
||||||
|
| MulExp PLUS AddExp { $$ = new_node(AddExp, $3, NULL, $1, PLUS, 0, NULL, NonType); }
|
||||||
|
| MulExp MINUS AddExp { $$ = new_node(AddExp, $3, NULL, $1, MINUS, 0, NULL, NonType); };
|
||||||
|
MulExp: UnaryExp { $$ = new_node(MulExp, NULL, NULL, $1, UnaryExp, 0, NULL, NonType); }
|
||||||
|
| UnaryExp MUL MulExp { $$ = new_node(MulExp, $3, NULL, $1, MUL, 0, NULL, NonType); }
|
||||||
|
| UnaryExp DIV MulExp { $$ = new_node(MulExp, $3, NULL, $1, DIV, 0, NULL, NonType); }
|
||||||
|
| UnaryExp MOD MulExp { $$ = new_node(MulExp, $3, NULL, $1, MOD, 0, NULL, NonType); };
|
||||||
|
UnaryExp: PrimaryExp { $$ = new_node(UnaryExp, NULL, NULL, $1, PrimaryExp, 0, NULL, NonType); }
|
||||||
|
| ID LP RP { $$ = new_node(UnaryExp, NULL, NULL, NULL, FuncRParams, 0, $1, NonType); }
|
||||||
|
| ID LP FuncRParams RP { $$ = new_node(UnaryExp, NULL, NULL, $3, FuncRParams, 0, $1, NonType); }
|
||||||
|
| PLUS UnaryExp { $$ = new_node(UnaryExp, NULL, NULL, $2, Plus, 0, NULL, NonType); }
|
||||||
|
| MINUS UnaryExp { $$ = new_node(UnaryExp, NULL, NULL, $2, Minus, 0, NULL, NonType); }
|
||||||
|
| NOT UnaryExp { $$ = new_node(UnaryExp, NULL, NULL, $2, NOT, 0, NULL, NonType); };
|
||||||
|
FuncRParams: Exp { $$ = new_node(FuncRParams, NULL, NULL, $1, 0, 0, NULL, NonType); }
|
||||||
|
| Exp COMMA FuncRParams { $$ = new_node(FuncRParams, $3, NULL, $1, 0, 0, NULL, NonType); };
|
||||||
|
PrimaryExp: LP Exp RP { $$ = new_node(PrimaryExp, NULL, NULL, $2, Exp, 0, NULL, NonType); }
|
||||||
|
| LVal { $$ = new_node(PrimaryExp, NULL, NULL, $1, LVal, 0, NULL, NonType); }
|
||||||
|
| INT_LIT { $$ = new_node(PrimaryExp, NULL, NULL, NULL, $1, 0, NULL, Int); }
|
||||||
|
| FLOAT_LIT { $$ = new_node(PrimaryExp, NULL, NULL, NULL, 0, $1, NULL, Float); };
|
||||||
|
LVal: ID ExpArray { $$ = new_node(LVal, NULL, NULL, $2, 0, 0, $1, NonType); };
|
||||||
|
|
||||||
|
Cond: LOrExp { $$ = new_node(Cond, NULL, NULL, $1, 0, 0, NULL, NonType); };
|
||||||
|
LOrExp: LAndExp { $$ = new_node(Cond, NULL, NULL, $1, 0, 0, NULL, NonType); }
|
||||||
|
| LAndExp OR LOrExp { $$ = new_node(Cond, $3, NULL, $1, OR, 0, 0, NonType); }
|
||||||
|
| LNotExp{ $$ = new_node(Cond, NULL, NULL, $1, 0, 0, NULL, NonType); };
|
||||||
|
|
||||||
|
LAndExp: EqExp { $$ = new_node(LAndExp, NULL, NULL, $1, 0, 0, NULL, NonType); }
|
||||||
|
| EqExp AND LAndExp { $$ = new_node(LAndExp, $3, NULL, $1, AND, 0, NULL, NonType); };
|
||||||
|
|
||||||
|
LNotExp: NOT LP EqExp RP { $$ = new_node(LNotExp, NULL, NULL, $3, 0, 0, NULL, NonType);};
|
||||||
|
|
||||||
|
EqExp: RelExp { $$ = new_node(EqExp, NULL, NULL, $1, 0, 0, NULL, NonType);}
|
||||||
|
| RelExp EQ EqExp { $$ = new_node(EqExp, $3, NULL, $1, EQ, 0, NULL, NonType); }
|
||||||
|
| RelExp NE EqExp { $$ = new_node(EqExp, $3, NULL, $1, NE, 0, NULL, NonType); };
|
||||||
|
|
||||||
|
RelExp: AddExp { $$ = new_node(RelExp, NULL, NULL, $1, 0, 0, NULL, NonType); }
|
||||||
|
| AddExp LT RelExp { $$ = new_node(RelExp, $3, NULL, $1, LT, 0, NULL, NonType); }
|
||||||
|
| AddExp GT RelExp { $$ = new_node(RelExp, $3, NULL, $1, GT, 0, NULL, NonType);}
|
||||||
|
| AddExp LE RelExp { $$ = new_node(RelExp, $3, NULL, $1, LE, 0, NULL, NonType); }
|
||||||
|
| AddExp GE RelExp { $$ = new_node(RelExp, $3, NULL, $1, GE, 0, NULL, NonType); };
|
||||||
|
|
||||||
|
ExpArray: { $$ = NULL; }
|
||||||
|
| LB Exp RB ExpArray { $$ = new_node(ExpArray, $4, NULL, $2, 0, 0, NULL, NonType); };
|
||||||
|
%%
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
int index = strlen(argv[1]) - 1;
|
||||||
|
while(index > 0 && argv[1][index - 1] != '/')
|
||||||
|
index--;
|
||||||
|
strcpy(filename, argv[1] + index);
|
||||||
|
freopen(argv[1], "r", stdin);
|
||||||
|
yyparse();
|
||||||
|
if (syntax_error == 0)
|
||||||
|
display(root);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void yyerror(char *msg) {
|
||||||
|
printf("%s:%d\n", name, yylineno);
|
||||||
|
printf("error text: %s\n", yytext);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
#include<stdarg.h>
|
||||||
|
void yyerror(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
syntax_error = 1;
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
fprintf(stderr, "%s:%d ", filename, yylineno);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
fprintf(stderr, ".\n");
|
||||||
|
}
|
Loading…
Reference in new issue