?? syntax.cpp
字號:
/*
FileName: syntax.cpp
Author: LiWen
Create: 2005-12-17
Last Modified: 2005-12-30
Discription: 語法分析和語義分析處理模塊
*/
#include "compiler.h"
//////////////////////////////////////////////////////////////////////////////////////////////
//語法分析中的錯誤一般有兩種:詞寫錯或者詞漏寫。但只有在特殊情況下才能分辨出到底屬于那種錯誤
//為了使語法分析盡可能的進行下去,在處理錯誤時,均認為是漏寫錯誤錯誤,當一個語法分析單位結束
//后,對其后跟符號集進行檢測,直到找到后跟符號集為止,再進行下一個語法單位的分析
//這樣做,不可避免的會在出錯的語法單元內相繼報告出一些無效錯誤,我們只能根據特殊情況來修正
//
//
#define iskeyword(a) (a>=beginsym && a<=procsym)
#define isrelation(a) (a>=eql && a<=geq)
#define isoperation(a) (a>=)
#define isseparator(a) (a>=lparen&&a<=period)
#define isstatebegin(a) (a==ident||a==callsym||a==beginsym||a==ifsym||a==whilesym||a==readsym||a==writesym)
/**********************后跟符號集**************************/
#define isstatefollow(a) (a==period||a==semicolon||a==endsym)
#define isprocbodyfollow(a) (a==period||a==semicolon)
#define isprocdeclfollow(a) (a==procsym||isstatebegin(a))
#define isvarfollow(a) isprocdeclfollow(a)
#define isconstfollow(a) (a==varsym||isprocdeclfollow(a))
#define iscdtfollow(a) (a==dosym||a==thensym)
#define isexpfollow(a) (isrelation(a)||isstatefollow(a)||a==dosym||a==thensym||a==rparen||a==comma)
#define istermfollow(a) (isexpfollow(a)||a==minus||a==plus)
#define isfactorfollow(a) (istermfollow(a)||a==times||a==slash)
extern symbol sym;
extern int row;
extern char word[];
extern int num;
extern TABLE table[];
extern int tx;
extern INSTRUCTION codelist[];
extern int cx;
/*=======================================================
函數:program
參數:無
描述:處理整個代碼
返回:正常0,否則TMNT
========================================================*/
int program(){
PRT_PROCBODY(0);
if(sym == period)
return 0;
PRT_REPORT(MISSING_PERIOD);
if(getsym()!=TMNT){
PRT_REPORT(UNEXPECTED_EXTERN_CODE);
}
return 0;
}
/*=======================================================
函數:probody
參數:層數
描述:處理過程體,其第一個詞型在sym中,當它返回時
sym中為下一個語法結構的第一個詞型
不檢查開始符號集,交付statement處理
返回:正常0,否則TMNT
========================================================*/
int procbody(int lev){
int dx = 3;
int tx0,dx0,cx0;
if(lev>LEVMAX){
PRT_REPORT(PROC_LEV_TOO_DEEP);
}
tx0 = tx; //記錄
dx0 = dx;
cx0 = cx;
table[tx0].addr = cx; //useful in call procedure outside
PRT_TRANSFORM(JMP,0,0); //先為0,0,后面修改
if(sym == constsym){
PRT_CONSTDECLARE(lev,&dx);
}
if(sym == varsym){
PRT_VARDECLARE(lev,&dx);
}
while(sym == procsym){
PRT_PROCDECLARE(lev,&dx);
}
codelist[cx0].a = cx;
table[tx0].addr = cx;
PRT_TRANSFORM(INT,0,dx);
PRT_STATEMENT(lev,&dx);
PRT_TABLEPOP(tx-tx0);
PRT_TRANSFORM(OPR,0,0);
if(!isprocbodyfollow(sym)){
PRT_REPORT(UNEXPECTED_PROCBODY_FOLLOW);
while(!isprocbodyfollow(sym)){
PRT_GETSYM();
}
}
return 0;
}
/*=======================================================
函數:constdeclare
參數:層數,層偏移指針
描述:處理常量聲明
返回:正常0,否則TMNT
========================================================*/
int constdeclare(int lev,int* pdx){
int i;
PRT_GETSYM();
while(1){
if(sym == ident){
i = tablesearch(word);
if(i!=0 && table[i].lev == lev){
PRT_REPORT(IDENT_REDECLARED);
}
PRT_GETSYM();
}else{
PRT_REPORT(IDENT_IN_CONST_EXPECTING);
}
if(sym == eql){
PRT_GETSYM();
}else{
PRT_REPORT(EQL_IN_CONST_EXPECTING);
}
if(sym == number){
PRT_TABLEINSERT(lev,cst,pdx);
PRT_GETSYM();
}else{
PRT_REPORT(NUM_IN_CONST_EXPECTING);
}
if(sym == comma){
PRT_GETSYM();
}else if(sym == semicolon){
PRT_GETSYM();
break;
}else{
PRT_REPORT(MISSING_SEMICOLON_IN_CONST);
break;
}
}
if(!isconstfollow(sym)){
PRT_REPORT(UNEXPECTED_CONST_FOLLOW);
while(!isconstfollow(sym)){
PRT_GETSYM();
}
}
return 0;
}
/*=======================================================
函數:vardeclare
參數:層數,層偏移指針
描述:處理變量聲明
返回:正常0,否則TMNT
========================================================*/
int vardeclare(int lev, int* pdx){
int i;
PRT_GETSYM();
while(1){
if(sym == ident){
i = tablesearch(word);
if(i!=0 && table[i].lev == lev){
PRT_REPORT(IDENT_REDECLARED);
}
PRT_GETSYM();
}else{
PRT_REPORT(IDENT_IN_VAR_EXPECTING);
}
PRT_TABLEINSERT(lev,var,pdx);
if(sym == comma){
PRT_GETSYM();
}else if(sym == semicolon){
PRT_GETSYM();
break;
}else{
PRT_REPORT(MISSING_SEMICOLON_IN_VAR);
}
}
if(!isvarfollow(sym)){
PRT_REPORT(UNEXPECTED_VAR_FOLLOW);
while(!isvarfollow(sym)){
PRT_GETSYM();
}
}
return 0;
}
int procdeclare(int lev,int*pdx){
int i;
PRT_GETSYM();
if(sym == ident){
i = tablesearch(word);
if(i!=0 && table[i].lev == lev){
PRT_REPORT(IDENT_REDECLARED);
}
PRT_TABLEINSERT(lev,proc,pdx);
PRT_GETSYM();
}else{
PRT_REPORT(IDENT_IN_PROC_EXPECTING);
}
if(sym == semicolon){
PRT_GETSYM();
}else{
PRT_REPORT(MISSING_SEMICOLON_IN_PROC);
}
PRT_PROCBODY(lev+1);
if(sym == semicolon){
PRT_GETSYM();
}else{
PRT_REPORT(MISSING_SEMICOLON_END_PROC);
}
if(!isprocdeclfollow(sym)){
PRT_REPORT(UNEXPECTED_PROCDECL_FOLLOW);
while(!isprocdeclfollow(sym)){
PRT_GETSYM();
}
}
return 0;
}
int statement(int lev,int* pdx){
int i;
int tcx,ccx; //for jpc and PRT_CONDITION
switch(sym){
case ident:
i = tablesearch(word);
if(i == 0){
PRT_REPORT(VAR_UNDECLARED);
PRT_TABLEINSERT(lev,var,pdx);
}else if(table[i].kind == constsym){
PRT_REPORT(IDENT_CONST_IN_ASSIGN);
}else if(table[i].kind == proc){
PRT_REPORT(IDENT_PROC_IN_ASSIGN);
}
PRT_GETSYM();
if(sym != becomes){
PRT_REPORT(BECOMES_EXPECTING_IN_ASSIGN);
break;
}
PRT_GETSYM();
PRT_EXP(lev,pdx);
PRT_TRANSFORM(STO,lev-table[i].lev,table[i].addr);
break;
case ifsym:
PRT_GETSYM();
PRT_CONDITION(lev,pdx);
if(sym == thensym){
PRT_GETSYM();
}else{
PRT_REPORT(THEN_EXPECTING_IN_IF);
}
tcx = cx;
PRT_TRANSFORM(JPC,0,0);
PRT_STATEMENT(lev,pdx);
codelist[tcx].a = cx;
break;
case whilesym:
PRT_GETSYM();
ccx = cx;
PRT_CONDITION(lev,pdx); // if PRT_CONDITION false jmp
tcx = cx;
PRT_TRANSFORM(JPC,0,0);
if(sym == dosym){
PRT_GETSYM();
}else{
PRT_REPORT(DO_EXPECTING_IN_WHILE);
}
PRT_STATEMENT(lev,pdx);
PRT_TRANSFORM(JMP,0,ccx);
codelist[tcx].a = cx;
break;
case callsym:
PRT_GETSYM();
if(sym == ident){
i = tablesearch(word);
if(i == 0){
PRT_REPORT(PROC_UNDECLARED);
}else if(table[i].kind != proc){
PRT_REPORT(PROC_EXPECTING_IN_CALL);
}
PRT_TRANSFORM(CAL,lev-table[i].lev,table[i].addr);
PRT_GETSYM();
}else{
PRT_REPORT(PROC_EXPECTING_IN_CALL);
}
break;
case readsym:
PRT_GETSYM();
if(sym == lparen){
do{
PRT_GETSYM();
if(sym == ident){
i = tablesearch(word);
if(i == 0){
PRT_REPORT(VAR_UNDECLARED);
}else if(table[i].kind == constsym){
PRT_REPORT(IDENT_CONST_IN_READ);
}else if(table[i].kind == proc){
PRT_REPORT(IDENT_PROC_IN_READ);
}
PRT_TRANSFORM(OPR,0,16);
PRT_TRANSFORM(STO,lev-table[i].lev,table[i].addr);
PRT_GETSYM();
}else if(iskeyword(sym)){
PRT_REPORT(KEYWORD_APPEAR_IN_READ);
}else{
PRT_REPORT(IDENT_EXPECTING_IN_READ);
}
}while(sym == comma);
}else{
PRT_REPORT(MISSING_LPAREN);
}
if(sym == rparen){
PRT_GETSYM();
}else{
PRT_REPORT(MISSING_RPAREN);
}
break;
case writesym:
PRT_GETSYM();
if(sym != lparen){
PRT_REPORT(MISSING_LPAREN);
}else{
do{
PRT_GETSYM();
PRT_EXP(lev,pdx);
PRT_TRANSFORM(OPR,0,14);
}while(sym == comma);
}
if(sym == rparen){
PRT_GETSYM();
}else{
PRT_REPORT(MISSING_RPAREN);
}
PRT_TRANSFORM(OPR,0,15);
break;
case beginsym:
PRT_GETSYM();
PRT_STATEMENT(lev,pdx);
while(isstatebegin(sym) || sym == semicolon){
if(sym==semicolon){
PRT_GETSYM();
}else{
PRT_REPORT(MISSING_SEMICOLON_IN_STATEMENT);
}
PRT_STATEMENT(lev,pdx);
}
if(sym == endsym){
PRT_GETSYM();
}else{
PRT_REPORT(MISSING_END);
}
break;
default:
if(isstatefollow(sym))
break;
PRT_REPORT(UNEXPECTED_STATEMENT_BEGIN);
PRT_GETSYM();
break;
}
if(!isstatebegin(sym)&&!isstatefollow(sym)){
PRT_REPORT(UNEXPECTED_STATEMENT_FOLLOW);
while(!isstatefollow(sym)){
PRT_GETSYM();
}
}
return 0;
}
int expression(int lev,int*pdx){
enum symbol opr = sym;
if(sym == plus || sym == minus){
PRT_GETSYM();
}
PRT_TERM(lev,pdx);
if(opr == minus){
PRT_TRANSFORM(OPR,0,1);
}
while(sym == plus || sym == minus){
opr = sym;
PRT_GETSYM();
PRT_TERM(lev,pdx);
if(opr == plus){
PRT_TRANSFORM(OPR,0,2);
}else if(opr == minus){
PRT_TRANSFORM(OPR,0,3);
}
}
return 0;
}
int term(int lev,int* pdx){
int opr;
PRT_FACTOR(lev,pdx);
while(sym == times || sym == slash){
opr = (sym == times)?4:5;
PRT_GETSYM();
PRT_FACTOR(lev,pdx);
PRT_TRANSFORM(OPR,0,opr);
}
return 0;
}
int factor(int lev,int* pdx){
int i;
if(sym == ident){
i = tablesearch(word);
if(i == 0){
PRT_REPORT(VAR_UNDECLARED);
}else if(table[i].kind == proc){
PRT_REPORT(IDENT_PROC_IN_EXP);
}else if(table[i].kind == cst){
PRT_TRANSFORM(LIT,0,table[i].val);
}else if(table[i].kind == var){
PRT_TRANSFORM(LOD,lev-table[i].lev,table[i].addr);
}
PRT_GETSYM();
}else if(sym == number){
PRT_TRANSFORM(LIT,0,num);
PRT_GETSYM();
}else if(sym == lparen){
PRT_GETSYM();
PRT_EXP(lev,pdx);
//PRT_GETSYM();
if(sym == rparen){
PRT_GETSYM();
}else{
PRT_REPORT(MISSING_RPAREN);
}
}
if(!isstatebegin(sym)&&!isfactorfollow(sym)){
PRT_REPORT(UNEXPECTED_FACTOR_FOLLOW);
while(!isfactorfollow(sym)){
PRT_GETSYM();
}
}
return 0;
}
int condition(int lev,int* pdx){
int opr;
if(sym == oddsym){
PRT_GETSYM();
PRT_EXP(lev,pdx);
return 0;
}
PRT_EXP(lev,pdx);
if(!isrelation(sym)){
PRT_REPORT(RELATIONOPR_EXPECTING_IN_CDT);
return 0;
}
opr = sym - eql +8; //8 -> opr 中 eql 的操作碼
PRT_GETSYM();
PRT_EXP(lev,pdx);
PRT_TRANSFORM(OPR,0,opr);
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -