编译原理实验报告

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;
}




LL 分析法和 LR 分析法
  • 6
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
设计思想 (1)程序主体结构部分: 说明部分 %% 规则部分 %% 辅助程序部分 (2)主体结构的说明 在这里说明部分告诉我们使用的LETTER,DIGIT, IDENT(标识符,通常定义为字母开头的字母数字串)和STR(字符串常量,通常定义为双引号括起来的一串字符)是什么意思.这部分也可以包含一些初始化代码.例如用#include来使用标准的头文件和前向说明(forward ,references).这些代码应该再标记"%{"和"%}"之间;规则部分>可以包括任何你想用来分析的代码;我们这里包括了忽略所有注释中字符的功能,传送ID名称和字符串常量内容到主调函数和main函数的功能. (3)实现原理 程序中先判断这个句语句中每个单元为关键字、常数、运算符、界符,对与不同的单词符号给出不同编码形式的编码,用以区分之。 PL/0语言的EBNF表示 <常量定义>::=<标识符>=<无符号整数>; <标识符>::=<字母>={<字母>|<数字>}; <加法运算符>::=+|- <乘法运算符>::=*|/ <关系运算符>::==|#|<|<=|>|>= <字母>::=a|b|…|X|Y|Z <数字>::=0|1|2|…|8|9 三:设计过程 1. 关键字:void,main,if,then,break,int,Char,float,include,for,while,printfscanf 并为小写。 2."+”;”-”;”*”;”/”;”:=“;”:”;”<“;”<=“;”>“;”>=“;”<>“;”=“;”(“;”)”;”;”;”#”为运算符。 3. 其他标记 如字符串,表示以字母开头的标识符。 4. 空格符跳过。 5. 各符号对应种别码 关键字分别对应1-13 运算符分别对应401-418,501-513。 字符串对应100 常量对应200 结束符# 四:举例说明 目标:实现对常量的判别 代码: digit [0-9] letter [A-Za-z] other_char [!-@\[-~] id ({letter}|[_])({letter}|{digit}|[_])* string {({letter}|{digit}|{other_char})+} int_num {digit}+ %% [ |\t|\n]+ "auto"|"double"|"int"|"struct"|"break"|"else"|"long"|"switch"|"case"|"enum"|"register"|"typedef"|"char"|"extern"|"return"|"union"|"const"|"float"|"short"|"unsigned"|"continue"|"for"|"signed"|"void"|"default"|"goto"|"sizeof"|"do"|"if"|"static"|"while"|"main" {Upper(yytext,yyleng);printf("%s,NULL\n",yytext);} \"([!-~])*\" {printf("CONST_string,%s\n",yytext);} -?{int_num}[.]{int_num}?([E][+|-]?{int_num})? {printf("CONST_real,%s\n",yytext);} "0x"?{int_num} {printf("CONST_int,%s\n",yytext);} ","|";"|"("|")"|"{"|"}"|"["|"]"|"->"|"."|"!"|"~"|"++"|"--"|"*"|"&"|"sizeof"|"/"|"%"|"+"|"-"|">"|"<"|">="|"<="|"=="|"!="|"&"|"^"|"|"|"&"|"||"|"+="|"-="|"*="|"/="|"%="|">>="|"<<="|"&="|"^="|"|="|"=" {printf("%s,NULL\n",yytext);} {id} {printf("ID,%s\n",yytext);} {digit}({letter})+ {printf("error1:%s\n",yytext);} %% #include <ctype.h> Upper(char *s,int l) { int i; for(i=0;i<l;i++) { s[i]=toupper(s[i]); } } yywrap() { return 1; } 五:DFA 六:数据测试 七:心得体会 其实匹配并不困难,主要是C++知识要求相对较高,只要把握住指针就好了。 附源程序: #include<iostream.h> #include<stdio.h> #include<stdlib.h> #include<string.h> int i,j,k,flag,number,status; /*status which is use to judge the string is keywords or not!*/ char ch; char words[10] = {" "}; char program[500]; int Scan(char program[]) { char *keywords[13] = {"void","main","if","then","break","int", "char","float","include","for","while","printf", "scanf"}; number = 0; status = 0; j = 0; ch = program[i++]; /* To handle the lettle space ands tab*/ /*handle letters*/ if ((ch >= 'a') && (ch <= 'z' )) { while ((ch >= 'a') && (ch <= 'z' )) { words[j++]=ch; ch=program[i++]; } i--; words[j++] = '\0'; for (k = 0; k < 13; k++) if (strcmp (words,keywords[k]) == 0) switch(k) { case 0:{ flag = 1; status = 1; break; } case 1:{ flag = 2; status = 1; break; } case 2:{ flag = 3; status = 1; break; } case 3:{ flag = 4; status = 1; break; } case 4:{ flag = 5; status = 1; break; } case 5:{ flag = 6; status = 1; break; } case 6:{ flag = 7; status = 1; break; } case 7:{ flag = 8; status = 1; break; } case 8:{ flag = 9; status = 1; break; } case 9:{ flag = 10; status = 1; break; } case 10:{ flag = 11; status = 1; break; } case 11:{ flag = 12; status = 1; break; } case 12:{ flag = 13; status = 1; break; } } if (status == 0) { flag = 100; } } /*handle digits*/ else if ((ch >= '0') && (ch <= '9')) { number = 0; while ((ch >= '0' ) && (ch <= '9' )) { number = number*10+(ch-'0'); ch = program[i++]; } flag = 200; i--; } /*opereation and edge handle*/ else switch (ch) { case '=':{ if (ch == '=') words[j++] = ch; words[j] = '\0'; ch = program[i++]; if (ch == '=') { words[j++] = ch; words[j] = '\0'; flag = 401; } else { i--; flag = 402; } break; } case'>':{ if (ch == '>') words[j++] = ch; words[j] = '\0'; ch = program[i++]; if (ch == '=') { words[j++] = ch; words[j] = '\0'; flag = 403; } else { i--; flag = 404; } break; } case'<':{ if (ch == '<') words[j++] = ch; words[j] = '\0'; ch = program[i++]; if (ch == '=') { words[j++] = ch; words[j] = '\0'; flag = 405; } else { i--; flag = 406; } break; } case'!':{ if (ch == '!') words[j++] = ch; words[j] = '\0'; ch = program[i++]; if (ch == '=') { words[j++] = ch; words[j] = '\0'; flag = 407; } else { i--; flag = 408; } break; } case'+':{ if (ch == '+') words[j++] = ch; words[j] = '\0'; ch = program[i++]; if (ch == '=') { words[j++] = ch; words[j] = '\0'; flag = 409; } else if (ch == '+') { words[j++] = ch; words[j] = '\0'; flag = 410; } else { i--; flag = 411; } break; } case'-':{ if (ch == '-') words[j++] = ch; words[j] = '\0'; ch = program[i++]; if (ch == '=') { words[j++] = ch; words[j] = '\0'; flag = 412; } else if( ch == '-') { words[j++] = ch; words[j] = '\0'; flag = 413; } else { i--; flag = 414; } break; } case'*':{ if (ch == '*') words[j++] = ch; words[j] = '\0'; ch = program[i++]; if (ch == '=') { words[j++] = ch; words[j] = '\0'; flag = 415; } else { i--; flag = 416; } break; } case'/':{ if (ch == '/') words[j++] = ch; words[j] = '\0'; ch = program[i++]; if (ch == '=') { words[j++] = ch; words[j] = '\0'; flag = 417; } else { i--; flag = 418; } break; } case';':{ words[j] = ch; words[j+1] = '\0'; flag = 501; break; } case'(':{ words[j] = ch; words[j+1] = '\0'; flag = 502; break; } case')':{ words[j] = ch; words[j+1] = '\0'; flag = 503; break; } case'[':{ words[j] = ch; words[j+1] = '\0'; flag = 504; break; } case']':{ words[j] = ch; words[j+1] = '\0'; flag = 505; break; } case'{':{ words[j] = ch; words[j+1] = '\0'; flag = 506; break; } case'}':{ words[j] = ch; words[j+1] = '\0'; flag = 507; break; } case':':{ words[j] = ch; words[j+1] = '\0'; flag = 508; break; } case'"':{ words[j] = ch; words[j+1] = '\0'; flag = 509; break; } case'%':{ if (ch == '%') words[j++] = ch; words[j] = '\0'; ch = program[i++]; if (ch == '=') { words[j++] = ch; words[j] = '\0'; flag = 510; } else { i--; flag = 511; } break; } case',':{ words[j] = ch; words[j+1] = '\0'; flag = 512; break; } case'#':{ words[j] = ch; words[j+1] = '\0'; flag = 513; break; } case'@':{ words[j] = '#'; flag = 0; break; } default:{ flag = -1; break; } } return flag; } main() { i=0; printf("please input a program end with @"); do { ch = getchar(); program[i++] = ch; }while(ch != '@'); i = 0; do{ flag = Scan(program); if (flag == 200) { printf("(%2d,%4d)",flag,number); } else if (flag == -1) { printf("(%d,error)",flag); } else { printf("(%2d,%4s)",flag,words); } }while (flag != 0); system("pause"); }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值