📄 pl0doc.cpp
字号:
// PL0Doc.cpp : implementation of the CPL0Doc class
//
#include "stdafx.h"
#include "PL0.h"
#include "Show.h"
#include "AnotherShow.h"
#include "PL0Doc.h"
#include "Instruction.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CPL0Doc
IMPLEMENT_DYNCREATE(CPL0Doc, CDocument)
BEGIN_MESSAGE_MAP(CPL0Doc, CDocument)
//{{AFX_MSG_MAP(CPL0Doc)
ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
ON_COMMAND(ID_SYNTAX_ANALYZE, OnSyntaxAnalyze)
ON_COMMAND(ID_WORD_ANALYZE, OnWordAnalyze)
ON_COMMAND(ID_WORD_ANALYZE_FILE, OnWordAnalyzeFile)
ON_COMMAND(ID_WORD_ANALYZE_SEE, OnWordAnalyzeSee)
ON_COMMAND(ID_CODES_ANALYZE, OnCodesAnalyze)
ON_COMMAND(ID_EXECUTE, OnExecute)
ON_COMMAND(ID_CODESVIEW, OnCodesview)
ON_COMMAND(IDM_Instru, OnInstru)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPL0Doc construction/destruction
CPL0Doc::CPL0Doc()
{
// TODO: add one-time construction code here
for(int i=0;i<=KeywordTotal;i++) keyword[i].Empty();
keyword[1]+="begin";
keyword[2]+="end";
keyword[3]+="if";
keyword[4]+="then";
keyword[5]+="var";
keyword[6]+="const";
keyword[7]+="procedure";
keyword[8]+="call";
keyword[9]+="write";
keyword[10]+="read";
keyword[11]+="while";
keyword[12]+="do";
keyword[13]+="+";
keyword[14]+="-";
keyword[15]+="*";
keyword[16]+="/";
keyword[17]+=":=";
keyword[18]+="<";
keyword[19]+="<=";
keyword[20]+="=";
keyword[21]+=">";
keyword[22]+=">=";
keyword[23]+=".";
keyword[24]+="(";
keyword[25]+=")";
keyword[26]+=";";
keyword[27]+=",";
keyword[28]+="#";
keyword[29]+="odd";
//TX=0;
sym_line = 1;
TX=1;
err[1]="常数说明中的' = '写成' := '。";
err[2]="常数说明中的' = '后应该是数字。";
err[3]="常数说明中的标识符后应该是' = '。";
err[4]="const,var,procedure后应该为标识符。";
err[5]="漏掉了' , '或' ; '。";
err[6]="过程说明后的符号不正确(应该是语句开始符,或过程定义符)。";
err[7]="' ; '后应该是过程说明。";
err[8]="程序体内语句部分的后跟符不正确。";
err[9]="程序结尾丢了'.'。";
err[10]="语句之间漏了';'。";
err[11]="标识符未说明。";
err[12]="赋值语句中,赋值号左部标识符属性应该是变量。";
err[13]="赋值语句左部标识符后应该是赋值号':='。";
err[14]="call后应该为标识符。";
err[15]="call后标识符应该为过程名。";
err[16]="条件语句中丢了'then'。";
err[17]="前面丢了'end'或';'。";
err[18]="while型循环语句中丢了'do'。";
err[19]="语句后的符合不正确。";
err[20]="应该为关系运算符。";
err[21]="表达式内标识符属性不能是过程。";
err[22]="表达式中漏掉')'。";
err[23]="因子后的非法符合。";
err[24]="表达式的开始符不能式此符合。";
err[25]="标识符定义重复";
err[26]="过程说明中,标识符后漏掉了';'。";
err[27]="' , '后应该是标识符。";
err[31]="数越界。";
err[32]="read语句括号中的标识符不是变量。";
err[33]="未定义的运算类型!";
}
CPL0Doc::~CPL0Doc()
{
}
BOOL CPL0Doc::OnNewDocument()
{
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
TX=1;
CIndex=0;
defconstant.Empty(); //置空常量表
defsymbol.Empty(); //置空变量表
twoelement.Empty(); //置空二元组表
CView* cv;
POSITION p=GetFirstViewPosition();
cv=GetNextView(p);
cv=GetNextView(p);
cv->SetWindowText("");
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CPL0Doc serialization
void CPL0Doc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CPL0Doc diagnostics
#ifdef _DEBUG
void CPL0Doc::AssertValid() const
{
CDocument::AssertValid();
}
void CPL0Doc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CPL0Doc commands
BOOL CPL0Doc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
// TODO: Add your specialized creation code here
CString text;
CFile f;
if(!f.Open(lpszPathName,CFile::modeRead)) return false;//按输入文件名与其路径,打开文件
int length=f.GetLength();
char *temp=new char[length+1];
f.Read(temp,length);
for(int i=0;i<length;i++) text+=temp[i];//文件内容全部加载到text中去
delete temp;
f.Close();
CView* cv;
POSITION p=GetFirstViewPosition();
cv=GetNextView(p);
cv=GetNextView(p);
cv->SetWindowText(text);//将文件内容添加到view 中去
TX=1;
CIndex=0;
defconstant.Empty(); //置空常量表
defsymbol.Empty(); //置空变量表
twoelement.Empty(); //置空二元组表
return TRUE;
}
BOOL CPL0Doc::CanCloseFrame(CFrameWnd* pFrame)
{
// TODO: Add your specialized code here and/or call the base class
return CDocument::CanCloseFrame(pFrame);
}
BOOL CPL0Doc::OnSaveDocument(LPCTSTR lpszPathName)
{
// TODO: Add your specialized code here and/or call the base class
CView* cv;
POSITION p=GetFirstViewPosition();
cv=GetNextView(p);
cv=GetNextView(p);
CString text;
cv->GetWindowText(text);//得到view中的数据
CString pn;
pn=lpszPathName;
if(pn.Find(".txt")<0) pn+=".txt";
CFile f;
if(!f.Open(pn,CFile::modeCreate|CFile::modeReadWrite)) return false;
int length=text.GetLength();
char *temp=new char[length+1];
for(int i=0;i<length;i++) temp[i]=text.GetAt(i);
f.Write(temp,length);//写到文档中去
delete temp;
f.Close();
return true;
//return CDocument::OnSaveDocument(lpszPathName);
}
void CPL0Doc::DeleteContents()
{
// TODO: Add your specialized code here and/or call the base class
CDocument::DeleteContents();
}
void CPL0Doc::OnFileSaveAs()
{
// TODO: Add your command handler code here
CString PathName;
CFileDialog dlg(false,"txt","PL0源文件",NULL,"文本文档|*.txt|所有文件(*.*)|*.*||");
if(dlg.DoModal()==IDOK) PathName=dlg.GetPathName();
else return;
CView* cv;
POSITION p=GetFirstViewPosition();
cv=GetNextView(p);
cv=GetNextView(p);
CString text;
cv->GetWindowText(text);
CFile f;
if(!f.Open(PathName,CFile::modeCreate|CFile::modeWrite)) return;
int length=text.GetLength();
char *temp=new char[length+1];
for(int i=0;i<length;i++) temp[i]=text.GetAt(i);
f.Write(temp,length);
delete temp;
f.Close();
}
//搜索关键字
int CPL0Doc::SearchKeyWord(CString str)//是否是关键字,是哪种关键字
{
for(int i=KeywordTotal;i>0;i--)
if(!keyword[i].Compare(str)) break;
return i;
}
//打印关键字
CString CPL0Doc::OutputKeyWord()
{
CString str,temp;
for(int i=1;i<=KeywordTotal;i++){
temp.Empty();
temp.Format("%d",i);
str+=(temp+","+keyword[i]+"\n");
}
return str;
}
//词法分析取字母
char CPL0Doc::GetChar(int n)
{
if(n){
char ch;
if(nPreChar<source.GetLength())
{
ch=source.GetAt(nPreChar);
nPreChar++;
if(ch==10)
{
nPreLine++;
sym_column=0;
}
else
{
sym_column++;
InPoint.SetRow(nPreLine);
}
// InPoint.SetColumn(sym_column);
return ch;
}
else return (char)127;
}
else{
CView* cv;
POSITION p=GetFirstViewPosition();
cv=GetNextView(p);
cv=GetNextView(p);
cv->GetWindowText(source);
nPreChar=0;
nPreLine=1;//行标的初始化
sym_column=0;
sym_word=sym_column;
return (char)0;
}
}
//程序
void CPL0Doc::program()
{
block(0,0);
if(sym==23)
Advance();//'.'
else error(9);//丢掉了结尾符
}
//子程序
void CPL0Doc::block(int lev, int tx)
{
if(sym==6){//const
do{
Advance();//向前读入一个单词
if(sym==888){
CString temp=sym_name;
if(test(temp,lev,tx)) error(25);//标识符说明重复
Advance();
if(sym==20){//'='
Advance();
if(sym==999){//数字
enter(temp,CON,lev,sym_val,0,0);//,PreTEI->line,PreTEI->column
Advance();
}
else if(sym==13)
{
Advance();
if(sym==999)
{
enter(temp,CON,lev,sym_val,0,0);//,PreTEI->line,PreTEI->column
Advance();
}
else error(2);
}
else if(sym==14)
{
Advance();
if(sym==999)
{
enter(temp,CON,lev,-sym_val,0,0);//,PreTEI->line,PreTEI->column
Advance();
}
else
error(2);
}
else error(2);//'='后应该是数字
}
else if(sym==17) error(1);//'='写成了':='
else error(3);//标识符后应该是'='
}
else error(4);//const、var、procedure后应该为标识符
}while(sym==27);//','
if(sym==26) Advance();//';'
else error(5);//漏掉了','或';'
}
if(sym==5){//var
do{
Advance();
if(sym==888){
if(test(sym_name,lev,tx)) error(25);//标识符说明重复
enter(sym_name,VAR,lev,0,0,0);//,PreTEI->line,PreTEI->column
Advance();
}
else error(4);//const、var、procedure后应该为标识符
}while(sym==27);//','
if(sym==26) Advance();//';'
else error(5);//漏掉了','或';'
}
while(sym==7){//'procedure'
Advance();
if(sym==888){
if(test(sym_name,lev,tx)) error(25);//标识符说明重复
enter(sym_name,PRO,lev,0,0,0);//,PreTEI->line,PreTEI->column
Advance();
if(sym==26){//';'
Advance();
block(lev+1,TX);
if(sym==26) Advance();//';'
else error(6);//过程说明中,标识符后漏掉了';'
}
else error(26);//过程说明中,标识符后漏掉了';'
}
else error(4);//const、var、procedure后应该为标识符
}
statement(lev,tx);
}
//句子
void CPL0Doc::statement(int lev, int tx)
{
if(sym==888){//赋值语句
if(test(sym_name,lev,tx,CON) || test(sym_name,lev,tx,PRO)) error(12);//赋值语句中,左部标识符应是变量
else if(!test(sym_name,lev,tx,VAR)) error(11);//变量未定义
Advance();
if(sym==17){// :=
Advance();
expression(lev,tx);
}
else error(13);//赋值语句中,标识符后应是赋值符合 :=
}
else if(sym==8){//call
Advance();
if(sym==888){
if(test(sym_name,lev,tx,CON) || test(sym_name,lev,tx,VAR)) error(15);//call后应该为过程名
else if(!test(sym_name,lev,tx,PRO)) error(15);//call后应该为过程名
Advance();
}
else error(14);//call后应该为标识符
}
else if(sym==1){//begin
Advance();
statement(lev,tx);
while(sym==26){//";"
Advance();
statement(lev,tx);
}
if(sym==2) Advance();//end
else error(17);//丢"end"或";"
}
else if(sym==3){//"if"
Advance();
condition(lev,tx);
if(sym==4){//"then"
Advance();
statement(lev,tx);
}
else error(16);//丢了"then"
}
else if(sym==11){//"while"
Advance();
condition(lev,tx);
if(sym==12){//"do"
Advance();
statement(lev,tx);
}
else error(18);//丢了"do"
}
else if(sym==10){//"read"
Advance();
if(sym==24){// "("
Advance();
if(sym==888){//标识符
if(test(sym_name,lev,tx,CON) || test(sym_name,lev,tx,PRO)) error(32);//read语句括号中标识符不是变量
else if(!test(sym_name,lev,tx,VAR)) error(11);//变量未定义
Advance();
while(sym==27){//","
Advance();
if(sym==888){
if(test(sym_name,lev,tx,CON) || test(sym_name,lev,tx,PRO)) error(32);//read语句括号中标识符不是变量
else if(!test(sym_name,lev,tx,VAR)) error(11);//变量未定义
Advance();
}
else error(27);//' , '后应该是标识符。
}
if(sym==25) Advance();//")"
else error(22);//漏掉")"
}
else error(32);//read语句括号中标识符不是变量
}
else error(24);//表达式开始符应该是"("
}
else if(sym==9){//write
Advance();
if(sym==24){//"("
do{
Advance();
expression(lev,tx);
}while(sym==27);//','
if(sym==25) Advance();//")"
else error(22);//漏掉")"
}
else error(24);//表达式开始符应该是"("
}
}
//条件
void CPL0Doc::condition(int lev, int tx)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -