怎么样用c语言编写文法压缩用加标记法实现

怎么样用c语言编写文法压缩用加标记法实现,第1张

基本方法是

从识别符号向终结符过度时,从含有识别符号的规则入手,寻找所有规则中左部为识别符号的规则,然后搜索这些找到的规则的右部是否含有非终结符,若含有则从所有规则中找出左部为这个非终结符的规则,并标记,当搜完第一次后,循环查找具有标记的规则,按照上面的方式继续标记剩下的规则,直到没有新的规则被标记 退出 删除未标记的规则体

反方向同理……

说什么都不如看代码 下面是我写文法压缩时候写的压缩函数

void Mylist::condense(char spot,CString gettofun)

{

//condense with spot way

addsignal(spot,1)

for(int i=1i<7i++)

{

for(int j=0j<countj++)

{

if(readsignal(j)==i)

{

int rightlength=findright(j).GetLength()

for(int k=0k<rightlengthk++)

{

if(gettofun.Find(findright(j).GetAt(k))!=-1)

{

addsignal(findright(j).GetAt(k),i+1)

}

}

}

}

}

// unsigned the wordrule like s::=s*

bool caiding=false

for(int j=0j<countj++)

{

int rightlength=findright(j).GetLength()

for(int k=0k<rightlengthk++)

{

if(findleft(j)!=findright(j).GetAt(k))

caiding=true

}

if(caiding==false)

{signal(j,0)}

}

//format every node have been signed

for(int m=0m<countm++)

{

if(readsignal(m)!=0)

{

signal(m,1)

}

}

//decide which to begin

for(m=0m<countm++)

{

if((gettofun.FindOneOf(findright(m))==-1)&&(readsignal(m)!=0))

{

signal(m,2)

}

}

//right way condense

int q=2

for(int worry=0worry<10worry++){

for(int j1=0j1<countj1++)

{

if(readsignal(j1)==q)

{

for(int i1=0i1<counti1++){

//int right=findright(i1).GetLength()

for(int i2=0i2<findright(i1).GetLength()i2++)

{

if(findleft(j1)==findright(i1).GetAt(i2))

{

signal(i1,q)

}

}

}

}

}//^

}

}

这里说明一下

其中的findright(int i) 函数的功能是从第i条文法规则中找到它的右部 返回值为CString类型

signal(int i,int j)函数 是在第i条规则中找到它的标志位(即加标记)并把j放入这个标志位 以示本条规则已经做好了标记

addsignal(char i,int j) 则是找到左部名为i的规则,并标记他的标志位为j addsignalright同理

本函数传递进来的有两个参数 其中spot是识别符号Z,CString类型的是终结符号队列,包含所有已知的终结符号

在说明一点 wordrule是一个文法体class的对象 它是一个链表 每一个结点(node)为一个规则:

class node

{

public:

char leftwords

int signal

CString rightwords

node *next

public:

node(char,CString)

virtual ~node()

}

希望对你有所帮助

在编写C语言源代码时,应该多使用注释,这样有助于对代码的理解。在C语言中有两种注释方式:

一种是以/*开始、以*/结束的块注释(block comment);

另一种是以//开始、以换行符结束的单行注释(line comment)。

可以使用/*和*/分隔符来标注一行内的注释,也可以标注多行的注释。例如,在下列的函数原型中,省略号的意思是 open() 函数有第三个参数,它是可选参数。注释解释了这个可选参数的用法:

int open( const char *name, int mode, … /* int permissions */ )

可以使用//插入整行的注释,或者将源代码写成两列分栏的格式,程序在左列,注释在右列:

const double pi = 3.1415926536 // pi是—个常量

在 C99 标准中,单行注释正式加入C语言,但是大部分编译器在 C99 之前就已经开始支持这种用法。有时候,其被称作“C++风格”的注释,但实际上,其源自于C的前身 BCPL。

在引号中,如果采用/*或//分隔一个字符常量或字符串字面量(string literal),它们都不会被视为注释的开始。例如,下面语句就没有注释:

printf("Comments in C begin with /* or //.\n" )

预处理器仅通过检查注释的结束符来检测注释中的字符,因此,不能嵌套块注释。然而,可以使用/*和*/注释包含单行注释的源代码:

/* 暂时注释掉这两行:

const double pi = 3.1415926536 // pi是一个常量

area = pi * r * r // 计算面积

暂时注释到此 */

如果想要注释掉包含块注释的部分程序,可以使用条件预处理命令:

#if 0

const double pi = 3.1415926536 /* pi是一个常量 */

area = pi * r * r /* 计算面积 */

#endif

预处理器会把每个注释都替换成一个空格。因此,min/*max*/Value变成两个标记min Value。

所有教程

直接在该行需要注释的地方加上"//"即可。

可以使用/*和*/分隔符来标注一行内的注释,也可以标注多行的注释。例如,在下列的函数原型中,省略号的意思是 open() 函数有第三个参数,它是可选参数。

注释解释了这个可选参数的用法:

int open( const char *name, int mode, … /* int permissions */ );

代码具有较好的可移植性

C语言是面向过程的编程语言,用户只需要关注所被解决问题的本身,而不需要花费过多的精力去了解相关硬件,且针对不同的硬件环境,在用C语言实现相同功能时的代码基本一致,不需或仅需进行少量改动便可完成移植,这就意味着,对于一台计算机编写的C程序可以在另一台计算机上轻松地运行,从而极大的减少了程序移植的工作强度。

以上内容参考:百度百科-C语言


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11413476.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-15
下一篇 2023-05-15

发表评论

登录后才能评论

评论列表(0条)

保存