算术表达式的语法分析及语义分析程序设计 —— LR分析法、输出三元式(续)

#include<iostream>
#include<string>
#include<vector>
#include<cmath>
#define MAX 40
using namespace std;

typedef struct code{
    string data;
    int num;
}Code;
Code code[MAX];

struct Gene{//产生式
    string left;
    char* right;
};
vector<Gene> gene;

typedef struct action{
    char para;
    int val;
}Action;
Action action[][MAX]={
    {{'O',0},{'O',0},{'O',0},{'O',0},{'S',3},{'O',0}, {'O',0},{'O',0},{'O',0}},
    {{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'A', 0}},
    {{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'S', 4},{'O',0}},
    {{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'R', 10},{'O',0}},
    {{'O',0},{'O',0},{'O',0},{'O',0},{'S',8},{'S',9},{'O',0},{'O',0},{'O',0}},
    {{'S',10},{'S',11},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'R',1}},
    {{'R', 4},{'R', 4},{'S', 12},{'S', 13},{'O',0},{'O',0},{'R',4},{'O',0},{'R', 4}},
    {{'R', 7},{'R', 7},{'R', 7},{'R', 7},{'O',0},{'O',0},{'R',7},{'O',0},{'R', 7}},
    {{'R', 8},{'R', 8},{'R', 8},{'R', 8},{'O',0},{'O',0},{'R',8},{'O',0},{'R', 8}},
    {{'O',0},{'O',0},{'O',0},{'O',0},{'S', 8},{'S', 9},{'O', 0},{'O',0},{'O',0}},
    {{'O',0},{'O',0},{'O',0},{'O',0},{'S', 8},{'S', 9},{'O', 0},{'O',0},{'O',0}},
    {{'O',0},{'O',0},{'O',0},{'O',0},{'S', 8},{'S', 9},{'O', 0},{'O',0},{'O',0}},
    {{'O',0},{'O',0},{'O',0},{'O',0},{'S', 8},{'S', 9},{'O', 0},{'O',0},{'O',0}},
    {{'O',0},{'O',0},{'O',0},{'O',0},{'S', 8},{'S', 9},{'O', 0},{'O',0},{'O',0}},
    {{'S',10},{'S',11},{'O',0},{'O',0},{'O',0},{'O',0},{'S',19},{'O',0},{'O',0}},
    {{'R',2},{'R',2},{'S',12},{'S',13},{'O',0},{'O',0},{'R',2},{'O', 0},{'R',2}},
    {{'R',3},{'R',3},{'S',12},{'S',13},{'O',0},{'O',0},{'R',3},{'O', 0},{'R',3}},
    {{'R',5},{'R',5},{'R',5},{'R',5},{'O',0},{'O',0},{'R',5},{'O', 0},{'R',5}},
    {{'R',6},{'R',6},{'R',6},{'R',6},{'O',0},{'O',0},{'R',6},{'O', 0},{'R',6}},
    {{'R',9},{'R',9},{'R',9},{'R',9},{'O',0},{'O',0},{'R',9},{'O', 0},{'R',9}},
};
//转移表goto
int Goto[MAX][MAX];
int num;//词法分析得到的单词个数
string str;//输入串
char *key[10]={"main","void","int","char","printf","scanf","else","if","return"};
char Word[20],ch;
string Vn="AETFV";//非终结符
int Seq;//三元式序号
string Equ[MAX][3];//存储三元式
int IsAlpha(char c)
{
    if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A')))
        return 1;
    else 
        return 0;
}

int IsNumber(char c)
{
    if(c>='0'&&c<='9')
        return 1;
    else 
        return 0;
}

int IsKey(char *word)
{
    int m,i;
    for(i=0;i<9;i++)
    {
        if((m=strcmp(word,key[i]))==0)
        {
            if(i==0)
                return 2;
            return 1;
        }
    }
    return 0;
}

