編譯原理PL0語法分析實驗1

編譯原理PL0語法分析實驗1

1,待分析的簡單語言的詞法
相同點:都是分析種別碼
不同點:詞法分析器分析的是字符串中的單詞的種別碼(單詞)
語法分析器分析的是字符串的文法是否正確(句子)
待分析的簡單語言的語法

BNF:
(1)<程序>::=begin<語句串>end
(2)<語句串>::=<語句>{;<語句>}
(3)<語句>::=<賦值語句>
(4)<賦值語句>::=ID:=<表達式>
(5)<表達式>::=<項>{+<項>|-<項>}
(6)<項>::=<因子{*<因子>|/<因子>}

語法分析程序的功能
輸入一個c語言的字符串,以#號結束,如果是文法正確的句子,那麼程序就會輸出成功信息;如果是文法錯誤的句子,那麼程序就會輸出錯誤的信息以及提示出錯點在哪裏
正確的文法:begin BNF文法 end#

【例1】
給定一個字符串,判斷語法是否正確:
輸入:begin a:=9;x:=2*3;b:=a+x end#
輸出:成功!
輸入:begin x:=a+b*c end
輸出:錯誤!“end”後出錯了
輸入:begin x:=a+b*c
輸出:錯誤!缺少“end”
輸入:x:=a+b*c end#
輸出:錯誤!缺少begin
程序驗證代碼(語法分析程序)

#include <studio.h>
#include <string.h>
void scaner();
void sentence();
void statement();
void expression();
void term();
void factor();
char *key[0]={"begin","if","then","while","do","end"},ch[100];
int p=0,kk=0,q,syn;
int main()
{
  printf("輸入:\n");
  gets(ch);
  sentence();
  return 0;
}

void scanner()
{
  char token[100] = {};
  q = 0;
  while(ch[p] == ' ') p++;
  if((ch[p] >= 'a' && ch[p] <= 'z')||(ch[p] >= 'A' && ch[p] <= 'Z')
  {
        token[q++] = ch[p];
        p++;
        while((ch[p] >= '0' && ch[p] <= '9')||(ch[p] >= 'a' && ch[p] <= 'z') ||(ch[p] >= 'A' && ch[p] <= 'Z')) 
            token[q++] = ch[p++];

     syn = 10;
     token[q] = '\0';
     for(int n = 0;n < 6;n++)
        {
            if(strcmp(token,key[n]) == 0)
          {
               syn = n + 1;
             break;
          }
        }
    }
   else if(ch[p] >= '0' && ch[p] <= '9')
    {
        token[q++] = ch[p];
     p++;
     while(ch[p] >= '0' && ch[p] <= '9') 
            token[q++] = ch[p++];

     syn = 11;
    }
    else switch(ch[p])
    {
        case '<':
            token[q++] = ch[p++];
          if(ch[p] == '>')
          {
               syn = 21;
            token[q++] = ch[p++];
          }  
          else if(ch[p] == '=')
          {
            syn = 22;
                token[q++] = ch[p++];
          }
          else 
                syn = 23;
          break;
     case '>':
            token[q++] = ch[p++];
          if(ch[p] == '>')
            {
                syn = 24;
                token[q++] = ch[p++];
         }
            else 
                syn = 20;

            break;

        case ':':
            token[q++] = ch[p++];
            if(ch[p] == "="){
                syn = 18;
                token[q++] = ch[p++];
            }
            else 
                syn = 17;
            token[q++] = ch[p++];
            break;
        case '*':
            syn = 13;
            token[q++] = ch[p++];
            break;
        case '/':
            syn = 14;
            token[q++] = ch[p++];
            break;
        case '+':
            syn = 15;
            token[q++] = ch[p++];
            break;
        case '-':
            syn = 16;
            token[q++] = ch[p++];
            break;
        case '=':
            syn = 25;
            token[q++] = ch[p++];
            break;
        case ';':
            syn = 26;
            token[q++] = ch[p++];
            break;
        case '(':
            syn = 27;
            token[q++] = ch[p++];
            break;
        case ')':
            syn = 28;
            token[q++] = ch[p++];
            break;
        case '#':
            syn = 0;
            token[q++] = ch[p++];
            break;
        case '\n':
            syn = -2;
            break;
        default:
            syn = -1;
            break;
    }
}

void sentence()
{
    scaner();
    if(syn == 1)
    {
        statement();
        while(syn == 26) statement();
        if(syn == 6)
        {
            scaner();
            if(syn == 0) printf("成功!\n");
            else printf("錯誤!“end”後出錯。\n");
        }
        else
        {
            printf("錯誤!缺少“end”。\n");
            kk = 1;
        }
    }
    else
    {
        printf("錯誤!缺少“begin”。\n");
        kk = 1;
    }
}

void statement()
{
    scaner();
    if(syn == 10)
    {
        scaner();
        if(syn == 18)
        {
            scaner();
            expression();
        }
        else
        {
            printf("錯誤!“:=”出錯。\n");
            kk = 1;
        }
    }
    else    
    {
        printf("錯誤!句子出錯。\n");
        kk = 1;
    }
    return;
}

void expression()
{
    term();
    while((syn == 13)||(syn == 14))
    {
        scaner();
        term();
    }
    return;
}

void term()
{
  factor();
  while((syn == 15)||(syn == 16))
  {
    scaner();
    factor();
  }  
    return;
}

void factor()
{
    if((syn == 10)||(syn == 11)) scaner();
    else if(syn == 27)
    {
        scaner();
        expression();
        if(syn == 28) scaner();
        else
        {
            printf("錯誤!“(”出錯。\n");
            kk = 1;
        }
    }
    else
    {
        printf("錯誤!\n");
        kk = 1;
    }
    return;
}

//begin a:=9;x:=2*3;b:=a+x end#
//begin x:a+b*c en

————————————————

版權聲明:本文爲博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。

 

原文鏈接:https://blog.csdn.net/qq_44709970/article/details/121804295

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章