递归下降语法分析

一、实验目的:

利用C语言编制递归下降分析程序,并对简单语言进行语法分析。

编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

 

二、实验原理

每个非终结符都对应一个子程序。

该子程序根据下一个输入符号(SELECT集)来确定按照哪一个产生式进行处理,再根据该产生式的右端:

  • 每遇到一个终结符,则判断当前读入的单词是否与该终结符相匹配,若匹配,再读取下一个单词继续分析;不匹配,则进行出错处理
  • 每遇到一个非终结符,则调用相应的子程序

 

三、实验要求说明

输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。

例如:

输入begin a:=9;x:=2*3;b:=a+x end #

输出success

输入x:=a+b*c  end #

输出‘end' error

 

四、实验步骤

      1.待分析的语言的语法(参考P90)

      2.将其改为文法表示,至少包含

–语句

–条件

–表达式

3. 消除其左递归

4. 提取公共左因子

5. SELECT集计算

6. LL(1)文法判断

7. 递归下降分析程序

#include "stdio.h" 
#include "string.h" 
 
 
char prog[100],token[8],ch; 
char *rwtab[6]={"begin","if","then","while","do","end"}; 
int syn,p,m,n,sum; 
int kk; 
 
void factor(void); 
void expression(void); 
void yucu(void); 
void term(void); 
void statement(void); 
void lrparser(void); 
void scaner(void); 
 
 
int main(void) 
{ 
    p=kk=0; 
    printf("\nplease input a string: \n"); 
 
    do 
    { 
        scanf("%c",&ch); 
        prog[p++]=ch; 
    }while(ch!='#'); 
 
    p=0; 
    scaner(); 
    lrparser(); 
    //getch(); 
} 
 
void lrparser(void) 
{ 
    if(syn==1) 
    {  
        scaner();       /*读下一个单词符号*/ 
        yucu();     /*调用yucu()函数;*/ 
 
        if(syn==6) 
        { 
            scaner(); 
            if((syn==0)&&(kk==0)) 
            printf("success!\n"); 
        } 
        else 
        { 
            if(kk!=1) printf("error!\n"); 
            kk=1; 
        } 
    } 
    else 
    {  
        printf("error!\n"); 
        kk=1; 
    } 
     
    return; 
} 
 
void yucu(void) 
{  
    statement();         /*调用函数statement();*/ 
 
    while(syn==26) 
    { 
        scaner();          /*读下一个单词符号*/ 
        if(syn!=6)  
            statement();         /*调用函数statement();*/ 
    }  
     
    return; 
} 
 
void statement(void) 
{ 
    if(syn==10) 
    { 
        scaner();        /*读下一个单词符号*/ 
        if(syn==18) 
        { 
            scaner();      /*读下一个单词符号*/ 
            expression();      /*调用函数statement();*/ 
        } 
        else 
        { 
            printf("the sing ':=' is wrong!\n"); 
            kk=1; 
        } 
    } 
    else 
    {  
        printf("wrong sentence!\n"); 
        kk=1; 
    } 
     
    return; 
} 
 
void expression(void) 
{ 
    term(); 
 
    while((syn==13)||(syn==14)) 
    { 
        scaner();             /*读下一个单词符号*/ 
        term();               /*调用函数term();*/ 
    } 
     
    return; 
} 
 
void term(void) 
{  
    factor(); 
 
    while((syn==15)||(syn==16)) 
    {  
        scaner();             /*读下一个单词符号*/ 
        factor();              /*调用函数factor(); */ 
    } 
     
    return; 
} 
 
void factor(void) 
{  
    if((syn==10)||(syn==11)) 
    { 
        scaner(); 
    } 
    else if(syn==27) 
    {  
        scaner();           /*读下一个单词符号*/ 
        expression();        /*调用函数statement();*/ 
 
        if(syn==28) 
        { 
            scaner();          /*读下一个单词符号*/ 
        } 
        else  
        { 
            printf("the error on '('\n"); 
            kk=1; 
        } 
    } 
    else 
    {  
        printf("the expression error!\n"); 
        kk=1; 
    } 
     
    return; 
} 
void scaner(void) 
{ 
    sum=0; 
 
    for(m=0;m<8;m++) 
        token[m++]=NULL; 
     
    m=0; 
    ch=prog[p++]; 
     
    while(ch==' ') 
        ch=prog[p++]; 
     
    if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))) 
    {  
        while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) 
        { 
            token[m++]=ch; 
            ch=prog[p++]; 
        } 
        p--; 
        syn=10; 
        token[m++]='\0'; 
        for(n=0;n<6;n++) 
        if(strcmp(token,rwtab[n])==0) 
        { 
            syn=n+1; 
            break; 
        } 
    } 
    else if((ch>='0')&&(ch<='9')) 
    { 
        while((ch>='0')&&(ch<='9')) 
        {  
            sum=sum*10+ch-'0'; 
            ch=prog[p++]; 
        } 
        p--; 
        syn=11; 
    } 
    else 
    switch(ch) 
    { 
        case '<': 
            m=0; 
            ch=prog[p++]; 
            if(ch=='>') 
            {  
                syn=21; 
            } 
            else if(ch=='=') 
            {  
                syn=22; 
            } 
            else 
            {  
                syn=20; 
                p--; 
            } 
        break; 
         
        case '>': 
            m=0; 
            ch=prog[p++]; 
            if(ch=='=') 
            {  
                syn=24; 
            } 
            else 
            { 
                syn=23; 
                p--; 
            } 
        break; 
         
        case ':': 
            m=0; 
            ch=prog[p++]; 
            if(ch=='=') 
            { 
                syn=18; 
            } 
            else 
            { 
                syn=17; 
                p--; 
            } 
            break; 
             
        case '+': 
            syn=13; 
        break; 
         
        case '-':  
            syn=14; 
        break; 
         
        case '*': 
            syn=15; 
        break; 
         
        case '/':  
            syn=16; 
        break; 
         
        case '(':  
            syn=27; 
        break; 
         
        case ')':  
            syn=28; 
        break; 
         
        case '=': 
            syn=25; 
        break; 
         
        case ';':  
            syn=26; 
        break; 
         
        case '#': 
            syn=0; 
        break; 
         
        default: 
            syn=-1; 
        break; 
    } 
} 

  参考网上

posted @ 2019-11-29 09:51  小罗伯特唐尼  阅读(245)  评论(0)    收藏  举报