📄 myparser.y
字号:
%{
/****************************************************************************
myparser.y
ParserWizard generated YACC file.
Date: 2005年11月21日
****************************************************************************/
#include "mylexer.h"
#include "interpret.h"
#include <fstream>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
int currentlever = 0; //当前层数
const int MAXENDCODE = 1024; //目标代码数组的最大值
int EndCode[MAXENDCODE]; //目标代码数组
int codeindex = 0; //写目标代码是的下标变量
char NameStack[30][30]; //变量名暂存数组
int stackindex=0; //已存变量名的最大下标
int varlength; //变量的长度
int vardispl; //偏移
int errorcount=0; //错误的个数
int warningcount=0; //警告的个数
%}
/////////////////////////////////////////////////////////////////////////////
// declarations section
%start ProgDef
%include {
#include "symbol.h"
enum IdType;
class symbol;
class symboltable;
}
// attribute type
%union
{
char str[20];
int Iv;
bool Bv;
int CH;
char OP;
struct { int sta,en;} Sta_end;
struct { int outwhile,conti;} _WBD;
struct { int varlen,displ;} _SubProg;
struct { int value; IdType type;} _CIB;
struct { int len,value;IdType type;} _Expr;
struct { int sta,en; IdType type; symbol* compsym;} _ArrD;
struct { int len; IdType type; symbol* sym;}_Var;
}
%token <str> ID
%token <Iv> NUMBER
%token <Bv> TRUE FALSE
%token PROGRAM
%token <CH> PROCEDURE
%token <CH> BEG
%token <CH> END
%token <CH> VAR
%token <CH> CONST
%token <CH> TYPE
%token <CH> ARRAY
%token <CH> DD
%token <CH> OF
%token <CH> RECORD
%token <CH> BOOLEAN
%token <CH> INTEGER
%token WHILE
%token DO
%token IF
%token THEN
%token ELSE
%token READ
%token WRITE
%token ASSIGN
%token LE
%token GE
%token NE
%token OR AND NOT DIV MOD
//优先级及结合性定义
%left ASSIGN
%left OR
%left AND
%right NOT
%nonassoc '<' '>' '=' LE GE NE
%left '+' '-'
%left '*' DIV MOD
%right UMINUS
//%nonassoc hiheest
%type <_SubProg> SubProg
%type <CH> ConstDef ConstDefList ConstDefState
%type <CH> TypeDef TypeDefList TypeDefState
%type <CH> TypeOfRecord DomainList RecordSection DomainNameList
%type <CH> VarDef VarDefList VarDefState VarList
%type <CH> ProceDefList ProceDef FormParaList ParaDef
%type <CH> Statement StateList AsignState
%type <CH> ISE IBT Wh
%type <_WBD> WBD
%type <CH> CompState ProQ CompQ
%type <_CIB> ConstNum
%type <_ArrD> TypeOfArray TypeName
%type <Sta_end> IndexDomain
%type <OP> RelationOp
%type <_Expr> Expr BoolExpr
%type <_Var> Variable
%type <CH> ProceState
%type <CH> RealParaList
%type <CH> RealPara
%type <CH> ProgDef
// parser name
%name myparser
// class definition
{
public:
symboltable * symtable; //符号表的根节点
symboltable * currentsymtable; //当前符号表的节点指针
symbol* symlist[30]; //用于存储一组变量的节点指针
int symlistindex; //已存变量的节点指针的下标(当前未存)
bool checkvar; //是否是函数的参数列表
bool checkparam; //函数参数是否是值参(true为var型,不复制,否则复制)
symbol** ParamArray; //过程调用时参数的节点数组指针
int IsParamIndex; //当前访问的参数下标
public:
void clearPsym()
{
for(int i=0;i<30;i++)
{
symlist[i]=NULL;
}
symlistindex = 0;
}
//查找过程名为name的符号表,前提是每个过程名都不相同
symboltable* searchProce(char* name,symboltable* child)
{
symboltable* temp=child;
while(temp)
{
if(strcmp((temp->m_procesymbol)->m_name,name)==NULL)
return temp;
else
{
//查找孩子
symboltable* tempchild = searchProce(name,temp->m_childtable);
//查找兄弟
if(tempchild)
return tempchild;
else
temp=temp->m_siblingtable;
}
}
return NULL;
}
}
// constructor
{
clearPsym();
}
// destructor
{
// place any extra cleanup code here
symtable->deletechild(symtable);
}
// attribute type
%include {
#ifndef YYSTYPE
#define YYSTYPE int
#endif
}
%%
/////////////////////////////////////////////////////////////////////////////
// rules section
/*<程序>->Program<程序名>;<块体>*/
ProgDef: PROGRAM ID
{
symtable = new symboltable(currentlever,NULL,NULL);
currentsymtable = symtable;
symtable->install($2, symtable->symbolList,CProce);
EndCode[codeindex]=24;
EndCode[codeindex+4]=yylexerptr->yylineno;
codeindex=codeindex+5;
}
';' SubProg progQ
{
EndCode[1]=$5.varlen; //过程中变量的长度
EndCode[2]=3*EndCode[1];
EndCode[3]=$5.displ; //过程语句开始时的偏移
EndCode[codeindex] = 7; //程序结束
cout<<"succeed"<<endl;
}
;
progQ: '.'
|
{
warningcount++;
cout<<"warning"<<warningcount<<":缺少结尾\".\"。"<<endl;
}
;
/*<块体>->[<常数定义部分>][<类型定义部分>][<变量定义部分>]{<过程定义部分>}<复合语句>*/
SubProg: ConstDef TypeDef VarDef ProceDefList CompState
{
$$.varlen=$3;
$$.displ=$5;
}
| TypeDef VarDef ProceDefList CompState
{
$$.varlen=$2;
$$.displ=$4;
}
| ConstDef VarDef ProceDefList CompState
{
$$.varlen=$2;
$$.displ=$4;
}
| VarDef ProceDefList CompState
{
$$.varlen=$1;
$$.displ=$3;
}
| ConstDef TypeDef ProceDefList CompState
{
$$.varlen=0;
$$.displ=$4;
}
| TypeDef ProceDefList CompState
{
$$.varlen=0;
$$.displ=$3;
}
| ConstDef ProceDefList CompState
{
$$.varlen=0;
$$.displ=$3;
}
| ProceDefList CompState
{
$$.varlen=0;
$$.displ=$2;
}
;
/*<常数定义部分>->const <常数定义>{<常数定义>}
<常数定义>-><常数名>=<常数>;*/
ConstDef: CONST ConstDefList ';'
;
ConstDefList: ConstDefList ';' ConstDefState
| ConstDefState
;
ConstDefState: ID '=' ConstNum
{
symbol* temp;
temp = currentsymtable->install($1,$3.type);
if(temp==NULL)
{
errorcount++;
cout<<"error"<<errorcount<<"h("<<yylexerptr->yylineno<<"):该常量已存在。"<<endl;
}
else
temp->SetSimpleValue($3.value);
}
| ID ASSIGN ConstNum
{
warningcount++;
cout<<"warning"<<warningcount<<"h("<<yylexerptr->yylineno<<"):常量不能赋值"<<endl;
symbol* temp;
temp = currentsymtable->install($1,$3.type);
if(temp==NULL)
{
errorcount++;
cout<<"error"<<errorcount<<"h("<<yylexerptr->yylineno<<"):该常量已存在。"<<endl;
}
else
temp->SetSimpleValue($3.value);
}
/* | ConstNum '=' ConstNum
{
warningcount++;
cout<<"warning"<<warningcount<<"h("<<yylexerptr->yylineno<<"):不能给常数赋值"<<endl;
}
| ConstNum ASSIGN ConstNum
{
warningcount++;
cout<<"warning"<<warningcount<<"h("<<yylexerptr->yylineno<<"):不能给常数赋值"<<endl;
}
*/ ;
/*<类型定义部分>->type<类型定义>{<类型定义>}
<类型定义>-><类型名>=<新类型>;
<新类型>-><数组类型>|<记录类型>*/
TypeDef: TYPE TypeDefList ';'
;
TypeDefList: TypeDefList ';' TypeDefState
| TypeDefState
;
TypeDefState: ID '=' TypeOfArray
{
currentsymtable->install($1,$3.sta,$3.en,$3.type,$3.compsym);
}
| ID '=' TypeOfRecord
{
currentsymtable->install($1,symlist,DRecord);
}
;
/*<数组类型>->array[<下标域>]of<类型名>
<下标域>-><常数>..<常数>*/
TypeOfArray: ARRAY '[' IndexDomain ']' OF TypeName
{
$$.type = $6.type;
$$.compsym = $6.compsym;
$$.sta = $3.sta;
$$.en = $3.en;
}
;
IndexDomain: ConstNum DD ConstNum
{
if($1.type==CInt && $3.type==CInt)
{
$$.sta = $1.value;
$$.en = $3.value;
}
else
{
errorcount++;
cout<<"error"<<errorcount<<"h("<<yylexerptr->yylineno<<"): 数组定义的下标不是常量"<<endl;
}
}
;
TypeName: INTEGER
{
$$.type = VInt;
$$.compsym = NULL;
}
| BOOLEAN
{
$$.type = VBool;
$$.compsym = NULL;
}
| ID //新类型名
{
symboltable* temp;
temp = currentsymtable->search($1);
if(temp)
{
if(temp->m_tempsymbol->m_type==DArray||temp->m_tempsymbol->m_type==DRecord)
{
$$.compsym = temp->m_tempsymbol;
$$.type = temp->m_tempsymbol->m_type;
}
else
{
errorcount++;
cout<<"error"<<errorcount<<"h("<<yylexerptr->yylineno<<"):"<<$1<<"不是新类型名"<<endl;
}
}
else
{
errorcount++;
cout<<"error"<<errorcount<<"h("<<yylexerptr->yylineno<<"):新类型"<<$1<<"不存在"<<endl;
}
}
;
/*<记录类型>->record <域表> end
<域表>-><记录节>{;<记录节>}
<记录节>-><域名>{,<域名>}:<类型名>*/
TypeOfRecord: RECORD
{
clearPsym();
}
DomainList END
;
DomainList: DomainList ';' RecordSection
| RecordSection
;
RecordSection: {stackindex=-1;} DomainNameList ':' TypeName
{
for(int i = 0; i <= stackindex; i++)
{
if(!$4.compsym &&($4.type==VInt||$4.type==VBool))//普通类型
{
symlist[symlistindex] = new symbol();
symlist[symlistindex]->create(NameStack[i],$4.type);
symlist[symlistindex]->m_length=1;
symlistindex++;
}
else
if($4.compsym &&($4.type == DArray||$4.type == DRecord))//新类型
{
symlist[symlistindex] = new symbol();
if($4.type == DArray)
symlist[symlistindex]->create(NameStack[i], VArray,$4.compsym);
if($4.type == DRecord)
symlist[symlistindex]->create(NameStack[i], VRecord,$4.compsym);
symlist[symlistindex]->m_length = $4.compsym->m_length;
symlistindex++;
}
else
{
errorcount++;
cout<<"error"<<errorcount<<"h("<<yylexerptr->yylineno<<"):"<<" 域定义错误"<<endl;
}
}
}
;
DomainNameList: DomainNameList ',' ID
{
stackindex++;
if(stackindex>=30)
cout<<"stackindex is small."<<endl;
else
{
for(int i=0;i<stackindex;i++)
if(strcmp(NameStack[stackindex],$3)==NULL)
{
break;
}
if(i==stackindex)
strcpy(NameStack[stackindex],$3);
else
{
stackindex--;
warningcount++;
cout<<"warning"<<warningcount<<"h("<<yylexerptr->yylineno<<"):"<<$3<<"重复"<<endl;
}
}
}
| ID
{
stackindex++;
if(stackindex>=30)
cout<<"stackindex is small."<<endl;
else
strcpy(NameStack[stackindex],$1);
}
;
/*<变量定义部分>->var <变量定义>{<变量定义>}
<变量定义>-><变量组>;
<变量组>-><变量名>{,<变量名>}:<类型名>*/
VarDef: {vardispl=3;}
VAR
{
checkvar = false; //不是参数定义
varlength=0; //变量的长度
}
VarDefList ';'
{
$$=varlength;
}
;
VarDefList: VarDefList ';' VarDefState
{}
| VarDefState
{}
;
VarDefState: {stackindex=-1;} VarList ':' TypeName
{
symbol* temp;
if(checkvar==false)
{
for(int i = 0; i <= stackindex; i++)
{
if(!$4.compsym && ($4.type==VInt||$4.type==VBool))//普通类型
{
temp=currentsymtable->install(NameStack[i], $4.type);
temp->m_value = vardispl;
vardispl++;
}
else
if($4.compsym && $4.type == DArray)
{
temp=currentsymtable->install(NameStack[i], VArray, $4.compsym);
temp->m_value = vardispl;
vardispl=vardispl + $4.compsym->m_length;
}
else
if($4.compsym && $4.type == DRecord)
{
temp=currentsymtable->install(NameStack[i], VRecord, $4.compsym);
temp->m_value = vardispl;
vardispl=vardispl + $4.compsym->m_length;
}
else
{
// errorcount++;
}
}
if($4.compsym)
{
varlength = varlength +$4.compsym->m_length * $2;
}
else
{
varlength = varlength + $2;
}
}
else//过程参数
{
if(checkparam)
{
for(int i = 0; i <= stackindex; i++)
{
symlist[symlistindex++]=currentsymtable->install(NameStack[i],
$4.type,1,$4.compsym,checkparam);
}
$$ = stackindex + 1;
}
else
{
int mlen;
for(int i = 0; i <= stackindex; i++)
{
if($4.compsym)
{
mlen=$4.compsym->m_length;
}
else
mlen=1;
symlist[symlistindex++]=currentsymtable->install(NameStack[i],
$4.type,mlen,$4.compsym,checkparam);
}
$$ = (stackindex + 1) * mlen;
}
}
}
;
VarList: VarList ',' ID
{
stackindex++;
if(stackindex>=30)
cout<<"stackindex is small."<<endl;
strcpy(NameStack[stackindex],$3);
$$ = $1+1;
}
| ID
{
stackindex++;
if(stackindex>=30)
cout<<"stackindex is small."<<endl;
strcpy(NameStack[stackindex],$1);
$$ = 1;
}
;
/*<过程定义>->procedure <过程名><过程块>;
<过程块>->[(<形参表>)];<块体>
<形参表>-><参数定义>{;<参数定义>}
<参数定义>->[var]<变量名>*/
ProceDefList: /*empty*/
| ProceDefList ProceDef ';'
;
ProceDef: PROCEDURE ID
{
currentsymtable=currentsymtable->insertchild($2);
currentlever++;
clearPsym();
EndCode[codeindex]=23;
EndCode[codeindex+4]=yylexerptr->yylineno;
currentsymtable->codebegin=codeindex;
codeindex=codeindex+5;
varlength=0;
}
'('FormParaList')'
{
currentsymtable->install($2,symlist,CProce);
}
';' ProQ SubProg
{
EndCode[$9+1]=$10.varlen;
EndCode[$9+2]=EndCode[$9+1]*3;
EndCode[$9+3]=$10.displ-$9;
EndCode[codeindex++]=6;
EndCode[codeindex++]=$5;
currentsymtable=currentsymtable->m_parenttable;
currentlever--;
}
| PROCEDURE ID ';'
{
currentsymtable=currentsymtable->insertchild($2);
currentlever++;
EndCode[codeindex]=23;
EndCode[codeindex+4]=yylexerptr->yylineno;
currentsymtable->codebegin=codeindex;
codeindex=codeindex+5;
currentsymtable->install($2,symlist,CProce);
}
ProQ SubProg
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -