1. 程式人生 > >語法分析器之遞迴子程式法

語法分析器之遞迴子程式法

這道題目有點坑,就是F(E)時,只應該輸出一次就可以了,但是這道題卻要在識別"("時輸出一次,在識別")"輸出一次。

還好重判 了。

//因為題目要求只輸入一組,所以此程式碼在遇到錯誤表示式時執行exit(0)操作,所以會退出程式
#include<stdio.h>
#include<stdlib.h>  //exit(0)函式標頭檔案


char st[60];	//輸入字串
int h=0;	//當前處理字元
int i=0;	//輸出序列標記


void E();
void T();
void G();
void F();
void S();


void E()
{
    printf("%d E-->TG\n",i++);
    T();
    G();
}


void T()
{
    printf("%d T-->FS\n",i++);
    F();
    S();
}


void S()
{
    if(st[h]=='*')
    {
        printf("%d S-->*FS\n",i++);
        h++;
        F();
        S();
    }
    else
    {
        printf("%d S-->&\n",i++);
    }
}


void G()
{
    if(st[h]=='+')
    {
        printf("%d G-->+TG\n",i++);
        h++;
        T();
        G();
    }
    else
    {
        printf("%d G-->&\n",i++);
    }
}


void F()
{
    if(st[h]=='i')
    {
        printf("%d F-->i\n",i++);
        h++;
    }
    else if(st[h]=='(')
    {
        printf("%d F-->(E)\n",i++);
        h++;
        E();
        if(st[h]==')')
        {
            //printf("%d F-->(E)\n",i++);//有疑問
            h++;
        }
        else
        {
            //printf("括號不匹配\n");
            printf("error\n");
            exit(0) ; //終止程式
        }
    }
    else
    {
        // printf("非法字元或括號不匹配\n");
        printf("error\n");
        exit(0) ; //終止程式
    }
}


int main()
{
    scanf("%s",st);
    //int len=strlen(st);


    E();	//從文法開始符E開始


    // if(h<len-1)
    //   printf("非法字元\n");
    // else
    if(st[h]!='#')	//如果結束符不是'#',則表示式不正確
    {
        // printf("無終結符'#'\n");
        printf("error\n");
    }
    else printf("accept\n");
    return 0;
}
//若想多組輸入,可以這樣
#include<iostream>  
#include<cstdio>  
#include<cstring>  
#include<string>  
#include<algorithm>  
#include<map>  
#include<stack>  
#include<queue>  
#include<cmath>  
  
using namespace std;  
  
string in;  
int I,pos;  
bool error,over;  
void __S();  
void __F();  
void __G();  
void __T();  
void __E()  
{  
//    cout<<"___________E"<<endl;  
    if(error)  
        return;  
    printf("%d E-->TG\n",I++);  
    __T();  
    __G();  
}  
void __T()  
{  
//    cout<<"___________T"<<endl;  
    if(error)  
        return;  
    printf("%d T-->FS\n",I++);  
    __F() ;  
    __S();  
}  
void __G()  
{  
//    cout<<"___________G"<<endl;  
    if(error)  
        return;  
    if(in[pos]=='+')  
    {  
        printf("%d G-->+TG\n",I++);  
        pos++;  
        __T() ;  
        __G();  
        return;  
    }  
    printf("%d G-->&\n",I++);  
    if(in[pos]=='#')  
        over=true;  
}  
void __F()  
{  
//    cout<<"___________F"<<endl;  
    if(error)  
        return;  
    if(in[pos]=='(')  
    {  
        printf("%d F-->(E)\n",I++);  
        pos++;  
        __E();  
        if(in[pos]!=')')  
            error=true;  
        //else  
            //printf("%d F-->(E)\n",I++);  
        pos++;  
        return;  
    }  
    if(in[pos]=='i')  
    {  
        printf("%d F-->i\n",I++);  
        pos++;  
        return;  
    }  
    error=true;  
}  
void __S()  
{  
//    cout<<"___________S"<<error<<endl;  
    if(error)  
        return;  
    if(in[pos]=='*')  
    {  
        printf("%d S-->*FS\n",I++);  
        pos++;  
        __F();  
        __S();  
        return;  
    }  
    if(in[pos]=='#')  
        over=true;  
    printf("%d S-->&\n",I++);  
}  
int main()  
{  
    while(cin>>in)  
    {  
        I=0;  
        error=over=false;  
        pos=0;  
        __E();  
        if(error || !over)  
            printf("error\n");  
        else  
            printf("accept\n");  
    }  
}  
//PS:非本人


相關推薦

語法分析器程式法

這道題目有點坑,就是F→(E)時,只應該輸出一次就可以了,但是這道題卻要在識別"("時輸出一次,在識別")"輸出一次。 還好重判 了。 //因為題目要求只輸入一組,所以此程式碼在遇到錯誤表示式時執行exit(0)操作,所以會退出程式#include<stdio.h> #include<

表示式語法分析——程式法

Problem Description 遞迴子程式法是一種確定的自頂向下語法分析方法,要求文法是LL(1)文法。它的實現思想是對應文法中每個非終結符編寫一個遞迴過程,每個過程的功能是識別由該非終結

python入門

表現形式:   函式體裡包含執行本身 def f1(): r = f1() f1()   例項:   斐波那契數   (a1+a2=a3   a2+a3=a4   a3+a4=a5   ......) def f1(a1,a2):

