12、递归下降语法分析

一、实验目的:

利用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"
#include "conio.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("
请输入字符串并以#结束: 
");
  
    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!
");
        }
        else
        {
            if(kk!=1) printf("error!
");
            kk=1;
        }
    }
    else
    { 
        printf("error!
");
        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!
");
            kk=1;
        }
    }
    else
    { 
        printf("wrong sentence!
");
        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 '('
");
            kk=1;
        }
    }
    else
    { 
        printf("the expression error!
");
        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++]='';
        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;
    }
}
--------------------------------------------------------------------------------
 实验截图

原文地址:https://www.cnblogs.com/dyun3/p/11959262.html