编译原理词法分析程序

编译原理词法分析程序,第1张

#include <iostream>

#include <ctype.h>

#include <fstream>

#include <string.h>

#include <malloc.h>

using namespace std

ifstream fp("source.txt",ios::in)

char cbuffer

char *key[13]={"if","else","for","while","do","return","break","continue","int","void"

,"main","const","printf"}//关键字

char *border[7]={ "," , "" , "{" , "袭喊}" , "(" , ")" ,"//"} //拍键野分界

char *arithmetic[6]={"+" , "-" , "*" , "/" , "++" , "--"} //运算符

char *relation[7]={"<" , "<=" , "=" , ">" , ">=" , "==" ,"!="}//关系运算符

char *lableconst[80] //标识符

int constnum=40

int lableconstnum=0

int linenum=1 //统计常数和标识符数量

int search(char searchchar[],int wordtype)

{

int i=0,t=0

switch (wordtype)

{

case 1:

{ for (i=0i<=12i++) //关键字

{

if (strcmp(key[i],searchchar)==0)

return(i+1)

}

return(0)}

case 2:

{

for (i=0i<=6i++)//分界符

{

if (strcmp(border[i],searchchar)==0)

return(i+1)

}

return(0)

}

case 3:

{

for (i=0i<=5i++)//运算符

{

if (strcmp(arithmetic[i],searchchar)==0)

return(i+1)

}

return(0)

}

case 4:

{

for (i=0i<=6i++)//关系运算符

{

if (strcmp(relation[i],searchchar)==0)

return(i+1)

}

return(0)

}

case 5:

{

for (t=40t<=constnumt++) //常数

{

if (strcmp(searchchar,lableconst[t])==0)//判断该常数是否已出现过

return(t+1)

}

lableconst[t-1]=(char *)malloc(sizeof(searchchar))//为新的元素分配内存亮行空间

strcpy(lableconst[t-1],searchchar)//为数组赋值lableconst指针数组名

constnum++ //常数个数自加

return(t)

}

case 6:

{

for (i=0i<=lableconstnumi++)

{

if (strcmp(searchchar,lableconst[i])==0) //判断标识符是否已出现过

return(i+1)

}

lableconst[i-1]=(char *)malloc(sizeof(searchchar))

strcpy(lableconst[i-1],searchchar)

lableconstnum++ //标识符个数自加

return(i)

}

default:cout<<"错误!"

}

}

char alphaprocess(char buffer)//字符处理过程

{

int atype

int i=-1

char alphatp[20]

while ((isalpha(buffer))||(isdigit(buffer)))

//这两个函数分别是判字符和判数字函数位于ctype.h中

{

alphatp[++i]=buffer

fp.get(buffer)

}

alphatp[i+1]='\0'//在末尾添加字符串结束标志

if (atype=search(alphatp,1))

cout<<"linenum: "<<linenum<<" String= "<<alphatp<<"\t\t\t"<<"关键字"<<endl

else

{

atype=search(alphatp,6) //标识符

cout<<"linenum: "<<linenum<<" String= "<<alphatp<<"\t\t\t"<<"标识符"<<endl

}

return(buffer)

}

char digitprocess(char buffer) //数字处理过程

{

int i=-1

char digittp[20]

int dtype

while ((isdigit(buffer)))

{

digittp[++i]=buffer

fp.get(buffer)

}

digittp[i+1]='\0'

dtype=search(digittp,5)

cout<<"linenum: "<<linenum<<" String= "<<digittp<<"\t\t\t"<<"数据"<<endl

return(buffer)

}

char otherprocess(char buffer) //分界符、运算符、逻辑运算符、等

