c语言take函数,C语言实现词法分析器

问题描述:

用C或C++语言编写一个简单的词法分析程序,扫描C语言小子集的源程序,根据给定的词法规则,识别单词,填写相应的表。如果产生词法错误,则显示错误信息、位置,并试图从错误中恢复。简单的恢复方法是忽略该字符(或单词)重新开始扫描。

相关词法规则

::=

::=

::=

::=

::=

::=

::=

::=a|b|c|……|x|y|z

::=0|1|2|3|4|5|6|7|8|9

::=+|-

::=*|/

::=|!=|>=|<=|==

::=,|;|(|)|{|}

::=main|int|if|else|while|do

编写词法分析程序的步骤:

(1)确定所要翻译的语言(或其子集)。

C语言

(2)设计属性字,及各类表格,如标识符表、常量表、符号及其机内表示对照表等。

与词法分析有关的表格:

1. 字符表

保留字:main,int,if,else,while,do

字母(全小写):a|b|c|……|x|y|z

数字:0,1,2,3,4,5,6,7,8,9

运算符和界符:,!=,>=,<=,==,,,;,(,),{,}

2. 特定单词机内表示表

76ec88e67979c5b3dadce840310c9cfb.png

3.画出总控流程图及各个子程序的流程图。

257a1f0106d3abe6a49d0f6ff8dde220.png

4. 程序

输入:一个存放C语言程序的s.txt文件

输出:存放以(单词,种别码)形式输出的result.txt文件

需要6个数组:

1. 存储关键字 key[6]

2. 存储对应下标关键字的种别码 keyNum[6]

3. 存储运算符和界符 symbol[17]

4. 存储运算符对应下标的种别码 symbolNum[17]

5. 存储从文件中取出的每个字符(不包括括号)letter[1000]

主要函数:

TakeWord();

功能:将文件letter[]中每个字符进行提取,找出关键字,输出种别码

Num作为全局变量保存提取到字符的哪个下标

1. 先提取一个字符,如果是字母,进入case1,调用identifier(),不断的提取字母或数字进行连接,没连接一个字符用int isKeyWord()程序(返回关键字种别码)判断是否为关键字,是就退出函数返回string,不是就继续执行函数,直到连接的字符不再是字母或数字,即此时字符串为标识符

2. 如果是数字,进入case 2,调用Number()函数,不断进行字符串连接,知道下一个连接字符不再是数字

3. 如果是符号,进入case 3,调用symbolStr()函数,如果是=,>,

其他辅助函数:

int isSymbol()判断运算符和界符,并返回种别码

bool isNum() 判断是否为数字

bool isLetter()判断是否为字母

int isKeyWord()判断是否为关键字,是返回种别码

int typeword()返回单个字符的类型

string identifier()标识符的连接

string symbolStr()符号和界符的连接

string Number()数字的连接

void print()输出

程序:

#include

#include

#include

#include

using namespace std;

//关键字

string key[6]={"main","int","if","else","while","do"};

//关键字的种别码

int keyNum[6]={1,2,3,4,5,6};

//运算符和界符

string symbol[17]={"","!=",">=","<=","==",",",";","(",")","{","}","+","-","*","/","="};

//char symbol[12]={'','!=','>=','<=','==',',',';','(',')','{','}'};

//运算符和界符的种别码

int symbolNum[17]={7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};

//存放文件取出的字符

string letter[1000];

//将字符转换为单词

string words[1000];

int length; //保存程序中字符的数目

int num;

int isSymbol(string s){ //判断运算符和界符

int i;

for(i=0;i<17;i++){

if(s==symbol[i])

return symbolNum[i];

}

return 0;

}

//判断是否为数字

bool isNum(string s){

if(s>="0" && s<="9")

return true;

return false;

}

//判断是否为字母

bool isLetter(string s)

{

if(s>="a" && s<="z")

return true;

return false;

}

//判断是否为关键字,是返回种别码

int isKeyWord(string s){

int i;

for(i=0;i<6;i++){

if(s==key[i])

return keyNum[i];

}

return 0;

}

//返回单个字符的类型

int typeword(string str){

if(str>="a" && str<="z") // 字母

return 1;

if(str>="0" && str<="9") //数字

return 2;

if(str==">"||str=="="||str=="

||str=="+"||str=="-"||str=="*"||str=="/") //判断运算符和界符

return 3;

}

string identifier(string s,int n){

int j=n+1;

int flag=1;

while(flag){

if(isNum(letter[j]) || isLetter(letter[j])){

s=(s+letter[j]).c_str();

if(isKeyWord(s)){

j++;

num=j;

return s;

}

j++;

}

else{

flag=0;

}

}

num=j;

return s;

}

string symbolStr(string s,int n){

int j=n+1;

string str=letter[j];

if(str==">"||str=="="||str=="

s=(s+letter[j]).c_str();

j++;

}

num=j;

return s;

}

string Number(string s,int n){

int j=n+1;

int flag=1;

while(flag){

if(isNum(letter[j])){

s=(s+letter[j]).c_str();

j++;

}

else{

flag=0;

}

}

num=j;

return s;

}

void print(string s,int n){

cout<

}

void TakeWord(){ //取单词

int k;

for(num=0;num

string str1,str;

str=letter[num];

k=typeword(str);

switch(k){

case 1:

{

str1=identifier(str,num);

if(isKeyWord(str1))

print(str1,isKeyWord(str1));

else

print(str1,0);

break;

}

case 2:

{

str1=Number(str,num);

print(str1,24);

break;

}

case 3:

{

str1=symbolStr(str,num);

print(str1,isSymbol(str1));

break;

}

}

}

}

int main(){

char w;

int i,j;

freopen("s.txt","r",stdin);

freopen("result.txt","w",stdout); //从控制台输出,而不是文本输出

length=0;

while(cin>>w){

if(w!=' '){

letter[length]=w;

length++;

} //去掉程序中的空格

}

TakeWord();

// for(j=0;j

// cout<

// }

fclose(stdin);//关闭文件

fclose(stdout);//关闭文件

return 0;

}

运行结果:

s.txt

c580fd42f59092b3fa10b3f2bffca8a9.png

Result.txt

1a52bc386577a2289fcf48b7649a2bc0.png

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值