flex_and_bison

master
jakeallen 1 year ago
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,116 @@
#ifndef DEF_H
#define DEF_H
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#include "stdarg.h"
#include "parser.h" //由bison根据parser.y生成
#define MAXLENGTH 200
#define DX 3*sizeof(int) /*活动记录控制信息需要的单元数,这个根据实际系统调整*/
//以下语法树结点类型、三地址结点类型等定义仅供参考,实验时一定要根据自己的理解来定义
extern int LEV; //层号
#define BLOCK -2147483647
typedef enum node_type {
CompUnit,
ConstDecl,
VarDecl,
FuncDef,
ConstDef,
ConstInitVal,
VarDef,
InitVal,
FuncFParam,
ExpArray,
Exp,
Block,
BlockItem,
Stmt,
LVal,
PrimaryExp,
UnaryExp,
LOrExp,
FuncRParams,
MulExp,
RelExp,
EqExp,
LAndExp,
LNotExp,
Cond,
ConstExp,
ConstExpArray,
BlankStmt, //空语句
ExpStmt, // 表达式语句
AssignStmt, // 赋值语句
IfStmt, // If语句
IfElseStmt, // If-Else语句
WhileStmt, // while语句
BreakStmt, // break语句
ContinueStmt, // continue语句
BlankReturnStmt, //不带返回值的return语句
AddExp,
ReturnStmt, // 带返回值的return语句
NonType,
Float,
Int,
InitVals,
Void,
Plus,
Minus,
Root
} node_type;
// AST节点(最多三个子节点lef,mid,right,当只有两节点时置mid为null):
typedef struct ASTNode {
node_type type;
struct ASTNode *left;
struct ASTNode *mid;
struct ASTNode *right;
int int_val;
float float_val;
char *symbol;
node_type d_type;
}ASTNode;
ASTNode *new_node(node_type type, ASTNode *left, ASTNode *mid, ASTNode *right, int int_val, float float_val, char *symbol, node_type d_type);
void display(ASTNode* T);
int getBranchNum(ASTNode* T);
void printVarType(node_type type);
void gapProcess();
void nextDisplay(ASTNode* T);
void nextDisplayReverse(ASTNode* T);
void print_root(ASTNode* T);
void print_comp_unit(ASTNode* T);
void print_const_decl(ASTNode* T);
void print_const_def(ASTNode* T);
void print_const_exp_array(ASTNode* T);
void print_const_init_val(ASTNode* T);
void print_const_exp(ASTNode* T);
void print_var_decl(ASTNode* T);
void print_var_def(ASTNode* T);
void print_init_val(ASTNode* T);
void print_init_vals(ASTNode* T);
void print_func_def(ASTNode* T);
void print_func_f_param(ASTNode* T);
void print_block(ASTNode* T);
void print_block_item(ASTNode* T);
void print_stmt(ASTNode* T);
void print_exp(ASTNode* T);
void print_add_exp(ASTNode* T);
void print_mul_exp(ASTNode* T);
void print_unary_exp(ASTNode* T);
void print_func_r_params(ASTNode* T);
void print_primary_exp(ASTNode* T);
void print_lv_al(ASTNode* T);
void print_cond(ASTNode* T);
void print_l_and_exp(ASTNode* T);
void print_eq_exp(ASTNode* T);
void print_rel_exp(ASTNode* T);
void print_exp_array(ASTNode* T);
void print_unknown(ASTNode* T);
#endif

Binary file not shown.

@ -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…
Cancel
Save