📄 bianyi.cpp
字号:
#include<iostream.h>
#include<stdlib.h>
#include<string.h>
enum words{ id, // 标识符 0
mainsy, // 主函数 1
ifsy, // if 2
elsesy, // else 3
intsy, // int 4
intconst, // 整形常量 5
addop, // + 6
subop, // - 7
timeop, // * 8
divop, // / 9
lpar, // ( 10
rpar, // ) 11
lbpar, // { 12
rbpar, // } 13
geop, // >= 14
goop, // > 15
leop, // <= 16
loop, // < 17
neop, // != 18
eqop, // = 19
comma, // , 20
semicolon, // ; 21
eoline, // 回车转行 22
eofile, // 文件结束 23
other // 其他错误 24
};
int CODE[200]={0}; // 词法分析生成的代码表,最大长度为200
char ID[50][10]={0}; // 标识符表最大长度为50,一个标识符的最多有效位为10
char KEYWORD[][5]={"\0","main","if","else","int"}; // 关键字表
int NEXT=0; // 代码表的当前位置
int ID_NUMBER=1; // 标识符表的当前长度
int error=0,overflow=0; // 出错和常数溢出标志
int G_next=0; // 记录语法分析读代码表的当前位置
int Line=1; // 记录源程序当前行数
int Isdigit(char); // 判断输入字符是否为数字
int Isletter(char); // 判断输入字符是否为字母
int Find_Keyword(char *);// 查找关键字表
int Find_ID(char *); // 查找标识符表
void WORD_ananlyse(); // 词法分析器
// 语法分析器子函数
void Complex_Sentence();
void Declare();
void ID_List();
void Sentence_Sec();
void Sentence();
void Condition();
void Evaluate();
void Expression();
void Exp_Item();
void Exp_Item_();
void E_Item();
void Item();
void Item_();
void WORD_analyse() // 词法分析
{
char ch; // 取输入的字符
int c_number; // 计算标识符或常数的位数
char word[10]=""; // 存放单词
while((ch=cin.peek())!='#') // 判断是否结束
{
if (ch==10) // 将eoline填入代码表
{
CODE[NEXT]=eoline;
NEXT++;
}
cin>>ch; // 读入字符
if (Isdigit(ch)) // 处理整型常数
{
int value=0; // 常数值
c_number=0; // 计算常数的位数
while(Isdigit(ch))
{
if(c_number>5||(value>3276&&ch>7)) // 判断常数是否溢出
overflow=1;
value=value*10+ch-48;
cin>>ch;
c_number++;
} cin.putback(ch); // 放回刚取的字符
CODE[NEXT]=intconst;// 将intconst填入代码表
NEXT++;
CODE[NEXT]=value; // 将常数值填入代码表
NEXT++;
}
else if(Isletter(ch)) // 接受字符串
{ int re_w; // 记录单词在关键字表或标识符表中的位置
word[0]=ch;
c_number=1;
while ((ch=cin.peek())!=' '&&c_number<10)
{
if(Isletter(ch)||Isdigit(ch))
{
word[c_number]=ch;
c_number++;
cin>>ch;
}
else break;
}
word[c_number]=0;
if((re_w=Find_Keyword(word))!=-1) // 若单词为关键字
{
CODE[NEXT]=re_w;
NEXT++;
}
else if((re_w=Find_ID(word))!=-1) // 若单词为标识符
{
CODE[NEXT]=id; // 将id填入代码表
NEXT++;
CODE[NEXT]=re_w; // 将标识符在ID[]数组的位置填入代码表
NEXT++;
}
else // 定义新的标识符
{
CODE[NEXT]=id; // 将id填入代码表
NEXT++;
strcpy(ID[ID_NUMBER],word); // 将标识符填入ID[]数组
CODE[NEXT]=ID_NUMBER; // 将标识符在ID[]数组的位置填入代码表
NEXT++;
ID_NUMBER++;
}
}
else if(ch=='!')
{
if(ch=='=')
{
cin>>ch;
CODE[NEXT]=neop; // 将neop填入代码表
NEXT++;
}
}
else if(ch=='>')
{
if(cin.peek()=='=')
{
cin>>ch;
CODE[NEXT]=geop; // 将geop填入代码表
NEXT++;
}
else // 将goop填入代码表
{ CODE[NEXT]=goop; NEXT++;}
}
else if(ch=='<')
{
if(cin.peek()=='=')
{
cin>>ch;
CODE[NEXT]=neop; // 将leop填入代码表
NEXT++;
}
else // 将loop填入代码表
{ CODE[NEXT]=loop; NEXT++;}
}
else if(ch=='=') // 将eqop填入代码表
{ CODE[NEXT]=eqop; NEXT++;}
else if(ch=='+') // 将addop填入代码表
{ CODE[NEXT]=addop; NEXT++;}
else if(ch=='-') // 将subop填入代码表
{ CODE[NEXT]=subop; NEXT++;}
else if(ch=='*') // 将timeop填入代码表
{ CODE[NEXT]=timeop; NEXT++;}
else if(ch=='/') // 将divop填入代码表
{ CODE[NEXT]=divop; NEXT++;}
else if (ch==',')
{ CODE[NEXT]=comma; NEXT++;}
else if(ch==';') // 将semicolon填入代码表
{ CODE[NEXT]=semicolon; NEXT++;}
else if(ch=='(') // 将lpar填入代码表
{ CODE[NEXT]=lpar; NEXT++;}
else if(ch==')') // 将rpar填入代码表
{ CODE[NEXT]=rpar; NEXT++;}
else if(ch=='{') // 将lbpar填入代码表
{ CODE[NEXT]=lbpar; NEXT++;}
else if(ch=='}') // 将rbpar填入代码表
{ CODE[NEXT]=rbpar; NEXT++;}
else
{ CODE[NEXT]=other; NEXT++;}
}
CODE[NEXT]=eofile; // 装入文件结束符
}
int Find_Keyword(char *word)
{ int i;
for (i=0 ; i<=5 ; i++)
{ if (!strcmp(KEYWORD[i],word)) // 找到匹配的关键字
return i;
}
return -1; // 匹配失败
}
int Find_ID(char *word)
{
int i;
for (i=1 ; i<=ID_NUMBER ; i++)
{
if (!strcmp(ID[i],word))
return i; // 找到匹配的标识符
}
return -1; // 匹配失败
}
int Isletter(char ch) // 是否为字母,是返回1 ,否返回0
{
if(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z')))
return(1);
else return(0);
}
int Isdigit(char ch) // 是否为数字,是返回1 ,否返回0
{
if((ch>='0')&&(ch<='9'))
return(1);
else return(0);
}
void match(enum words word) // 匹配当前代码
{
if (CODE[G_next]==word)
{
G_next++;
if(word==intconst||word==id)
G_next++;
}
else error=1; // 出错
while (CODE[G_next]==eoline)
{ // 记录行数
G_next++;
Line++;
}
}
void GRAMMAR_analyse() // 程序->main(){复合语句}
{
match(mainsy);
if (!error)
match(lpar);
if (!error)
match(rpar);
if (!error)
match(lbpar);
if (!error)
Complex_Sentence();
if (!error)
match(rbpar);
if (!error)
match(eofile);
}
void Complex_Sentence() // 复合语句->说明部分;复合语句|语句部分
{
if (CODE[G_next]==intsy)
{
Declare(); // 说明部分,声明变量
match(semicolon);
if (CODE[G_next]!=rbpar && CODE[G_next]!=eofile && !error)
Complex_Sentence();// 复合语句
}
else
Sentence_Sec();
}
void Declare() // 说明部分->int 变量列
{
match(intsy);
if (!error) ID_List();
}
void Sentence_Sec() // 语句部分->语句 语句部分|语句
{
while (!error && CODE[G_next]!=eoline && CODE[G_next]!=rbpar )
Sentence();
}
void Sentence() // 语句->条件语句|赋值语句|;
{
if (CODE[G_next]==ifsy)
Condition(); // 条件语句
else if (CODE[G_next]==semicolon)
match(semicolon);// 空语句
else
Evaluate(); // 赋值语句
}
void ID_List() // 变量列->id,变量列|id
{
match(id);
if(!error&&CODE[G_next]==comma)
{
match(comma);
if (!error) ID_List();
}
}
void Condition() // 条件语句->if(表达式)语句 else 语句 | if(表达式)语句
{
match(ifsy);
if (!error)
match(lpar);
if (!error)
Expression();
if (!error)
match(rpar);
if (!error)
Sentence();
if (!error && CODE[G_next]==elsesy)
{
match(elsesy); if (!error)
Sentence();
}
}
void Expression() // 表达式->表达项>表达项|表达项>=表达项|表达项<表达项
{ // |表达项<=表达项|表达项!=表达项|表达项=表达项
Exp_Item();
if (!error)
switch(CODE[G_next])
{
case geop: match(geop);
break;
case goop: match(goop);
break;
case leop: match(leop);
break;
case loop: match(loop);
break;
case neop: match(neop);
break;
case eqop: match(eqop);
break;
default: return;
}
if (!error) Exp_Item();
}
void Exp_Item() //表达项->项 表项
{
Item();
if (!error)
Exp_Item_();
}
void Exp_Item_() // 表项->+项|表项 表项->-项|表项
{
if (CODE[G_next]==addop)
{
match(addop);
if (!error)
Item();
if (!error)
Exp_Item_();
}
else if (CODE[G_next]==subop)
{
match(subop);
if (!error)
Item();
if (!error)
Exp_Item_();
}
}
void Item() // 项->子项 项’
{
E_Item();
if (!error)
Item_();
}
void Item_() // 项’->* 子项 项’ 项’->/子项 项’
{
if (CODE[G_next]==timeop)
{
match(timeop);
if (!error)
E_Item();
if (!error)
Item_();
}
else if (CODE[G_next]==divop)
{
match(divop);
if (!error)
E_Item();
if (!error)
Item_();
}
}
void E_Item() // 子项->id|num|(表项)
{
switch(CODE[G_next])
{ case id: match(id);
break;
case intconst: match(intconst);
break;
default: match(lpar);
if (!error) Exp_Item();
if (!error) match(rpar);
}
}
void Evaluate() // 赋值语句->id=表达式
{
match(id);
if (!error)
match(eqop);
if (!error)
Expression();
if (!error)
match(semicolon);
}
void main()
{
cout<<"enter the origial codes"<<endl;
WORD_analyse(); // 词法分析
GRAMMAR_analyse(); // 语法分析
cout<<"the coding table is "<<endl;
for(int i=0; i<NEXT;i++) // 输出代码表
{
cout<<CODE[i]<<" ";
if(CODE[i]==22) cout<<endl;
}
if (overflow) // 输出结果
cout <<"\n something wrong about int." <<endl;
else if (error)
cout <<"\n the " <<Line<<"th line is wrong" <<endl;
else
cout <<"\n all right!" <<endl;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -