编译原理_常量定义语句语法分析

一、作用
  判断常量语句定义是否合法,合法则输出分析结果,不合法则输出原由。

二、不合法原由
    1、是否有关键字“const”开头定义
    2、是否有“;”结束定义;
    3、句子中格式行的空格处理;
    4、常量名是否合法(首字符是字母);
    5、整形常量不能有前导零;
    6、整形常量中不能有除数字以外的其他字符;
    7、字符常量中只能有一个字符;
    8、字符型常量不能为空;
    //9、字符串常量不能为空;
    10、浮点型常量“0.”型的,不能有多余的前导零;
    11、浮点型常量中不能有除数字及小数点外的其他字符;
    12、浮点型常量中不能出现多个小数点。

三、代码测试
  见《yufa测试数据及测试结果》

四、测试数据意义分析
    const a=234,b="asdas",c='f',s=435.345;
    正确数据
    sconst a=234,b="asdas",c='f',s=435.345;
    关键字错误
    const a=234,b="asdas",c='f',s=435.345
    句尾无“;”
    const a=234,b="asdas",c = 'f' ,s =435.345;
    句中有格式空格
    const a=234,b="asdas",1c='f',s=435.345;
    const a=234,_b="asdas",c='f',s=435.345;
    const a=234,,b="asdas",c='f',s=435.345;
    常量名错误
    const a=0234,b="asdas",c='f',s=435.345;
    整型常量有前导零
    const a=23ed4,b="asdas",c='f',s=435.345;
    “整型常量”中有非数字字符
    const a=234,b="asdas",c='ff',s=435.345;
    “字符型常量”中有多个字符
    const a=234,b="asdas",c='',s=435.345;
    “字符型常量”值为空
    const a=234,b="",c='f',s=435.345;
    “字符串型常量”值为空
    const a=234,b="asdas",c='f',s=00.345;
    “浮点型常量”有多余前导零
    const a=234,b="asdas",c='f',s=43sdf5.345;
    “浮点型常量”中有非数字非小数点字符
    const a=234,b="asdas",c='f',s=43.5.345;
    “浮点型常量”中有多个小数点
五、问题分析
   程序中仍不能解决的问题有:
    1、若字符串中有空格,无法处理,会被直接删除;
    2、若语句中有多余的或在字符串中有“,”会导致程序崩溃;

    3、若语句中有非英文字符,可能会导致程序崩溃。



测试数据:

const a=234,b="asdas",c='f',s=435.345;
sconst a=234,b="asdas",c='f',s=435.345;
const a=234,b="asdas",c='f',s=435.345
const a=234,b="asdas",c = 'f' ,s =435.345;
const a=234,b="asdas",1c='f',s=435.345;
const a=234,_b="asdas",c='f',s=435.345;
const a=234,,b="asdas",c='f',s=435.345;
const a=0234,b="asdas",c='f',s=435.345;
const a=23ed4,b="asdas",c='f',s=435.345;
const a=234,b="asdas",c='ff',s=435.345;
const a=234,b="asdas",c='',s=435.345;
const a=234,b="",c='f',s=435.345;
const a=234,b="asdas",c='f',s=00.345;
const a=234,b="asdas",c='f',s=43sdf5.345;
const a=234,b="asdas",c='f',s=43.5.345;


测试结果:

const a=234,b="asdas",c='f',s=435.345;
@the constent is lagel ,fllow is the result of Analysis:
*********************************
a(int , 234)
b(String , "asdas")
c(char , 'f')
s(float , 435.345)

num_int = 1 ;
num_float = 1 ;
num_char = 1 ;
num_string = 1 ;

*********************************
The Analysis is finish!
Please input a string again!

-------------------------------------------------

sconst a=234,b="asdas",c='f',s=435.345;
It is not a constant declaration statement! <const>
The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",c='f',s=435.345
It is not a constant! <;>
The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",c = 'f' ,s =435.345;
@the constent is lagel ,fllow is the result of Analysis:
*********************************
a(int , 234)
b(String , "asdas")
c(char , 'f')
s(float , 435.345)

num_int = 1 ;
num_float = 1 ;
num_char = 1 ;
num_string = 1 ;

*********************************
The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",1c='f',s=435.345;
<1c>: the name is illege!

The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,_b="asdas",c='f',s=435.345;
<_b>: the name is illege!

The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,,b="asdas",c='f',s=435.345;
<,b>: the name is illege!

The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=0234,b="asdas",c='f',s=435.345;
<0234> :is not a legal int! <0>
The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=23ed4,b="asdas",c='f',s=435.345;
<23ed4> :is not a legal int! <other charecater>
The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",c='ff',s=435.345;
<'ff'> :is not a legal charThe Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",c='',s=435.345;
<''> :is not a legal charThe Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="",c='f',s=435.345;
<""> :is not a legal StringThe Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",c='f',s=00.345;
<00.345> :is not a legal float! <00>
The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",c='f',s=43sdf5.345;
<43sdf5.345> :is not a legal float! <other charecater>
The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",c='f',s=43.5.345;
<43.5.345> :is not a legal float! <.. >
The Analysis is finish!
Please input a string again!

-------------------------------------------------



/*
    @常量定义语法判断
    @作者:Amy
    @版本:1.1
*/
#include<iostream>
#include<string>
#include<vector>
#include<stdio.h>
#include<string.h>
#include<ctype.h>
using namespace std;
struct node //常量定义分析
{
    string name;    //常量名
    string in; //常量内容
    string type;    //常量类型//interger,char,int,float
}content;
string s,ss;
vector<node> ve;
int len;
int num_int,num_float,num_char,num_string;
char a[1000];
bool initial()//初始化,输入数据
{
    num_int=0;
    num_float=0;
    num_char=0;
    num_string=0;
    ve.clear();
    if(gets(a))
    {
        s=a;
        return true;
    }
    return false;
}