自學C理解

一、 理解概念   C語言允許一個函式呼叫自身,這種過程被稱為遞迴(Recursion)。程式使用遞迴處理特殊的問題,如階乘、 Ackermann函式,反序等等。實際上,如果不考慮執行時記憶體的開消,任何使用賦值語句、if-else和while結構的函 數都可以用遞迴方式重寫。

二叉樹遍歷演算法

作者:石鍋拌飯  原文連結 二叉樹的遍歷演算法有多種,典型的有先序遍歷、中序遍歷、後序遍歷以及層序遍歷。而且這些遍歷的遞迴演算法較為簡單,程式碼很少,容易實現,本文就是彙總二叉樹遍歷的遞迴演算法,非遞迴演算法將在下一篇文章中進行總結。本文中用到的二叉樹例項如下:

python函式

遞迴:自己呼叫自己 無限遞迴:和死迴圈不一樣 避免無限遞迴---遞迴收斂條件 遞迴應用於難題---思想(思路) 遞迴:效率低,佔資源 能用遞迴的一定能用迴圈 解決階乘:(把大問題拆分成小問題)解決大問題的思路和小問題思路完全一樣,則可以是用遞迴的思想 def jc(n):  

Linux高階程式設計基礎——檔案系統程式設計遍歷/home目錄

檔案系統程式設計之遞迴遍歷/home目錄 /編寫程式完成以下功能: 1.遞迴遍歷/home目錄,打印出所有檔案和子目錄名稱及節點號。 2.判斷檔案型別,如果是子目錄,繼續進行遞迴遍歷,直到遍歷完所有子目錄為止。/ #include <stdio.h> #include &

python函式,二分查詢

遞迴函式 遞迴函式一直都是我們所覺得難理解的以一種方式,但其實,也很好理解的,遞迴函式就是自己呼叫自己。就是在重複的做同一件事情。只是有的時候,也最好不要使用遞迴函式,因為你的函式一旦呼叫,就要開闢新的記憶體空間。不利於程式的執行。python對你記憶體一個保護機制,預設只能遞迴到998

php演算法排序

<?php function quickSort($arr) { if(count($arr) > 1) { $k=$arr[0]; $x=array(); $y=array(); $_size=count($arr);

左神第八課演算法

題目一 求n! 簡單得不想說 題目二 漢諾塔問題 古代有一個梵塔,塔內有三個座A、B、C,A座上有64個盤子,盤子大小不等,大的在下,小的在上(如圖)。有一個和尚想把這64個盤子從A座移到C座,但每次只能允許移動一個盤子,並且在移動過程中,3個座上的盤子始終

資料結構與演算法

1、背景 現在很多App都有這個功能。使用者A來推薦使用者B來註冊,使用者B又推薦了使用者C來註冊,我們可以說,使用者C的“最終推薦人”為使用者A,使用者B的"最終推薦按人”也為使用者A,而使用者A沒有"最終推薦人"。 一般來說,我們會通過資料庫來記錄這種推薦關係。在資料庫表中,我們可以

10-Python函式

Python函式之遞迴     主要內容:遞迴知識、遞迴例項、總結三部分 一.遞迴知識 遞迴函式就是函式自己內部呼叫自己。注意兩個知識點: 遞迴:定義函式時候,函式本身自己內部呼叫自己。 巢狀:定義函式時候,函式內部重新定義新

Python3&資料結構

#遞迴 def fact(x): if x == 1: return 1 else: return x * fact(x - 1) #tail recursion(尾遞迴) def tail_recusion(x,total=1): if

執行時型別資訊(RTTI)列印類資訊

深度優先 public class ClassPrint { private static void printSupers(Class<?> clazz) { String name = clazz.getCanonicalName(); System.out.p

12.scrapy框架解析和post請求

今日概要 遞迴爬取解析多頁頁面資料 scrapy核心元件工作流程 scrapy的post請求傳送 今日詳情 1.遞迴爬取解析多頁頁面資料 - 需求:將糗事百科所有頁碼的作者和段子內容資料進行爬取切持久化儲存 - 需求分析:每一個頁面對應一個url,則scrapy工程需要對每一個頁碼

C++ 二叉樹程式設計實戰遍歷

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> //二叉樹節點 typedef struct BINAR

python演算法演算法

# -*- coding: utf-8 -*- import numpy as np # 遞迴演算法 i = 0 def my_Recursion(list, n): global i try: if list[i] == n:

編譯原理:語法分析1-下降

要求: 使用的文法如下: E →TE’ E → + TE’ | ε T → FT’ T →* FT’ | ε F → (E) | id 對於任意給定的輸入串(詞法記號流)進行語法分析,遞迴下降方法實現。 要有一定的錯誤處理功能。即對錯誤能提示,並且

【資料結構與演算法】的基本介紹---第六篇

一、遞迴的基本概念 1、定義 遞迴:指的是一個過程,函式直接或者間接的呼叫自己,此時則發生了遞迴。 遞迴的兩個要素:遞推公式和遞迴邊界 可以看到遞迴的定義非常的簡潔,但是理解起來就沒有這麼容易了。不知道大家是否和我一樣,在遇到遞迴問題的時候,總是試圖去一步一步的分

Day6 python、 內建函式等(4)

一、操作mysql 連線資料庫 import pymysql conn = pymysql.connect(host='118.24.3.40',user='jxz', password='123456',port=3306, db='