char* scanner(char *fp,int ii)
{
    char Word[20]={'\0'};
    char ch;
    int i,c,sign=9;
    ch=*fp;
    if(IsAlpha(ch))
    {
        Word[0]=ch;
        fp++;
        ch=*fp;
        i=1;
        while(IsNumber(ch)||IsAlpha(ch))
        {
            Word[i]=ch;
            i++;
            fp++;
            ch=*fp;
        }
        Word[i]='\0';
        c=IsKey(Word);
        if(c==0)
        {
            sign=4;
            printf("%s\t普通标识符\t%d\n",Word,sign);
        }
        else if(c==2)
            printf("%s\t主函数  \t%d\n",Word,sign);
        else
            printf("%s\t关键字  \t%d\n",Word,sign);
    }
    else 
        if(IsNumber(ch))
        {
            Word[0]=ch;
            fp++;
            ch=*fp;
            i=1;
            while(IsNumber(ch))
            {
                Word[i]=ch;
                i++;
                fp++;
                ch=*fp;
            }
            Word[i]='\0';
            sign=4;
            printf("%s\t无符号实数\t%d\n",Word,sign);
        }
        else
        {
            Word[0]=ch;
            switch(ch)
            {
            case '[':
            case '(':
            case '{':
                fp++;
                sign=5;
                printf("%s\t界符      \t%d\n",Word,sign); 
                break;
            case ',':
            case '"':
            case ';':
                fp++;
                printf("%s\t界符      \t%d\n",Word,sign); 
                break;
            case ']':
            case ')':
            case '}':
                fp++;
                sign=6;
                printf("%s\t界符      \t%d\n",Word,sign); 
                break;
            case '+':
                fp++;
                ch=*fp;
                if(ch=='=')
                {
                    Word[1]=ch;
                    fp++;
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                else if(ch=='+')
                {
                    Word[1]=ch;
                    fp++;
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                else
                {
                    sign=0;
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                break;
            case '-':
                fp++;
                ch=*fp;
                if(ch=='=')
                {
                    Word[1]=ch;
                    fp++;
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                else if(ch=='-')
                {
                    Word[1]=ch;
                    fp++;
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                else
                {
                    sign=1;
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                break;
            case '*':
                fp++;
                ch=*fp;
                if(ch=='=')
                {
                    Word[1]=ch;
                    fp++;
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                else
                {
                    sign=2;
                    printf("%s\t运算符  \t%d\n",Word,sign);

                }
                break;
            case '/':
                fp++;
                ch=*fp;
                if(ch=='=')
                {
                    Word[1]=ch;
                    fp++;
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                else
                {
                    sign=3;
                    printf("%s\t运算符  \t%d\n",Word,sign);

                }
                break;
            case '!':
            case '=':
                fp++;
                ch=*fp;
                if(ch=='=')
                {
                    Word[1]=ch;
                    fp++;
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                else
                {
                    sign=7;
                    printf("%s\t运算符  \t%d\n",Word,sign);

                }
                break;
            case '<':
                fp++;
                ch=*fp;
                if(ch=='=')
                {
                    Word[1]=ch;
                    fp++;
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                else if(ch=='<')
                {
                    Word[1]=ch;
                    fp++;
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                else
                {
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                break;
            case '>':
                fp++;
                ch=*fp;
                if(ch=='=')
                {
                    Word[1]=ch;
                    fp++;
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                else if(ch=='>')
                {
                    Word[1]=ch;
                    fp++;
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                else
                {
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                break;
            case '%':
                fp++;
                ch=*fp;
                if(ch=='=')
                {
                    Word[1]=ch;
                    fp++;
                    printf("%s\t运算符  \t%d\n",Word,sign);
                }
                if(IsAlpha(ch))
                {
                    Word[1]=ch;
                    fp++;
                    printf("%s\t类型标识符\t%d\n",Word,sign);
                }
                else
                {
                    printf("%s\t取余运算符\t%d\n",Word,sign);
                }
                break;
            case '\\':
                fp++;
                ch=*fp;
                Word[1]=ch;
                fp++;
                printf("%s\t制表符  \t%d\n",Word,sign);
                break;
            default:
                printf("无法识别字符\n"); 
                break;
        }
    }
    code[ii].data=Word;
    code[ii].num=sign;
    return fp;
}

int Cifafenxi()
{
    int i=-1;//种别码
    printf("请输入表达式(以‘#’号结束):\n");
    cin>>str;   
    cout<<"词法分析:\n";
    char *fp=&str[0];                   
    do{
        i++;                
        if(*fp=='#')
            break;
        else if(*fp==' ')
        {}
        else
        {
            fp=scanner(fp,i);
        }
    }while(*fp!='#');
    return i;
}

void GetWenfa()
{
    Gene gen;
    gen.left='S';
    gen.right="A";
    gene.push_back (gen);           

    gen.left ='A';
    gen.right ="V=E";
    gene.push_back (gen);               

    gen.left ='E';
    gen.right ="E+T";
    gene.push_back (gen);
    gen.right ="E-T";
    gene.push_back (gen);
    gen.right ="T";
    gene.push_back (gen);

    gen.left ='T';
    gen.right ="T*F";
    gene.push_back (gen);
    gen.right ="T/F";
    gene.push_back (gen);
    gen.right ="F";
    gene.push_back (gen);   

    gen.left ='F';
    gen.right ="i";
    gene.push_back (gen);
    gen.right ="(E)";
    gene.push_back (gen);

    gen.left ='V';
    gen.right ="i";
    gene.push_back (gen);

}

void Init()
{
    Goto[13][1]=9; Goto[13][3]=18;
    Goto[12][1]=9; Goto[12][3]=17;
    Goto[11][1]=9; Goto[11][2]=16;Goto[11][3]=7;
    Goto[10][1]=9; Goto[10][2]=15; Goto[10][3]=7; 
    Goto[9][1]=14; Goto[9][2]=6; Goto[9][3]=7;
    Goto[4][1]=5; Goto[4][2]=6; Goto[4][3]=7;
    Goto[0][0]=1; Goto[0][4]=2;;    
}

void error()
{
    cout<<"ERROR!"<<endl;
    cout<<"\n动作不存在!"<<endl;
    exit(-1);
}

void Output(vector<string> str)
{
    int len=str.size();
    for(int i=0;i<len;i++)
        cout<<str[i];
    cout<<"        \t";
}

void Yufafenxi(int num)
{                     
    Init(); 
    GetWenfa();                 
    vector<int> state;//状态栈
    vector<string> ana;//分析栈
    vector<string> an;//输入栈
    state.push_back (0);
    ana.push_back ("#");
    int i,j;
    int k=0;
    do{                                         
        for(int a=0;a<state.size();a++)//输出状态栈
            cout<<state[a];
        cout<<"\t\t";
        Output(ana);//输出分析栈                                         
        for(a=k;a<=num;a++)//输出剩余输入栈
            cout<<code[a].data;
        cout<<"\t";
        i=state[state.size()-1];        
        j=code[k].num ; 
        if(j==9)
            error();
        cout<<"\t"<<action[i][j].para<<action[i][j].val<<"\t";  //输出动作         
        if(action[i][j].para=='O')
            error();
        else if(action[i][j].para=='S')//移进 
        {                                                                       
            cout<<"移进"<<"\n";
            state.push_back (action[i][j].val);    
            ana.push_back (code[k].data);      
            an.push_back (code[k].data);
            k++;                         
        }
        else if(action[i][j].para=='R')//规约
        {                                                               
            cout<<"规约"<<"\t";
            int len;
            int tem=action[i][j].val;
            len=strlen(gene[tem].right);            
            while(len!=0)//将分析栈中的待约项规约
            {
                state.pop_back ();                          
                ana.pop_back ();                    
                len--;
            }
            cout<<gene[action[i][j].val].left<<"->"<<gene[action[i][j].val].right<<endl;//输出规约所用的产生式
            if(action[i][j].val==1||action[i][j].val==2||action[i][j].val==3||action[i][j].val==5||action[i][j].val==6||action[i][j].val==9)//输出三元式
            {   
                int  t=an.size()-1;
                if(action[i][j].val!=9)
                {
                    Seq++;
                    Equ[Seq][0]=an[t-1];
                    Equ[Seq][1]=an[t-2];
                    Equ[Seq][2]=an[t];

                }
                an.pop_back ();
                an.pop_back ();
                an.pop_back ();
                char c=Seq+'1'-1;           
                string str="(";
                str=str+c;
                str=str+")";                    
                an.push_back (str);
            }
            ana.push_back (gene[action[i][j].val].left);    
            int a=state[state.size()-1];            
            string b=ana[ana.size()-1];         
            int dex=0;
            while(Vn[dex]!=b[0])
                dex++;                                      
            if(Goto[a][dex]==0)
                error();
            else
                state.push_back (Goto[a][dex]);         
        }
        else if(action[i][j].para=='A')
        {
            cout<<"\n分析成功!\n";
            break;
        }
    }while(1);
    int n=1;
    cout<<"\n三元式:\n";
    while(n<=Seq)
    {
        cout<<"\n"<<n<<"\t";    
        cout<<"("<<Equ[n][0]<<",\t"<<Equ[n][1]<<",\t"<<Equ[n][2]<<")"<<endl;
        n++;
    }
}
int main(void)
{  
    num=Cifafenxi();        
    cout<<"词法分析结束"<<"\n";
    system("pause");
    code[num+1].data="#";
    code[num+1].num =8;
    num++;
    int i;
    cout<<"语法分析:\n";
    cout<<"状态栈      "<<"\t"<<"分析栈"<<"\t\t"<<"剩余输入栈"<<"\t"<<"   动作   "<<"\t产生式"<<"\n"; 
    Yufafenxi(num);             
    cout<<"语法分析结束\n";
    return 0;
}
毕业论文引言 随着计算机技术的发展与普及,计算机已经成为各行业最基本的工具之一,迅速进入千家万户。因此,掌握计算机应用的基本技能成为新世纪人才不可缺少的基本素质之一。为使计算机能正常工作, 除了构成计算机各个组成部分的物理设备外, 一般说来, 还必须要有指挥计算机“做什么”和“如何做”的“程序”。程序及其有关文档构成计算机软件, 其中用以书写计算机软件的语言称为计算机程序设计语言。 1 计算机程序设计语言简介 计算机程序设计语言是计算机可以识别的语言,用于描述解决问题的方法,供计算机阅读和执行,通常简称为编程语言,是一组用来定义计算机程序的语法规则。它是一种被标准化的交流技巧,用来向计算机发出指令。一种计算机语言让程序员能够准确地定义计算机所需要使用的数据,并精确地定义在不同情况下所应当采取的行动。使用程序设计语言往往使程序员能够比使用机器语言更准确地表达他们所想表达的目的。对那些从事计算机科学的人来说,懂得程序设计语言是十分重要的,因为所有的程序都需要程序设计语言才能完成,而计算机的工作是用程序来控制的,离开了程序,计算机将一事无成。 2 开发背景及意义 现有计算器不能计算表达式,这是一个缺陷,为此,开发了一个能直接计算表达式计算器,这为计算提高了更大的方便,可以大幅度提高计算效率。 第二章 第三章 第一节 递归下降法的描述 3.1.1实现思想 它的主要原理是,对每个非终极符按其产生结构构造相应语法分析子程序,其中终极符产生匹配命令,而非终极符则产生过程调用命令。因为文法递归相应子程序也递归,所以称这种方法为递归子程序下降法或递归下降法。其中子程序的结构与产生结构几乎是一致的。文法中每个非终结符对应一个递归过程(子程序),每个过程的功能是识别由该非终结符推出的串,当某非终结符的产生有多个候选时能够按LL(1)形可唯一地确定选择某个候选进行推导。 3.1.2算法的特点 递归下降法是语法分析中最易懂的一种方法。递归下降法要满足的条件:假设A的全部产生为Aα1|α2|……|αn ,则必须满足如下条件才能保证可以唯一的选择合适的产生 predict(Aαi)∩predict(Aαj)=Φ,当i≠j. 3.1.3构造递归下降语法分析程序 采用了递归子程序方法进行语法分析,对文法中的每个非终极符号按其产生结构产生相应的语法分析子程序,完成相应的识别任务。其中终结符产生匹配命令,非终结符则产生调用命令。每次进入子程序之前都预先读入一个单词。因为使用了递归下降方法,所以程序结构和层次清晰明了,易于手工实现,且时空效率较高。实际的语法分析工作,从调用总程序的分析子程序开始,根据产生进行递归调用各个分析子程序。 第二节
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值