bool judge_const()//判断const是否正确
{
    int x=s.find(" ",0);
    ss=s.substr(0,x);//提取关键字const
    for(int i=0;i<s.size();i++)     //去掉空格
        if(s[i]==' ')s.erase(i--,1);
    s.copy(a,s.size()-5,5);
    len=s.size()-5;
    a[len]='\0';
    if(ss!="const")return false;
    return true;
}

bool jundge_tail()  //判断是否有“;”
{
    if(a[len-1]!=';')return false;
   return true;

}

void sent()//提取语句(每个定义)
{
    int side=0;
    char name1[20],in[20];
    a[len-1]=',';
    while(sscanf(a+side,"%[^=]%[^,]",name1,in))
    {
        content.name=name1;
        content.in=in;
        content.in.erase(0,1);
        ve.push_back(content);
        side+=strlen(name1)+strlen(in)+1;
        if(side==len)  //到结尾
            break;
    }
}

bool judge_name()   //判断常量名是否合语法
{
    for(int i=0;i<ve.size();i++)
        if(!isalpha(ve[i].name[0])){    //首字符不是字母
            cout<<"<"<<ve[i].name<<">";
            return false;
        }
    return true;
}

void classf()   //根据常量特征分类
{
    for(int i=0;i<ve.size();i++){
        if(ve[i].in[0]=='"')    //双引号开始的是字符串
            ve[i].type="String",num_string++;
        else if(ve[i].in[0]=='\'')  //单引号开始的是字符
            ve[i].type="char",num_char++;
        else if(ve[i].in.find(".",0)<ve[i].in.size())   //带小数点的是小数
            ve[i].type="float",num_float++;
        else  ve[i].type="int",num_int++;   //否则是整数
    }
}

bool judge_content()//判断常量内容是否正确
{
    char txt[20];
    for(int i=0;i<ve.size();i++){
        if(ve[i].type=="int"){
            ve[i].in.copy(a,ve[i].in.size(),0);
            a[ve[i].in.size()]='\0';
            if(sscanf(a,"%[0-9]",txt)&&strlen(a)==strlen(txt)); //整数中没有非数字字符
            else
            {
                cout<<"<"<<ve[i].in<<"> :is not a legal int! <other charecater>"<<endl;
                 return false;
            }
            if(ve[i].in[0]=='0'){   //整数不能前导零
                cout<<"<"<<ve[i].in<<"> :is not a legal int! <0>"<<endl;
                return false;
            }
        }
        if(ve[i].type=="float"){
            ve[i].in.copy(a,ve[i].in.size(),0);
            a[ve[i].in.size()]='\0';
            if(sscanf(a,"%[0-9,.]",txt)&&strlen(a)==strlen(txt));   //小数中没有非数字和非小数点的字符
            else
            {
                cout<<"<"<<ve[i].in<<"> :is not a legal float! <other charecater>"<<endl;
                 return false;
            }
            if(ve[i].in[0]==ve[i].in[1]&&ve[i].in[1]=='0'){ //小数不能前导两个零
               cout<<"<"<<ve[i].in<<"> :is not a legal float! <00>"<<endl;
               return false;
            }
            if(ve[i].in.find(".",ve[i].in.find(".",0)+1)<ve[i].in.size()){//小数中不能有多个小数点
                cout<<"<"<<ve[i].in<<"> :is not a legal float! <.. >"<<endl;
               return false;
            }
        }
        if(ve[i].type=="char"){
            if(ve[i].in.size()!=3){
                cout<<"<"<<ve[i].in<<"> :is not a legal char";//常量中自能有一个字符
                return false;
            }
        }
        else {
            if(ve[i].in.size()<3){//字符串常量中不能为空
                cout<<"<"<<ve[i].in<<"> :is not a legal String";
                return false;
            }
        }
    }
    return true;
}

void output()//输出结果,若无语法问题
{
    cout<<"@the constent is lagel ,fllow is the result of Analysis:";
    cout<<"\n*********************************\n";
    for(int i=0;i<ve.size();i++)
        cout<<ve[i].name<<"("<<ve[i].type<<" , "<<ve[i].in<<")"<<endl;
    cout<<endl;
    cout<<"num_int = "<<num_int<<" ;\n";
    cout<<"num_float = "<<num_float<<" ;\n";
    cout<<"num_char = "<<num_char<<" ;\n";
    cout<<"num_string = "<<num_string<<" ;\n";
    cout<<"\n*********************************\n";
}
int main()
{
    bool x;
    while(initial())
    {
        if(!judge_const())//判断是否有关键字“const”
        {
            cout<<"It is not a constant declaration statement! <const>"<<endl;
            goto end1;
        }
        if(!jundge_tail())//判断句尾是否有“;”
        {
            cout<<"It is not a constant! <;>"<<endl;
            goto end1;
        }
        sent();
        if(!judge_name())//判断常量名是否合法
        {
            cout<<": the name is illege!\n\n";
            goto end1;
        }
        classf();   //分析常量类型
        if(!judge_content())    //判断常量初始化是否有误
            goto end1;
        output();   //输出结果(若没有发现问题)
end1:
        cout<<"The Analysis is finish!\nPlease input a string again!"<<endl;
        cout<<"\n-------------------------------------------------\n"<<endl;
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值