📄 phraseanalysis.cpp
字号:
// PhraseAnalysis.cpp : implementation file
//
#include "stdafx.h"
#include "My1.h"
#include "PhraseAnalysis.h"
#include "Error.h"
#include "Table.h"
#include "Symbol.h"
#include "Code.h"
class CMainFrame;
//#include "Compiler.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CPhraseAnalysis
CPhraseAnalysis::CPhraseAnalysis()
{
}
CPhraseAnalysis::CPhraseAnalysis(CCompiler * compiler)
{
mCompiler=compiler;
declbegsys+=constsym; //three keys words to begin declaration
declbegsys+=varsym;
declbegsys+=procsym;
statbegsys+=beginsym; //control keywords
statbegsys+=callsym;
statbegsys+=ifsym;
statbegsys+=whilesym;
statbegsys+=repeatsym;
facbegsys+=ident; //
facbegsys+=number;
facbegsys+=lparen; //左括号
}
void CPhraseAnalysis::Constdeclaration()
{
CError *err=mCompiler->mError;
CTable *bg=mCompiler->mTable;
if (sym==ident)
{
Getsym();
if (sym==eql || sym==becomes)
{
if (sym==becomes)
err->Add(1);
Getsym();
if (sym==number)
{
bg->Enter(constant);
Getsym();
}
else
err->Add(2);
}
else
err->Add(3);
}
else
err->Add(4);
}
void CPhraseAnalysis::Test(CSymbol s1,CSymbol s2,int n)
{
if (!s1.InSet(sym))
{
mCompiler->mError->Add(n);
s1+=s2;
while (!s1.InSet(sym)) Getsym();
}
}
void CPhraseAnalysis::Term(CSymbol fsys)
{
symbol mulop;
CSymbol symset;
symset+=fsys;
symset+=times;
symset+=slash;
Factor(symset);
while (sym==times||sym==slash)
{
mulop=sym;
Getsym();
Factor(symset);
if (mulop==times)
mCompiler->mCode->Gen(opr,0,4);
else
mCompiler->mCode->Gen(opr,0,5);
}
}
void CPhraseAnalysis::Factor(CSymbol fsys)
{
int i;
CCode *dm;
CError *err;
table_type *table;
dm=mCompiler->mCode;
err=mCompiler->mError;
table=mCompiler->mTable->table;
Test(facbegsys,fsys,24);
while (facbegsys.InSet(sym))
{
switch (sym)
{
case ident:
i=mCompiler->mTable->Position(mCompiler->mWordAnalysis->id);
if (i==0)
err->Add(11);
else{
switch (table[i].kind)
{
case constant:
dm->Gen(lit,0,table[i].val);
break;
case variable:
dm->Gen(lod,lev-table[i].level,table[i].adr);
break;
case procedure:
err->Add(21);
break;
}
}
Getsym();
break;
case number:
if (mCompiler->mWordAnalysis->num>MAX_NUMBER)
{
err->Add(31);
mCompiler->mWordAnalysis->num=0;
}
dm->Gen(lit,0,mCompiler->mWordAnalysis->num);
Getsym();
break;
case lparen:
Getsym();
Expression(fsys+=rparen);
if (sym==rparen)
Getsym();
else
err->Add(22);
break;
}
Test(fsys,facbegsys,23);
}
}
void CPhraseAnalysis::Expression(CSymbol fsys)
{
symbol addop;
CSymbol symset;
symset+=fsys;
symset+=plus;
symset+=minus;
if (sym==plus||sym==minus)
{
addop=sym;
Getsym();
Term(symset);
if (addop==minus)
mCompiler->mCode->Gen(opr,0,1);
}
else{
Term(symset);
}
while (sym==plus||sym==minus)
{
addop=sym;
Getsym();
Term(symset);
if (addop==plus)
mCompiler->mCode->Gen(opr,0,2);
else
mCompiler->mCode->Gen(opr,0,3);
}
}
void CPhraseAnalysis::Condition(CSymbol fsys)
{
symbol relop;
CSymbol s1,s2;
s1+=eql;
s1+=neq;
s1+=lss;
s1+=leq;
s1+=gtr;
s1+=geq;
if (sym==oddsym)
{
Getsym();
Expression(fsys);
mCompiler->mCode->Gen(opr,0,6);
}
else{
s2+=s1;
Expression(s2+=fsys);
if (!s1.InSet(sym))
mCompiler->mError->Add(20);
else{
relop=sym;
Getsym();
Expression(fsys);
switch (relop)
{
case eql:mCompiler->mCode->Gen(opr,0,8);break;
case neq:mCompiler->mCode->Gen(opr,0,9);break;
case lss:mCompiler->mCode->Gen(opr,0,10);break;
case geq:mCompiler->mCode->Gen(opr,0,11);break;
case gtr:mCompiler->mCode->Gen(opr,0,12);break;
case leq:mCompiler->mCode->Gen(opr,0,13);break;
}
}
}
}
void CPhraseAnalysis::Statement(CSymbol fsys)
{
int i,cx1,cx2;
table_type *table=mCompiler->mTable->table;
CError *err=mCompiler->mError;
CCode *dm=mCompiler->mCode;
CSymbol s,s2;
switch (sym)
{
case ident:
i=mCompiler->mTable->Position(mCompiler->mWordAnalysis->id);
if (i==0)
err->Add(11);
else if (table[i].kind!=variable)
{
err->Add(12);i=0;
}
Getsym();
if (sym==becomes)
Getsym();
else
err->Add(13);
Expression(fsys);
if (i>0)
dm->Gen(sto,lev-table[i].level,table[i].adr);
break;
case readsym:
Getsym();
if (sym!=lparen)
err->Add(34);
else
do{
Getsym();
i=(sym==ident) ? mCompiler->mTable->Position(mCompiler->mWordAnalysis->id):0;
if (i==0)
err->Add(35);
else
{
dm->Gen(opr,0,16);
dm->Gen(sto,lev-table[i].level,table[i].adr);
}
Getsym();
}while (sym==comma);
if (sym!=rparen)
{
err->Add(33);
while (fsys.InSet(sym)) Getsym();
}
else Getsym();
break;
case writesym:
s=fsys;
s+=rparen;
s+=comma;
Getsym();
if (sym==lparen)
{
do{
Getsym();
Expression(s);
mCompiler->mCode->Gen(opr,0,14);
}while (sym==comma);
if (sym!=rparen)
err->Add(33);
else
Getsym();
}
dm->Gen(opr,0,15);
break;
case callsym:
Getsym();
if (sym!=ident)
err->Add(14);
else{
i=mCompiler->mTable->Position(mCompiler->mWordAnalysis->id);
if (i==0) err->Add(11);
else if (table[i].kind==procedure)
dm->Gen(cal,lev-table[i].level,table[i].adr);
else
err->Add(15);
Getsym();
}
break;
case ifsym:
s=fsys;
s+=thensym;
s+=dosym;
Getsym();
Condition(s);
if (sym==thensym)
Getsym();
else
err->Add(16);
cx1=dm->cx;
dm->Gen(jpc,0,0);
s=fsys;
s+=elsesym;
Statement(s);
if (sym==elsesym)
{
Getsym();
cx2=dm->cx;
dm->Gen(jmp,0,0);
Statement(fsys);
dm->code[cx1].a=cx2+1;
dm->code[cx2].a=dm->cx;
}
else
dm->code[cx1].a=dm->cx;
break;
case beginsym:
s=fsys;
s+=semicolon;
s+=endsym;
s2=statbegsys;
s2+=semicolon;
Getsym();
Statement(s);
while (s2.InSet(sym))
{
if (sym==semicolon) Getsym();else err->Add(10);
Statement(s);
}
if (sym==endsym) Getsym(); else err->Add(17);
break;
case whilesym:
cx1=dm->cx;
Getsym();
s=fsys;
s+=dosym;
Condition(s);
cx2=dm->cx;
dm->Gen(jpc,0,0);
if (sym==dosym)
Getsym();
else
err->Add(18);
Statement(fsys);
dm->Gen(jmp,0,cx1);
dm->code[cx2].a=dm->cx;
break;
case repeatsym:
Getsym();
s=fsys;
s+=semicolon;
s+=untilsym;
cx1=dm->cx;
Statement(s);
s2=statbegsys;
s2+=semicolon;
while (s2.InSet(sym))
{
if (sym==semicolon)
Getsym();
else
err->Add(10);
Statement(s);
}
if (sym==untilsym)
{
Getsym();
Condition(fsys);
dm->Gen(jpc,0,cx1);
}
else
err->Add(25);
break;
}
Test(fsys,CSymbol(),19);
}
void CPhraseAnalysis::Block(CSymbol fsys)
{
lev++;
int tx0,cx0;
CSymbol s;
CError *err=mCompiler->mError;
CCode *dm=mCompiler->mCode;
CTable *bg=mCompiler->mTable;
dx[lev]=3;
tx0=bg->TableIndex();
bg->table[tx0].adr=dm->cx;
dm->Gen(jmp,0,0);
if (lev>MAX_LEVEL) err->Add(32);
do{// there is a no
if (sym==constsym)
{
Getsym();
HTREEITEM root=mCompiler->mFrame->m_CtrlBar.m_Function.GetRootItem();
HTREEITEM root1=mCompiler->mFrame->m_CtrlBar.m_Function.GetChildItem(root);
HTREEITEM root2=mCompiler->mFrame->m_CtrlBar.m_Function.GetNextItem(root1,TVGN_NEXT);
mCompiler->mFrame->m_CtrlBar.m_Function.InsertItem(mCompiler->mWordAnalysis->id,1,1,root2);
do{
Constdeclaration();
while (sym==comma)
{
Getsym();
Constdeclaration();
}
if (sym==semicolon) Getsym(); else err->Add(5);
}while (sym==ident);
}
else if (sym==varsym)
{
Getsym();
HTREEITEM root=mCompiler->mFrame->m_CtrlBar.m_Function.GetRootItem();
HTREEITEM root1=mCompiler->mFrame->m_CtrlBar.m_Function.GetChildItem(root);
HTREEITEM root2=mCompiler->mFrame->m_CtrlBar.m_Function.GetNextItem(root1,TVGN_NEXT);
mCompiler->mFrame->m_CtrlBar.m_Function.InsertItem(mCompiler->mWordAnalysis->id,1,1,root1);
do{
Vardeclaration();
while (sym==comma)
{
Getsym();//MessageBox(mCompiler->mWordAnalysis->id);
mCompiler->mFrame->m_CtrlBar.m_Function.InsertItem(mCompiler->mWordAnalysis->id,1,1,root1);
Vardeclaration();
}
if (sym==semicolon) Getsym(); else err->Add(5);
}while (sym==ident);
}
else if(sym==procsym){
while (sym==procsym)
{
Getsym();
if (sym==ident)
{
bg->Enter(procedure);
Getsym();
}
else err->Add(4);
if (sym==semicolon)
Getsym();
else
err->Add(5);
s=fsys;
s+=semicolon;
Block(s);
if (sym==semicolon)
{
Getsym();
s=statbegsys;
s+=ident;
s+=procsym;
Test(s,fsys,6);
}
else
err->Add(5);
}
s=statbegsys;
s+=ident;
Test(s,declbegsys,7);
}
else break;
}while (declbegsys.InSet(sym));
dm->code[bg->table[tx0].adr].a=dm->cx;
bg->table[tx0].adr=dm->cx;
bg->table[tx0].size=dx[lev];
cx0=dm->cx;
dm->Gen(intint,0,dx[lev]);
s=fsys;
s+=semicolon;
s+=endsym;
Statement(s);
dm->Gen(opr,0,0);
Test(fsys,CSymbol(),8);
lev--;
}
void CPhraseAnalysis::Vardeclaration()
{
CError *err=mCompiler->mError;
CCode *dm=mCompiler->mCode;
CTable *bg=mCompiler->mTable;
if (sym==ident)
{
bg->Enter(variable);
dx[lev]++;
Getsym();
}
else
err->Add(4);
}
void CPhraseAnalysis::Analysis()
{
Getsym();
lev=-1;
CSymbol s;
s=declbegsys;
s+=statbegsys;
s+=period;
Block(s);
}
CPhraseAnalysis::~CPhraseAnalysis()
{
}
BEGIN_MESSAGE_MAP(CPhraseAnalysis, CWnd)
//{{AFX_MSG_MAP(CPhraseAnalysis)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPhraseAnalysis message handlers
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -