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;
输出:
<(>
<<>>
<)>
<:=>
<;>
<:=>
<+>
<;>
部分代码小组成员的写的
使用说明:
(1) 运行.cpp文件,在当前目录生成Debug文件夹和如下文件: output.txt,.dsp,.ncb,.plg;
(2) 新建input.txt,并将output.txt和input.txt移到Debug目录下;
(3) 在input.txt中输入pascal语言,双击.exe可执行文件,在output.txt中则自动输出词法分析结果。
#include#include #include 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 worddd; void JiaRu_In(string ans) { for(int i=0;i ='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 ='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 "< "; c=getchar();} else if(c=='>'){cout<<"<<>>"; c=getchar();} else if(c=='<'){cout<<"<<<>"; c=getchar();} else cout<<"<<>"; valid=false; cout< ': c=getchar(); if(c=='='){cout<<"<>=>"; c=getchar();} else if(c=='>'){ cout<<"<>>>"; c=getchar();} else cout<<"<>>"; valid=false; cout< ";c=getchar();} else cout<<"<:>"; valid=false; cout< "; else { cout<<" "; } } else cout<<"error line"< "; else if(ans.size()>32) cout<<"error line"< 8) { ansInt=ans.size()-8; ans.erase(8,ansInt); } JiaRu_In(ans); cout<<" "; } } else {cout<<"<"< "; c=getchar();}/*_+_*_/_&_^_|_~_=_!_(_)_._'*/ cout<
编译实验(二)语法分析
采用的是手工制造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 → exprexpr → expr + term | term
term →term * factor | factor
factor → id | num
[样例程序(记号流版) ]
program id ( id , id ) ;
begin
id:=num;
if idelse begin
while id+idid:=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#include #include 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 + 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 *sTate, vector *Nsign, int index) { for (int i = 0; i pop_back(); Nsign->pop_back(); } } int findIndex(string ans) { for(int index=0;index *sTate, vector *Nsign, string str, bool succ) { if (succ) { for (vector ::iterator iter = sTate->begin(); iter != sTate->end(); iter++) cout <<(*iter); cout <<" "; for (vector ::iterator it = Nsign->begin(); it != Nsign->end(); it++) cout <<(*it) <<" "; } else cout < *sTate, vector *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 sTate; vector 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 → exprexpr → 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+ywhile x+y z:=z*7
end.$
输出:
LABLE0:
t0=x+y
if t0GOTO LABLE2
LABLE1:
LABLE3:
t1=x+y
if t1GOTO LABLE5
LABLE4:
t2=y+1
y=t2
GOTO LABLE3
LABLE5:
GOTO LABLE0
LABLE2:
t3=z*7
z=t3
//wordAnalyze.h #include#include #include 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 worddd; void JiaRu_In(string ans) { for(int i=0;i ='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 ='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 '){cout<<"<>"; c=getchar();} else if(c=='<'){cout<<"<<"; c=getchar();} else cout<<"<"; valid=false; cout< ': c=getchar(); if(c=='='){cout<<">="; c=getchar();} else if(c=='>'){ cout<<">>"; c=getchar();} else cout<<">"; valid=false; cout< 32) cout<<"error line"< 8) { ansInt=ans.size()-8; ans.erase(8,ansInt); } JiaRu_In(ans); cout<<"id "<
//semantics.h #include#include #include #include 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 < > temp; return temp; } void nowstr( vector *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 + ":" < push_back(value); } void outstr(vector *Nsign, vector *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 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//#include //#include #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 + 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 *sTate, vector *Nsign, vector *expandNsign, int index) { for (int i = 0; i pop_back(); Nsign->pop_back(); expandNsign->pop_back(); } } int findIndex(string ans) { for (int index = 0; index *sTate, vector *Nsign, string str, bool succ) { if (succ) { for (vector ::iterator iter = sTate->begin(); iter != sTate->end(); iter++) cout <<(*iter); cout <<" "; for (vector ::iterator it = Nsign->begin(); it != Nsign->end(); it++) cout <<(*it) <<" "; } else cout < *sTate, vector *Nsign,vector *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 sTate; vector Nsign; vector expandNsign; initial_table(); wordAna(&sTate, &Nsign,&expandNsign); // fclose(f); } int main() { wordAnalyze(); worda(); return 0; }
LL 分析法和 LR 分析法