用c语言编写一个词法分析器用来识别:由任意个a或b开始后接aa再自加或自减1的字符串

该词法分析器的功能:
从键盘读入或打开文件读入字符串,词法分析器读入字符串后扫描源字符串,若发现符合符合正规式r=(a|b)*aa(+|-)1描述的字符串时,输出“yes”或“可接受”或“可识别”,否则输出“no”或“不可识别”。

我们通过这个正规式可以知道,最后4个字符是确定的,即aa+1或aa-1。然后再判断前面的字符是否为a或b。我的想法是从后往前判断,只有当前的条件符合时再进行下面的判断。
我们可以将正规式分为4部分,于是得到一下几个判断的原则:
1.读入的字符串长度必须大于等于4;
2.最后一个字符必须为‘1’;
3.倒数第2个字符必须为‘+’或‘-’;
4.倒数第3个和第4个字符必须为‘a’;
5.前面的字符必须为‘a’或‘b’;

下面是具体的程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//判断输入的字符串是否符合正规式
//返回0表示不符合,返回1表示符合正规式
int func(char *s)
{
int i, j, t;
char c;

t = strlen(s);

//如果输入的长度小于4,一定不符合正规式
if(t<4)
{
return 0;
}

//如果最后一个不是1,则不符合正规式
if(s[t-1]!='1')
{
return 0;
}

//如果最后是1但倒数第二个不是+或-,则不符合正规式
if(s[t-2]!='+' && s[t-2]!='-')
{
return 0;
}

//如果前两个条件符合,则检测是否存在连续的两个a
//只要其中一个不为a,则不符合正规式
if(s[t-4]!='a' || s[t-3]!='a')
{
return 0;
}

//如果前面的条件符合,则进行此判断
//此时不用判断读入的字符串长度是否大于4或者等于4,
//因为如果字符串的长度等于4时,根本不进入循环
for(i=0; i<t-4; i++)
{
if(s[i]!='a' && s[i]!='b')
{
return 0;
}
}

//如果条件都符合,则符合正规式
return 1;
}

int main()
{
char s[200];

while(scanf("%s", s)==1)
{
if(func(s)==1)
{
printf("yes\n");
}
else
{
printf("no\n");
}
}

return 0;
}

/*
测试用例:
aa+1 yes
aa-1 yes
aaa+1 yes
aaaaa+1 yes
bbbbaa-1 yes
abababaa+1 yes
aaabbaa-1 yes
a+1 no
aa+2 no
aa*1 no
aaab+1 no
abababcaa-1 no
aaabbbcccaa+1 no
*/
温馨提示:答案为网友推荐,仅供参考