{

int i=-1

char othertp[20]

int otype,otypetp

othertp[0]=buffer

othertp[1]='\0'

if (otype=search(othertp,3))

{

fp.get(buffer)

othertp[1]=buffer

othertp[2]='\0'

if (otypetp=search(othertp,3)) //判断该运算符是否是

//由连续的两个字符组成的

{

cout<<"linenum: "<<linenum<<" String= "<<othertp<<"\t\t\t"<<"运算符"<<endl

fp.get(buffer)

goto out

}

else //单字符逻辑运算符

{

othertp[1]='\0'

cout<<"linenum: "<<linenum<<" String= "<<othertp<<"\t\t\t"<<"逻辑运算符"<<endl

goto out

}

}

if (otype=search(othertp,4)) //关系运算符

{

fp.get(buffer)

othertp[1]=buffer

othertp[2]='\0'

if (otypetp=search(othertp,4)) //判断该关系运算符是否是

//由连续的两个字符组成的

{

cout<<"linenum: "<<linenum<<" String= "<<othertp<<"\t\t\t"<<"关系运算符"<<endl

fp.get(buffer)

goto out

}

else //单字符逻辑运算符

{

othertp[1]='\0'

cout<<"linenum: "<<linenum<<" String= "<<othertp<<"\t\t\t"<<"逻辑运算"<<endl

goto out

}

}

if (buffer=='!') //"=="的判断

{

fp.get(buffer)

if (buffer=='=')

//cout<<"!= (2,2)\n"

fp.get(buffer)

goto out

}

else

{

if (otype=search(othertp,2)) //分界符

{

cout<<"linenum: "<<linenum<<" String= "<<othertp<<"\t\t\t"<<"分界符"<<endl

fp.get(buffer)

goto out

}

}

if ((buffer!='\n')&&(buffer!=' '))

cout<<"错误!,字符非法"<<"\t\t\t"<<buffer<<endl

fp.get(buffer)

out: return(buffer)

}

void main()

{

int i

for (i=0i<=50i++)

{

lableconst[i]=" "//用于保存标识符

}

if (!fp)

cout<<"文件打开错误!!"<<endl

else

{

fp.get (cbuffer)

while (!fp.eof())

{

if(cbuffer=='\n')

{

linenum++

fp.get(cbuffer)

}

else if (isalpha(cbuffer))

{

cbuffer=alphaprocess(cbuffer)

}

else if (isdigit(cbuffer))

{

cbuffer=digitprocess(cbuffer)

}

else

cbuffer=otherprocess(cbuffer)

}

}

cout<<"标识符个数是:"<<lableconstnum<<"分别是"<<endl

i=0

while(i<lableconstnum)

{

cout<<lableconst[i++]<<" "

}

cout<<endl

cout<<"完成\n"

getchar()

}

现可以提供两种思路:

1.String或是StringBuffer(建议用) 中的indexOf("中华")方法,查找给定的的字符串中是否有给定词表历旅中的词。

2.借鉴编译原理中的状态装换的思想。

先编写一个状态机,用于测试给定字符串中的词是否满足词表中的内容。

写在最后:1)建议使用第一种方法,因为在java 内部实现的查找 *** 作其实 和你想得思路是相同的,不过他的效率会高些。

2)如果个人的编程能力比较强或是不陆烂冲考虑效率只是想实现专有的分词算法。可以使用早歼第二种方法。

3)以上的两种方法都可以使用多线程来提高程序的效率。

分类: 电脑/网络 >>程序设计 >>其他编程语言

问题描述:

完成以下正则文法所描述的Pascal语言子集单词符号的词法分析程序。

<标识符>→字母| <标识符>字母| <标识符>数字

<无符号整数>→数字| <无符号整数>数字

<单字符分界符>→+ |- |* ||(|)

<双字符分界符>→<大于>碰陵=|<小于>=|<小于>>|<冒号>=|<斜竖>*

<小于>→<

<等于>→笑坦戚=

<大于>→>

<冒号>→:

<斜竖>→/

该语言的保留字 :begin end if then else for do while and or not

说明:

1 该语言大小写不敏感。

2 字母为a-z A-Z,数字为0-9。

3可以对上述文法进行扩充和改造。

4 ‘/*……*/’为程序的注释部分。

[设计要求]

1、 给出各单词符号的类别编码。

2、 词法分析程序应能发现输入串中的错误。

3、 词法分析作为单独一遍编写,词法分析结果为二元式序列组成的中间文件。

4、设计两个测试用例(尽可能完备),并给信宴出测试结果。

解析:

这种问题 …… 会有人解答吗?


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

原文地址: http://outofmemory.cn/yw/12259004.html

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

发表评论

登录后才能评论

评论列表(0条)

保存