20160119提交的编译原理实验报告,一共有三次提交。程序其实不完美。
最近分析RFC等系列文档需要涉及词法、语法、语义。于是整合一下,回顾一下。
含义介绍:
词法分析Lexical analysis或Scanning:根据代码文本区分单词类型 保留字(while if else ...),数据类型(整型,字符,浮点..),操作符(+ - * | & ...) ,若有对应单词类型继续语法分析,否 则 词法异常
语法分析Syntax analysis或Parsin:根据给定的语法,在词法分析器给的结果分析是否符合语法规则。LL分析法和LR分析法。符合继续语义分析,否则 语法异常
语义分析semantic analysis:在语法分析的基础上,给出对应语法语句的语义规则,根据语义规则得到中间代码(eg.三地址码(类似汇编))
编译实验(一)词法分析
[实验内容]
以经过改造的PASCAL语言源程序作为词法分析对象,选取它的一个适当大小的子集,可以选取一类典型单词(改造部分必须完成)。
基本要求:对源程序从左到右进行扫描,对组成源程序的字符串拼接成为词素;并把其转换成属性字输出,并管理符号表,在分析结束后将符号表顺序输出,处理词法错误(要给出错误的行号)。
[语言的改造部分]
(1)如果一个整数以“0X”开头,则按三十六进制数处理。此时后面可跟后跟0,1,…,9,A,B,…Z。词法分析时,应将三十六进制数转化为十进制整数。
如0X1AG 要转化为1672
注:PSACAL语言大小写不敏感
(2)能处理注释,注释以--开头,以换行结束。
例如: --sort by index
(3)大于等于224的整数报越界错误;标识符长度大于32报错,标识符的有效长度为8。
输入:WHILE (next<>NIL) DO BEGIN x:=6; Y:=xy+z END;
输出:
<while>
<(>
<id,next>
<<>>
<nil>
<)>
<do>
<begin>
<id, x>
<:=>
<num, 6>
<;>
<id,y>
<:=>
<id, xy>
<+>
<id, z>
<end>
<;>
部分代码小组成员的写的
使用说明:
(1) 运行.cpp文件,在当前目录生成Debug文件夹和如下文件: output.txt,.dsp,.ncb,.plg;
(2) 新建input.txt,并将output.txt和input.txt移到Debug目录下;
(3) 在input.txt中输入pascal语言,双击.exe可执行文件,在output.txt中则自动输出词法分析结果。
#include<iostream>
#include<string>
#include<vector>
using namespace std;
#define LENWords 36
#define Max10Len 8
#define Max36Len 4
string words[]={"program","function","procedure","array","const","file","lable","packed","var","record","set","type","of",
"case","do","downto","else","for","goto","if","repeat","then","to","until","while","with","forward","and","not","or",
"in","div","mod","begin","end","nil"};/*36/82,"false","true","maxint","interger","real","char","string","boolean","text",
"input","output","abs","arctan","chr","cos","eof","eoln","exp","odd","ord","pred","round","sin","sqr","sqrt","succ","trunc",
"get","new","pack","page","put","read","readln","reset","rewrite","unpack","write","writeln","longint","int64","shortint",
"single","double","ansistring","qword"*/
long int line;
int lenth;
string xiaoshu;
vector<string>worddd;
void JiaRu_In(string ans)
{
for(int i=0;i<worddd.size();i++)
if(worddd[i]==ans)return;
worddd.push_back(ans);
}
bool IsLetter_ZiMu(char c)/*判断是否为字母*/
{
if(c>='a'&&c<='z'||c>='A'&&c<='Z')
return true;
return false;
}
bool IsDigit_ShuJi(char c)/*判断是否为数字*/
{
if(c>='0'&&c<='9')
return true;
return false;
}
bool Is0X_ShiLIu(char c)/*判断数字是否为三十六进制*/
{
if(c=='x'||c=='X')return true;
return false;
}
long int jisuan(char (*c),long int sum)/*十进制值的计算函数*/
{
if( IsDigit_ShuJi(*c))
{
do
{
if(lenth<Max10Len)
sum=sum*10+(*c)-'0';
lenth++;
} while(((*c)=getchar())>='0'&&(*c)<='9');
}
if((*c)=='.')
{
lenth=0;
xiaoshu='.';
while(((*c)=getchar())>='0'&&(*c)<='9')
xiaoshu+=(*c);
}
return sum;
}
long int exchange(char (*c))/*将36进制转换为10进制*/
{
long int t=0;
while(((*c)=getchar())>='0'&&(*c)<='9'||IsLetter_ZiMu((*c)))
{
if(IsDigit_ShuJi((*c))) t=t*36+(*c)-'0';
else if((*c)>='a'&&(*c)<='z') t=t*36+(*c)-'a'+10;
else if((*c)>='A'&&(*c)<='Z') t=t*36+(*c)-'A'+10;
lenth++;
}
if(lenth>4)
{
t=1<<24;
t++;
}
return t;
}
bool judge_digitscale(long int ansInt)/*判断数字是否越界*/
{
long int a;
a=1<<24;
if(ansInt>=a)
return false;
return true;
}
void getWord(string*ans,char *c)
{
do
{
if((*c)>='A'&&(*c)<='Z')(*c)=(*c)-'A'+'a';
(*ans)+=(*c);
}
while(((*c)=getchar())=='_'||IsDigit_ShuJi((*c))||IsLetter_ZiMu((*c)));
}
bool InTheWords(string*ans)
{
for(int i=0;i<LENWords;i++)
if(words[i]==(*ans))return true;
return false;
}
void AnalyFunc()
{
bool valid;
char c=getchar();
for(;c!=EOF;)
{
for(valid=false;!valid;)
{
if(c==' '||c=='\t')c=getchar();
else if(c=='\n')
{
line++;
c=getchar();
}
else valid=true;
}
string ans="";
long int ansInt=0;
xiaoshu='\0';
lenth=0;
switch(c)
{
case '-':
c=getchar();
if(c=='-')
{
getline(cin,ans);
line++;
c=getchar();
}
else cout<<"<->"<<endl;
valid=false;
break;
case '<':
c=getchar();
if(c=='='){cout<<"<<=>"; c=getchar();}
else if(c=='>'){cout<<"<<>>"; c=getchar();}
else if(c=='<'){cout<<"<<<>"; c=getchar();}
else cout<<"<<>";
valid=false;
cout<<endl;
break;
case '>':
c=getchar();
if(c=='='){cout<<"<>=>"; c=getchar();}
else if(c=='>'){ cout<<"<>>>"; c=getchar();}
else cout<<"<>>";
valid=false;
cout<<endl;
break;
case ':':
c=getchar();
if(c=='='){cout<<"<:=>";c=getchar();}
else cout<<"<:>";
valid=false;
cout<<endl;
break;
}
if(valid)
{
if(IsDigit_ShuJi(c))
{
ansInt=c-'0';
c=getchar();
if(ansInt==0&&Is0X_ShiLIu(c))
ansInt=exchange(&c);
else ansInt=jisuan(&c,ansInt);
if(judge_digitscale(ansInt))
{
if(xiaoshu.size()==0)
cout<<"<num,"<<ansInt<<">";
else
{
cout<<"<num,"<<ansInt<<xiaoshu<<">";
}
}
else cout<<"error line"<<line<<":out of range";/*数字越界*/
}
else if(IsLetter_ZiMu(c)||c=='_')
{
getWord(&ans,&c);
if(InTheWords(&ans))
cout<<"<"<<ans<<">";
else if(ans.size()>32) cout<<"error line"<<line<<":invalid identifier";/*标识符越界,输出无效的标识*/
else
{
if(ans.size()>8)
{
ansInt=ans.size()-8;
ans.erase(8,ansInt);
}
JiaRu_In(ans);
cout<<"<id,"<<ans<<">";
}
}
else {cout<<"<"<<c<<">"; c=getchar();}/*_+_*_/_&_^_|_~_=_!_(_)_._'*/
cout<<endl;
}
}
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
line=1;
AnalyFunc();
line=0;
for(line=0;line<LENWords;line++)
cout<<line<<" "<<words[line]<<endl;
for(int i=0;i<worddd.size();i++)
cout<<line+i<<" "<<worddd[i]<<endl;
return 0;
}
编译实验(二)语法分析
采用的是手工制造SLR(1)
这个实验中的SLR(1)组员做的还有错误未订正,后面三个实验整合一起的错误比较少
[实验内容 ]
对所给语言文法的子集,构造SLR(1)分析表,编制语法分析程序,要求将错误信息输出到错误文件中,并输出分析句子的过程(显示栈的内容,采取的动作);
实验报告必须包括采用的文法,设计的思路,SLR(1)分析表,以及测试报告(输入测试例子,输出结果)。
[文法 ]
S → program id ( id_lists ); compound_stmt .
id_lists → id | id_lists , id
compound_stmt →begin optional_stmts end
optional_stmts →stmts | ε
stmts → stmt | stmts; stmt
stmt → id := expr | compound_stmt | if bool then stmt |
if bool then stmt else stmt | while bool do stmt
bool → expr < expr
expr → expr + term | term
term →term * factor | factor
factor → id | num
[样例程序(记号流版) ]
program id ( id , id ) ;
begin
id:=num;
if id<id then id:=id
else begin
while id+id<id do id:=id+num;
id:=id*num
end
end.
使用说明:
(1)运行.cpp文件,在当前目录生成Debug文件夹和如下文件: output.txt,.dsp,.ncb,.plg;
(2)新建input.txt,并将output.txt和input.txt移到Debug目录下;
(3)在input.txt中输入pascal语言,双击.exe可执行文件,在output.txt中则自动输出词法分析结果。
#include<iostream>
#include<vector>
#include<string>
using namespace std;
#define len 21
#define Hang 45
#define Lie 30
int Cnt[len]={
1,8,1,3,3,1,0,1,3,3,1,4,6,4,3,3,1,3,1,1,1};
string WenFa[len][2] = {
{"S'","->S"},
{"S","->program id(id_lists);compound_stmt."},
{"id_lists","-> id"},
{"id_lists","->id_lists,id"},
{"compound_stmt","->begin optional_stmts end"},
{"optional_stmts","->stmts"},
{"optional_stmts","->ε"},
{"stmts","->stmt"},
{"stmts","->stmts; stmt"},
{"stmt","->id := expr"},
{"stmt","->compound_stmt "},
{"stmt","->if bool then stmt "},
{"stmt","->if bool then stmt else stmt "},
{"stmt","->while bool do stmt"},
{"bool","->expr < expr"},
{"expr","->expr + term "},
{"expr","->term"},
{"term","->term * factor"},
{"term","->factor"},
{"factor","->id"},
{"factor","->num"}
};
string Lie_index[Lie]=
{
"program",
"id",
"(",
")",
";",
",",
"begin",
"end",
":=",
"if",
"then",
"else",
"while",
"do",
"<",
"+",
"*",
"num",
".",
"$",
"S",
"id_lists",
"compound_stmt",
"optional_stmts",
"stmts",
"stmt",
"bool",
"expr",
"term",
"factor",
};
int line = 1;
struct cont
{
bool move;
int to;
cont():move(true), to(-1){}
cont(bool tf, int t) :move(tf), to(t){}
/*规约:false,规约编号>0
*移入:true,移入状态>=0
接受:false,编号0
true,-1出错*/
};
cont FenXi_table[Hang][Lie];
bool IsLetter_ZiMu(char c)/*判断是否为字母*/
{
if (c >= 'a'&&c <= 'z' || c >= 'A'&&c <= 'Z')
return true;
return false;
}
void getWord(string*ans, char *c)
{
do
{
if ((*c) >= 'A' && (*c) <= 'Z')(*c) = (*c) - 'A' + 'a';
(*ans) += (*c);
} while (((*c) = getchar()) == '_' || IsLetter_ZiMu((*c)));
}
void reduce(vector<int >*sTate, vector<string>*Nsign, int index)
{
for (int i = 0; i < Cnt[index]; i++)
{
sTate->pop_back();
Nsign->pop_back();
}
}
int findIndex(string ans)
{
for(int index=0;index<Lie;index++)
if(Lie_index[index]==ans)return index;
return Lie;
}
void ShuChu(vector<int >*sTate, vector<string >*Nsign, string str, bool succ)
{
if (succ)
{
for (vector<int>::iterator iter = sTate->begin(); iter != sTate->end(); iter++)
cout << (*iter);
cout << " ";
for (vector< string >::iterator it = Nsign->begin(); it != Nsign->end(); it++)
cout << (*it) << " ";
}
else cout << line;
cout << str << endl;
}
void wordAna(vector<int>*sTate, vector<string>*Nsign)
{
bool succ = true;
bool YiJingYiRU = true;
bool flagw = false;//用于处理如果不是
string ans;
char c;
sTate->push_back(0);
Nsign->push_back("$");
c = getchar();
while (c != EOF&&succ)
{
for (bool fl=true;fl;)/*吸收空格退格换行*/
{
if (c == ' ' || c == '\t')c = getchar();
else
if (c == '\n')
{
line++;
c=getchar();
}
else fl = false;
}
/*输入词获取与处理*/
if (YiJingYiRU)
{
ans = "";
if (IsLetter_ZiMu(c))getWord(&ans, &c);
else if (c == ':')
{
c = getchar();
if (c == '=')
ans = ":=";
else
{
succ = false;
ShuChu(sTate, Nsign, " error: :=",succ);
return;
}
flagw = true;
}
else
{
ans = c;
flagw = true;
}
}
/*分析表的输入action读取*/
int li=findIndex(ans);
if(li>=Lie)
{
succ = false;
ShuChu(sTate, Nsign, " error: input",succ);
return;
}
cont temp = FenXi_table[(*sTate)[sTate->size()-1]][li];
/*移入/规约/接受/出错*/
if (temp.move&&temp.to>=0)
{
YiJingYiRU = true;
ShuChu(sTate, Nsign, " 移入",succ);
sTate->push_back(temp.to);
Nsign->push_back(ans);
if (flagw)
{
c = getchar();
flagw = false;
}
}
else if (!temp.move&&temp.to > 0)
{
YiJingYiRU = false;
string str= WenFa[temp.to][0];
ShuChu(sTate, Nsign, " 根据" + str + WenFa[temp.to][1] + "归约", succ);
reduce(sTate,Nsign, temp.to);
Nsign->push_back(str);
/*分析表的GOTO读取*/
li = findIndex(str);
if (li >= Lie)
{
succ = false;
ShuChu(sTate, Nsign, " error:input", succ);
return;
}
li = FenXi_table[(*sTate)[sTate->size() - 1]][li].to;
if (li <0)
{
succ = false;
ShuChu(sTate, Nsign, " error:GOTO", succ);
return;
}
sTate->push_back(li);
}
else if (!temp.move&&temp.to == 0)
{
ShuChu(sTate, Nsign, " 接受",succ);
return;
}
else
{
succ = false;
ShuChu(sTate, Nsign, " error",succ);
return;
}
}
}
void initial_table()
{
//------------------------input sn
FenXi_table[0][0]=cont(true,2);
FenXi_table[2][1]=cont(true,3);
FenXi_table[3][2]=cont(true,4);
FenXi_table[4][1]=cont(true,6);
FenXi_table[5][3]=cont(true,7);
FenXi_table[5][5]=cont(true,8);
FenXi_table[7][4]=cont(true,9);
FenXi_table[8][1]=cont(true,10);
FenXi_table[9][6]=cont(true,13);
FenXi_table[11][18]=cont(true,12);
FenXi_table[13][1]=cont(true,17);
FenXi_table[13][6]=cont(true,13);
FenXi_table[13][9]=cont(true,19);
FenXi_table[13][12]=cont(true,20);
FenXi_table[14][7]=cont(true,21);
FenXi_table[15][4]=cont(true,22);
FenXi_table[17][8]=cont(true,23);
FenXi_table[19][1]=cont(true,28);
FenXi_table[19][17]=cont(true,29);
FenXi_table[20][1]=cont(true,28);
FenXi_table[20][17]=cont(true,29);
FenXi_table[22][1]=cont(true,17);
FenXi_table[22][6]=cont(true,13);
FenXi_table[22][9]=cont(true,19);
FenXi_table[22][12]=cont(true,30);
FenXi_table[23][1] = cont(true, 28);
FenXi_table[23][17]=cont(true,29);
FenXi_table[24][10]=cont(true,32);
FenXi_table[25][14]=cont(true,33);
FenXi_table[25][15]=cont(true,34);
FenXi_table[26][16]=cont(true,35);
FenXi_table[30][13]=cont(true,36);
FenXi_table[31][15]=cont(true,34);
FenXi_table[32][1]=cont(true,17);
FenXi_table[32][6]=cont(true,13);
FenXi_table[32][9]=cont(true,19);
FenXi_table[32][12]=cont(true,20);
FenXi_table[33][1]=cont(true,28);
FenXi_table[33][17]=cont(true,29);
FenXi_table[34][1]=cont(true,28);
FenXi_table[34][17]=cont(true,29);
FenXi_table[35][1]=cont(true,28);
FenXi_table[35][17]=cont(true,29);
FenXi_table[36][1]=cont(true,17);
FenXi_table[36][6]=cont(true,13);
FenXi_table[36][9]=cont(true,19);
FenXi_table[36][12]=cont(true,20);
FenXi_table[37][11]=cont(true,42);
FenXi_table[38][15]=cont(true,34);
FenXi_table[39][16]=cont(true,35);
FenXi_table[42][1]=cont(true,17);
FenXi_table[42][6]=cont(true,13);
FenXi_table[42][9]=cont(true,19);
FenXi_table[42][12]=cont(true,20);
// *移入状态i,输入j,sn:FenXi_table[i][findIndex(j)]=cont(true,n);
//------------------rn
FenXi_table[6][3] =
FenXi_table[6][5] = cont(false,2 );
FenXi_table[10][3] =
FenXi_table[10][5] = cont(false, 3);
FenXi_table[12][19] = cont(false, 1);
FenXi_table[13][7] = cont(false,6 );
FenXi_table[15][7] = cont(false, 5);
FenXi_table[16][4] =
FenXi_table[16][7] = cont(false, 7);
FenXi_table[18][4] =
FenXi_table[18][7] =
FenXi_table[18][11] = cont(false,20);
FenXi_table[21][18] = cont(false,4);
FenXi_table[26][4] =
FenXi_table[26][7] =
FenXi_table[26][10] =
FenXi_table[26][11] =
FenXi_table[26][13] =
FenXi_table[26][14] =
FenXi_table[26][15] = cont(false, 16);
FenXi_table[27][4] =
FenXi_table[27][7] =
FenXi_table[27][10] =
FenXi_table[27][11] =
FenXi_table[27][13] =
FenXi_table[27][14] =
FenXi_table[27][15] =
FenXi_table[27][16] = cont(false,18 );
FenXi_table[28][4] =
FenXi_table[28][7] =
FenXi_table[28][10] =
FenXi_table[28][11] =
FenXi_table[28][13] =
FenXi_table[28][14] =
FenXi_table[28][15] =
FenXi_table[28][16] = cont(false, 19);
FenXi_table[29][4] =
FenXi_table[29][7] =
FenXi_table[29][10] =
FenXi_table[29][11] =
FenXi_table[29][13] =
FenXi_table[29][14] =
FenXi_table[29][15] =
FenXi_table[29][16] = cont(false,20);
FenXi_table[31][4] =
FenXi_table[31][7] =
FenXi_table[31][11] = cont(false, 9);
FenXi_table[37][4] =
FenXi_table[37][7] = cont(false, 11);
FenXi_table[38][10] =
FenXi_table[38][13] = cont(false, 14);
FenXi_table[39][4] =
FenXi_table[39][7] =
FenXi_table[39][10] =
FenXi_table[39][11] =
FenXi_table[39][13] =
FenXi_table[39][14] =
FenXi_table[39][15] = cont(false,15 );
FenXi_table[40][4] =
FenXi_table[40][7] =
FenXi_table[40][10] =
FenXi_table[40][11] =
FenXi_table[40][13] =
FenXi_table[40][14] =
FenXi_table[40][15] =
FenXi_table[40][16] = cont(false, 17);
FenXi_table[41][4] =
FenXi_table[41][7] =
FenXi_table[41][11] = cont(false, 13);
FenXi_table[43][4] =
FenXi_table[43][7] =
FenXi_table[43][11] = cont(false, 12);
FenXi_table[44][4] =
FenXi_table[44][7] = cont(false, 8);
//规约状态i,输入j,rn:FenXi_table[i][findIndex(j)]=cont(false,n);false,规约编号>0
//----------------GOTO n
FenXi_table[0][20] = cont(true, 1);
FenXi_table[4][21] = cont(true, 5);
FenXi_table[9][22] = cont(true, 11);
FenXi_table[13][22] = cont(true, 18);
FenXi_table[13][23] = cont(true, 14);
FenXi_table[13][24] = cont(true, 15);
FenXi_table[13][25] = cont(true, 16);
FenXi_table[19][26] = cont(true, 24);
FenXi_table[19][27] = cont(true, 25);
FenXi_table[19][28] = cont(true, 26);
FenXi_table[19][29] = cont(true, 27);
FenXi_table[20][26] = cont(true, 30);
FenXi_table[20][27] = cont(true, 25);
FenXi_table[20][28] = cont(true, 26);
FenXi_table[20][29] = cont(true, 27);
FenXi_table[22][22] = cont(true, 18);
FenXi_table[22][25] = cont(true, 44);
FenXi_table[23][27] = cont(true, 31);
FenXi_table[23][28] = cont(true, 26);
FenXi_table[23][29] = cont(true, 27);
FenXi_table[32][22] = cont(true, 18);
FenXi_table[32][25] = cont(true, 37);
FenXi_table[33][27] = cont(true, 38);
FenXi_table[33][28] = cont(true, 26);
FenXi_table[33][29] = cont(true, 27);
FenXi_table[34][28] = cont(true, 39);
FenXi_table[34][29] = cont(true, 27);
FenXi_table[35][29] = cont(true, 40);
FenXi_table[36][22] = cont(true, 18);
FenXi_table[36][25] = cont(true, 41);
FenXi_table[42][22] = cont(true, 18);
FenXi_table[42][25] = cont(true, 43);
//状态i,GOTOj,rn:FenXi_table[i][findIndex(j)]=cont(true,n);
//--------------acc
FenXi_table[1][19]=cont(false,0);
// 接受状态i,输入j,acc:FenXi_table[i][findIndex(j)]=cont(false,0);false,编号0
}
int main()
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
vector<int>sTate;
vector<string>Nsign;
initial_table();
wordAna(&sTate, &Nsign);
return 0;
}
编译实验(三)语义分析
[实验内容 ]
对所给语言文法的子集,给出SDD或SDT,编制语义分析程序,要求将错误信息输出到错误文件中,并输出输入程序对应的三地址码;
实验报告必须包括采用的文法以及相应的SDD或SDT,设计的思路,SLR(1)分析表,以及测试报告(输入测试例子,输出结果),设计的体会。
[文法 ]
S → program id ( id_lists ); compound_stmt .
id_lists → id | id_lists , id
compound_stmt →begin optional_stmts end
optional_stmts →stmts | ε
stmts → stmt | stmts; stmt
stmt → id := expr | compound_stmt | if bool then stmt |
if bool then stmt else stmt | while bool do stmt
bool → expr < expr
expr → expr + term | term
term →term * factor | factor
factor → id | num
使用说明:
(1) 将semantics.h,wordAnalyze.h,source.cpp文件放到同一目录下,运行.cpp文件,在当前目录生成Debug文件夹和如下文件: input1.txt,output.txt,.dsp,.ncb,.plg;
(2) 在Debug文件夹内新建input.txt和output.txt;
(3) 在input.txt中输入pascal语言,双击.exe可执行文件,在output.txt中则自动输出词法分析结果,会自动生成一个input1.txt保存中间结果。
[样例程序]
program test(a,b);
begin
while x+y<x do
while x+y<x do y:=y+1;
z:=z*7
end.$
输出:
LABLE0:
t0=x+y
if t0<x GOTO LABLE1
GOTO LABLE2
LABLE1:
LABLE3:
t1=x+y
if t1<x GOTO LABLE4
GOTO LABLE5
LABLE4:
t2=y+1
y=t2
GOTO LABLE3
LABLE5:
GOTO LABLE0
LABLE2:
t3=z*7
z=t3
//wordAnalyze.h
#include<iostream>
#include<string>
#include<vector>
using namespace std;
#define LENWords 36
#define Max10Len 8
#define Max36Len 4
string words[]={"program","function","procedure","array","const","file","lable","packed","var","record","set","type","of",
"case","do","downto","else","for","goto","if","repeat","then","to","until","while","with","forward","and","not","or",
"in","div","mod","begin","end","nil"};/*36/82,"false","true","maxint","interger","real","char","string","boolean","text",
"input","output","abs","arctan","chr","cos","eof","eoln","exp","odd","ord","pred","round","sin","sqr","sqrt","succ","trunc",
"get","new","pack","page","put","read","readln","reset","rewrite","unpack","write","writeln","longint","int64","shortint",
"single","double","ansistring","qword"*/
int lenth;
int line1;
string xiaoshu;
vector<string>worddd;
void JiaRu_In(string ans)
{
for(int i=0;i<worddd.size();i++)
if(worddd[i]==ans)return;
worddd.push_back(ans);
}
bool IsLetter_ZiMu(char c)/*判断是否为字母*/
{
if(c>='a'&&c<='z'||c>='A'&&c<='Z')
return true;
return false;
}
bool IsDigit_ShuJi(char c)/*判断是否为数字*/
{
if(c>='0'&&c<='9')
return true;
return false;
}
bool Is0X_ShiLIu(char c)/*判断数字是否为三十六进制*/
{
if(c=='x'||c=='X')return true;
return false;
}
long int jisuan(char (*c),long int sum)/*十进制值的计算函数*/
{
if( IsDigit_ShuJi(*c))
{
do
{
if(lenth<Max10Len)
sum=sum*10+(*c)-'0';
lenth++;
} while(((*c)=getchar())>='0'&&(*c)<='9');
}
if((*c)=='.')
{
lenth=0;
xiaoshu='.';
while(((*c)=getchar())>='0'&&(*c)<='9')
xiaoshu+=(*c);
}
return sum;
}
long int exchange(char (*c))/*将36进制转换为10进制*/
{
long int t=0;
while(((*c)=getchar())>='0'&&(*c)<='9'||IsLetter_ZiMu((*c)))
{
if(IsDigit_ShuJi((*c))) t=t*36+(*c)-'0';
else if((*c)>='a'&&(*c)<='z') t=t*36+(*c)-'a'+10;
else if((*c)>='A'&&(*c)<='Z') t=t*36+(*c)-'A'+10;
lenth++;
}
if(lenth>4)
{
t=1<<24;
t++;
}
return t;
}
bool judge_digitscale(long int ansInt)/*判断数字是否越界*/
{
long int a;
a=1<<24;
if(ansInt>=a)
return false;
return true;
}
void getWord(string*ans,char *c)
{
do
{
if((*c)>='A'&&(*c)<='Z')(*c)=(*c)-'A'+'a';
(*ans)+=(*c);
}
while(((*c)=getchar())=='_'||IsDigit_ShuJi((*c))||IsLetter_ZiMu((*c)));
}
bool InTheWords(string*ans)
{
for(int i=0;i<LENWords;i++)
if(words[i]==(*ans))return true;
return false;
}
void AnalyFunc()
{
bool valid;
char c=getchar();
for(;c!=EOF;)
{
for(valid=false;!valid;)
{
if(c==' '||c=='\t')c=getchar();
else if(c=='\n')
{
line1++;
c=getchar();
}
else valid=true;
}
string ans="";
long int ansInt=0;
xiaoshu='\0';
lenth=0;
switch(c)
{
case '-':
c=getchar();
if(c=='-')
{
getline(cin,ans);
line1++;
c=getchar();
}
else cout<<"-"<<endl;
valid=false;
break;
case '<':
c=getchar();
if(c=='='){cout<<"<="; c=getchar();}
else if(c=='>'){cout<<"<>"; c=getchar();}
else if(c=='<'){cout<<"<<"; c=getchar();}
else cout<<"<";
valid=false;
cout<<endl;
break;
case '>':
c=getchar();
if(c=='='){cout<<">="; c=getchar();}
else if(c=='>'){ cout<<">>"; c=getchar();}
else cout<<">";
valid=false;
cout<<endl;
break;
case ':':
c=getchar();
if(c=='='){cout<<":=";c=getchar();}
else cout<<":";
valid=false;
cout<<endl;
break;
}
if(valid)
{
if(IsDigit_ShuJi(c))
{
ansInt=c-'0';
c=getchar();
if(ansInt==0&&Is0X_ShiLIu(c))
ansInt=exchange(&c);
else ansInt=jisuan(&c,ansInt);
if(judge_digitscale(ansInt))
{
if(xiaoshu.size()==0)
cout<<"num "<<ansInt;
else
{
cout<<"num "<<ansInt<<xiaoshu;
}
}
else cout<<"error line"<<line1<<":out of range";/*数字越界*/
}
else if(IsLetter_ZiMu(c)||c=='_')
{
getWord(&ans,&c);
if(InTheWords(&ans))
cout<<ans;
else if(ans.size()>32) cout<<"error line"<<line1<<":invalid identifier";/*标识符越界,输出无效的标识*/
else
{
if(ans.size()>8)
{
ansInt=ans.size()-8;
ans.erase(8,ansInt);
}
JiaRu_In(ans);
cout<<"id "<<ans;
}
}
else {cout<<c; c=getchar();}/*_+_*_/_&_^_|_~_=_!_(_)_._'*/
cout<<endl;
}
}
}
void wordAnalyze()
{
//FILE*f;
//freopen_s(&f, "input.txt", "r", stdin);
//freopen_s(&f, "input1.txt", "w", stdout);
freopen("input.txt","r",stdin);
freopen("input1.txt","w",stdout);
line1=0;
AnalyFunc();
cout<<"$"<<endl;
//fclose(f);
}
//semantics.h
#include<iostream>
#include<string>
#include<vector>
#include <sstream>
using namespace std;
int lable=0;//label
int id_num = 0;//t
struct E
{
string addr_place;
string code;
string lable_true;
string lable_false;
E() :addr_place(""), code(""), lable_true(""), lable_false(""){}
};
string ToStr(int num)
{
stringstream ss;
string temp;
ss << num;
ss >> temp;
return temp;
}
void nowstr( vector<E>*expandNsign, string*itt,int li)
{
E value;
switch (li)
{
case 1://id
value.addr_place = (*itt);
break;
case 9://if出口标志存储
value.lable_false = "LABLE" + ToStr(lable++);
break;
case 11://if else标志输出
cout << " GOTO "+(*expandNsign)[(*expandNsign).size() - 4].lable_false+"\n"
<<(*expandNsign)[(*expandNsign).size() - 3].lable_false + ":" << endl;
break;
case 12://while循环标志输出
value.lable_false= "LABLE" + ToStr(lable++);
cout << value.lable_false << ":" << endl;
break;
case 17: //num
value.addr_place = (*itt);
break;
}
expandNsign->push_back(value);
}
void outstr(vector<string>*Nsign, vector<E>*expandNsign,int WenFaindex)
{
int
i = expandNsign->size();;
string str = "";
switch (WenFaindex)
{
case 20:
case 19:
case 18:
case 16:
case 10:
case 8:
case 7:
case 6:
case 5:
case 4:
case 3:
case 2:
case 1:
case 0:
(*expandNsign)[i - 1].code = "";
break;
case 17: //term->term*factor
str = "t" + ToStr(id_num++);
(*expandNsign)[i - 3].code = " " +
str + "=" + (*expandNsign)[i - 3].addr_place+"*"+(*expandNsign)[i-1].addr_place+"\n";
(*expandNsign)[i - 3].addr_place = str;
break;
case 15://expr->expr+term
str = "t" + ToStr(id_num++);
(*expandNsign)[i - 3].code = " "+
str + "=" + (*expandNsign)[i - 3].addr_place + "+" + (*expandNsign)[i - 1].addr_place+"\n";
(*expandNsign)[i - 3].addr_place = str;
break;
case 14: //bool->expr<expr
(*expandNsign)[i - 3].lable_true = "LABLE" + ToStr(lable++);
(*expandNsign)[i - 3].lable_false= "LABLE" + ToStr(lable++);
(*expandNsign)[i - 3].code = " if "+ (*expandNsign)[i - 3].addr_place + "<" + (*expandNsign)[i - 1].addr_place+
" GOTO " + (*expandNsign)[i - 3].lable_true + "\n"
+ " GOTO " + (*expandNsign)[i - 3].lable_false+"\n"
+ (*expandNsign)[i - 3].lable_true+":\n";
break;
case 13: //stmt->while bool do stmt
(*expandNsign)[i - 4].code = " GOTO " + (*expandNsign)[i - 4].lable_false + "\n"
+ (*expandNsign)[i - 3].lable_false + ":\n";
break;
case 12://stmt->if bool then stmt else stmt
(*expandNsign)[i - 6].code = (*expandNsign)[i - 6].lable_false + ":\n";
case 11://stmt->if bool them stmt
(*expandNsign)[i - 4].code = (*expandNsign)[i - 3].lable_false + ":\n"
+ (*expandNsign)[i - 4].lable_false + ":\n";
break;
case 9://stmt->id := expr
(*expandNsign)[i - 3].code = " " + (*expandNsign)[i - 3].addr_place + "=" + (*expandNsign)[i - 1].addr_place + "\n";
break;
}
}
//Source.cpp
//#include<iostream>
//#include<vector>
//#include<string>
#include"wordAnalyze.h"
#include"semantics.h"
using namespace std;
//#pragma warning(disable:4996)去掉vs的freopen_s警告
#define len 21
#define Hang 45
#define Lie 30
int Cnt[len] = {
1, 8, 1, 3, 3, 1, 0, 1, 3, 3, 1, 4, 6, 4, 3, 3, 1, 3, 1, 1, 1 };
string WenFa[len][2] = {
{ "S'", "->S" },
{ "S", "->program id(id_lists);compound_stmt." },
{ "id_lists", "-> id" },
{ "id_lists", "->id_lists,id" },
{ "compound_stmt", "->begin optional_stmts end" },
{ "optional_stmts", "->stmts" },
{ "optional_stmts", "->ε" },
{ "stmts", "->stmt" },
{ "stmts", "->stmts; stmt" },
{ "stmt", "->id := expr" },
{ "stmt", "->compound_stmt " },
{ "stmt", "->if bool then stmt " },
{ "stmt", "->if bool then stmt else stmt " },
{ "stmt", "->while bool do stmt" },
{ "bool", "->expr < expr" },
{ "expr", "->expr + term " },
{ "expr", "->term" },
{ "term", "->term * factor" },
{ "term", "->factor" },
{ "factor", "->id" },
{ "factor", "->num" }
};
string Lie_index[Lie] =
{
"program",
"id",
"(",
")",
";",
",",
"begin",
"end",
":=",
"if",
"then",
"else",
"while",
"do",
"<",
"+",
"*",
"num",
".",
"$",
"S",
"id_lists",
"compound_stmt",
"optional_stmts",
"stmts",
"stmt",
"bool",
"expr",
"term",
"factor",
};
int line = 0;
struct cont
{
bool move;
int to;
cont() :move(true), to(-1){}
cont(bool tf, int t) :move(tf), to(t){}
/*规约:false,规约编号>0
*移入:true,移入状态>=0
接受:false,编号0
true,-1出错*/
};
cont FenXi_table[Hang][Lie];
void reduce(vector<int >*sTate, vector<string>*Nsign, vector<E>*expandNsign, int index)
{
for (int i = 0; i < Cnt[index]; i++)
{
sTate->pop_back();
Nsign->pop_back();
expandNsign->pop_back();
}
}
int findIndex(string ans)
{
for (int index = 0; index<Lie; index++)
if (Lie_index[index] == ans)return index;
return Lie;
}
void ShuChu(vector<int >*sTate, vector<string >*Nsign, string str, bool succ)
{
if (succ)
{
for (vector<int>::iterator iter = sTate->begin(); iter != sTate->end(); iter++)
cout << (*iter);
cout << " ";
for (vector< string >::iterator it = Nsign->begin(); it != Nsign->end(); it++)
cout << (*it) << " ";
}
else cout << line;
cout << str << endl;
}
void getfirst(string*ans, char*c)
{
do
{
(*ans) += (*c);
} while (((*c) = getchar()) != ' ' && (*c) != '\n' && (*c) != '\t' && (*c) != EOF);
}
void wordAna(vector<int>*sTate, vector<string>*Nsign,vector<E>*expandNsign)
{
bool succ = true;
bool YiJingYiRU = true;
string ans;
string itt;
char c;
sTate->push_back(0);
Nsign->push_back("$");
c = getchar();
while (c != EOF&&succ)
{
/*输入词获取与处理*/
if (YiJingYiRU)
{
YiJingYiRU = false;
ans = "";
getfirst(&ans, &c);
line++;
if (c != '\n'&&c != EOF)
getline(cin, itt);
if (c != EOF)
c = getchar();
}
/*分析表的输入action读取*/
int li = findIndex(ans);
if (li >= Lie)
{
succ = false;
ShuChu(sTate, Nsign, " error: input", succ);
return;
}
cont temp = FenXi_table[(*sTate)[sTate->size() - 1]][li];
/*移入/规约/接受/出错*/
if (temp.move&&temp.to >= 0)
{
//--------
nowstr( expandNsign, &itt, li);
//--------
YiJingYiRU = true;
//ShuChu(sTate, Nsign, " 移入", succ);
sTate->push_back(temp.to);
Nsign->push_back(ans);
}
else if (!temp.move&&temp.to > 0)
{
YiJingYiRU = false;
string str = WenFa[temp.to][0];
//--------
outstr(Nsign, expandNsign, temp.to);
expandNsign->push_back(E());//简单的增加一个后面同时规约相同个数
//--------
//ShuChu(sTate, Nsign, " 根据" + str + WenFa[temp.to][1] + "归约", succ);
reduce(sTate, Nsign, expandNsign, temp.to);
Nsign->push_back(str);
//---
cout << (*expandNsign)[(*expandNsign).size() - 1].code;
//---
/*分析表的GOTO读取*/
li = findIndex(str);
if (li >= Lie)
{
succ = false;
ShuChu(sTate, Nsign, " error:input", succ);
return;
}
li = FenXi_table[(*sTate)[sTate->size() - 1]][li].to;
if (li <0)
{
succ = false;
ShuChu(sTate, Nsign, " error:GOTO-format", succ);
return;
}
sTate->push_back(li);
}
else if (!temp.move&&temp.to == 0)
{
//ShuChu(sTate, Nsign, " 接受", succ);
return;
}
else
{
succ = false;
ShuChu(sTate, Nsign, " error", succ);
return;
}
}
}
void initial_table()
{
//------------------------input sn
FenXi_table[0][0] = cont(true, 2);
FenXi_table[2][1] = cont(true, 3);
FenXi_table[3][2] = cont(true, 4);
FenXi_table[4][1] = cont(true, 6);
FenXi_table[5][3] = cont(true, 7);
FenXi_table[5][5] = cont(true, 8);
FenXi_table[7][4] = cont(true, 9);
FenXi_table[8][1] = cont(true, 10);
FenXi_table[9][6] = cont(true, 13);
FenXi_table[11][18] = cont(true, 12);
FenXi_table[13][1] = cont(true, 17);
FenXi_table[13][6] = cont(true, 13);
FenXi_table[13][9] = cont(true, 19);
FenXi_table[13][12] = cont(true, 20);
FenXi_table[14][7] = cont(true, 21);
FenXi_table[15][4] = cont(true, 22);
FenXi_table[17][8] = cont(true, 23);
FenXi_table[19][1] = cont(true, 28);
FenXi_table[19][17] = cont(true, 29);
FenXi_table[20][1] = cont(true, 28);
FenXi_table[20][17] = cont(true, 29);
FenXi_table[22][1] = cont(true, 17);
FenXi_table[22][6] = cont(true, 13);
FenXi_table[22][9] = cont(true, 19);
FenXi_table[22][12] = cont(true, 20);
FenXi_table[23][1] = cont(true, 28);
FenXi_table[23][17] = cont(true, 29);
FenXi_table[24][10] = cont(true, 32);
FenXi_table[25][14] = cont(true, 33);
FenXi_table[25][15] = cont(true, 34);
FenXi_table[26][16] = cont(true, 35);
FenXi_table[30][13] = cont(true, 36);
FenXi_table[31][15] = cont(true, 34);
FenXi_table[32][1] = cont(true, 17);
FenXi_table[32][6] = cont(true, 13);
FenXi_table[32][9] = cont(true, 19);
FenXi_table[32][12] = cont(true, 20);
FenXi_table[33][1] = cont(true, 28);
FenXi_table[33][17] = cont(true, 29);
FenXi_table[34][1] = cont(true, 28);
FenXi_table[34][17] = cont(true, 29);
FenXi_table[35][1] = cont(true, 28);
FenXi_table[35][17] = cont(true, 29);
FenXi_table[36][1] = cont(true, 17);
FenXi_table[36][6] = cont(true, 13);
FenXi_table[36][9] = cont(true, 19);
FenXi_table[36][12] = cont(true, 20);
FenXi_table[37][11] = cont(true, 42);
FenXi_table[38][15] = cont(true, 34);
FenXi_table[39][16] = cont(true, 35);
FenXi_table[42][1] = cont(true, 17);
FenXi_table[42][6] = cont(true, 13);
FenXi_table[42][9] = cont(true, 19);
FenXi_table[42][12] = cont(true, 20);
// *移入状态i,输入j,sn:FenXi_table[i][findIndex(j)]=cont(true,n);
//------------------rn
FenXi_table[6][3] =
FenXi_table[6][5] = cont(false, 2);
FenXi_table[10][3] =
FenXi_table[10][5] = cont(false, 3);
FenXi_table[12][19] = cont(false, 1);
FenXi_table[13][7] = cont(false, 6);
FenXi_table[15][7] = cont(false, 5);
FenXi_table[16][4] =
FenXi_table[16][7] = cont(false, 7);
FenXi_table[18][4] =
FenXi_table[18][7] =
FenXi_table[18][11] = cont(false, 10);
FenXi_table[21][7] =
FenXi_table[21][11] =
FenXi_table[21][18] = cont(false, 4);
FenXi_table[26][4] =
FenXi_table[26][7] =
FenXi_table[26][10] =
FenXi_table[26][11] =
FenXi_table[26][13] =
FenXi_table[26][14] =
FenXi_table[26][15] = cont(false, 16);
FenXi_table[27][4] =
FenXi_table[27][7] =
FenXi_table[27][10] =
FenXi_table[27][11] =
FenXi_table[27][13] =
FenXi_table[27][14] =
FenXi_table[27][15] =
FenXi_table[27][16] = cont(false, 18);
FenXi_table[28][4] =
FenXi_table[28][7] =
FenXi_table[28][10] =
FenXi_table[28][11] =
FenXi_table[28][13] =
FenXi_table[28][14] =
FenXi_table[28][15] =
FenXi_table[28][16] = cont(false, 19);
FenXi_table[29][4] =
FenXi_table[29][7] =
FenXi_table[29][10] =
FenXi_table[29][11] =
FenXi_table[29][13] =
FenXi_table[29][14] =
FenXi_table[29][15] =
FenXi_table[29][16] = cont(false, 20);
FenXi_table[31][4] =
FenXi_table[31][7] =
FenXi_table[31][11] = cont(false, 9);
FenXi_table[37][4] =
FenXi_table[37][7] = cont(false, 11);
FenXi_table[38][10] =
FenXi_table[38][13] = cont(false, 14);
FenXi_table[39][4] =
FenXi_table[39][7] =
FenXi_table[39][10] =
FenXi_table[39][11] =
FenXi_table[39][13] =
FenXi_table[39][14] =
FenXi_table[39][15] = cont(false, 15);
FenXi_table[40][4] =
FenXi_table[40][7] =
FenXi_table[40][10] =
FenXi_table[40][11] =
FenXi_table[40][13] =
FenXi_table[40][14] =
FenXi_table[40][15] =
FenXi_table[40][16] = cont(false, 17);
FenXi_table[41][4] =
FenXi_table[41][7] =
FenXi_table[41][11] = cont(false, 13);
FenXi_table[43][4] =
FenXi_table[43][7] =
FenXi_table[43][11] = cont(false, 12);
FenXi_table[44][4] =
FenXi_table[44][7] = cont(false, 8);
//规约状态i,输入j,rn:FenXi_table[i][findIndex(j)]=cont(false,n);false,规约编号>0
//----------------GOTO n
FenXi_table[0][20] = cont(true, 1);
FenXi_table[4][21] = cont(true, 5);
FenXi_table[9][22] = cont(true, 11);
FenXi_table[13][22] = cont(true, 18);
FenXi_table[13][23] = cont(true, 14);
FenXi_table[13][24] = cont(true, 15);
FenXi_table[13][25] = cont(true, 16);
FenXi_table[19][26] = cont(true, 24);
FenXi_table[19][27] = cont(true, 25);
FenXi_table[19][28] = cont(true, 26);
FenXi_table[19][29] = cont(true, 27);
FenXi_table[20][26] = cont(true, 30);
FenXi_table[20][27] = cont(true, 25);
FenXi_table[20][28] = cont(true, 26);
FenXi_table[20][29] = cont(true, 27);
FenXi_table[22][22] = cont(true, 18);
FenXi_table[22][25] = cont(true, 44);
FenXi_table[23][27] = cont(true, 31);
FenXi_table[23][28] = cont(true, 26);
FenXi_table[23][29] = cont(true, 27);
FenXi_table[32][22] = cont(true, 18);
FenXi_table[32][25] = cont(true, 37);
FenXi_table[33][27] = cont(true, 38);
FenXi_table[33][28] = cont(true, 26);
FenXi_table[33][29] = cont(true, 27);
FenXi_table[34][28] = cont(true, 39);
FenXi_table[34][29] = cont(true, 27);
FenXi_table[35][29] = cont(true, 40);
FenXi_table[36][22] = cont(true, 18);
FenXi_table[36][25] = cont(true, 41);
FenXi_table[42][22] = cont(true, 18);
FenXi_table[42][25] = cont(true, 43);
//状态i,GOTOj,rn:FenXi_table[i][findIndex(j)]=cont(true,n);
//--------------acc
FenXi_table[1][19] = cont(false, 0);
// 接受状态i,输入j,acc:FenXi_table[i][findIndex(j)]=cont(false,0);false,编号0
}
void worda()
{
// FILE*f;
// freopen_s(&f, "input1.txt", "r", stdin);
// freopen_s(&f, "output.txt", "w", stdout);
freopen("input1.txt","r",stdin);
freopen("output.txt","w",stdout);
vector<int>sTate;
vector<string>Nsign;
vector<E>expandNsign;
initial_table();
wordAna(&sTate, &Nsign,&expandNsign);
// fclose(f);
}
int main()
{
wordAnalyze();
worda();
return 0;
}