国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

編譯原理:算符優(yōu)先分析算法的設(shè)計與實現(xiàn)(含代碼)

這篇具有很好參考價值的文章主要介紹了編譯原理:算符優(yōu)先分析算法的設(shè)計與實現(xiàn)(含代碼)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

算符優(yōu)先分析算法的設(shè)計與實現(xiàn)

寫在最前面:我的編譯原理學(xué)的不是很好,不怎么聽課,所以我寫代碼的思路比較簡單。簡單的思路也就意味著代碼很笨重,介意的話請點叉叉。如果有什么指教歡迎評論區(qū)留言。

特別說明:本博代碼在識別:
E→E+T
E→E-T
E→T
時,firstvt集和lastvt集可能會出現(xiàn)錯誤。
最好合并為以下形式:
E→E+T|E-T|T

一、實驗?zāi)康?/strong>

1.根據(jù)算符優(yōu)先分析法,對表達式進行語法分析,使其能夠判斷一個表達式是否正確。

2.通過算符優(yōu)先分析方法的實現(xiàn),加深對自下而上語法分析方法的理解。

二、 實驗內(nèi)容

1.輸入文法??梢允侨缦滤阈g(shù)表達式的文法(你可以根據(jù)需要適當改變):

E→E+T|E-T|T
T→T*F|T/F|F
F→(E)|i

2.對給定表達式進行分析,輸出表達式正確與否的判斷。

程序輸入/輸出示例:

輸入:1+2;
輸出:正確

輸入:(1+2)/3+4-(5+6/7);
輸出:正確

輸入:((1-2)/3+4
輸出:錯誤

輸入:1+2-3+(*4/5)
輸出:錯誤

3.根據(jù)文法求FIRSTVT集和LASTVT集

給定一個上下文無關(guān)文法,根據(jù)算法設(shè)計一個程序,求文法中每個非終結(jié)符的FirstVT 集和LastVT 集。

找Firstvt的三條規(guī)則
如果要找A的Firstvt, A的候選式中出現(xiàn):
A->a…,即以終結(jié)符開頭,a入 Firstvt
A->B…,即以非終結(jié)符開頭,B的Firstvt入A的Firstvt
A->Ba…,即先以非終結(jié)符開頭,緊跟終結(jié)符,則a入Firstvt

找Lastvt的三條規(guī)則
如果要找A的Lastvt, A的候選式中出現(xiàn):
A->…a,即以終結(jié)符結(jié)尾,a入Lastvt
A->…B,即以非終結(jié)符結(jié)尾,B的Lastvt入A的Lastvt
A->…aB,即先以非終結(jié)符結(jié)尾,前面是終結(jié)符,則a入Lastvt

根據(jù)上述求firstvt和lastvt的方法,我們計算一下我給的例子,得到的最終結(jié)果如下。
編譯原理:算符優(yōu)先分析算法的設(shè)計與實現(xiàn)(含代碼)

4.構(gòu)造算符優(yōu)先分析表

我先概述一下構(gòu)造方法:
在右邊的產(chǎn)生式中,找每個終結(jié)符。

  1. 如果就單一個終結(jié)符,那么忽略不看。
  2. 先找出…aB…這種形式,這代表a<firstvt(B)。
    在算符優(yōu)先分析表的左邊一列中找到a,然后向右在對應(yīng)的每個firstvt(B)的元素的位置上標上<。
  3. 再找…Ba…這種形式,這代表a>lastvt(B)。
    在算符優(yōu)先分析表的上面一行中找到a,然后向下在對應(yīng)的每個lastvt(B)的元素的位置上標上>。
  4. 如果有…ab…或…aCb…這兩種情況,則在a行b列的位置上標上=。

下面我來結(jié)合例子講一下:
首先構(gòu)造好表:

+ - * / ( ) i #
+
-
*
/
(
)
i
#

然后我們先看文法的第一行:
E->E+T|E-T|T
第一個終結(jié)符為+。
其實E+T就代表著lastvt(E) < + < firstvt(T)。
我們每次都要先看<,再看>。
+ < firstvt(T),
即+ < * , / , ( , i。
<是從左向右,所以要在
(+,*) (+,/) (+,() (+,i)
這四個位置標上<。
即:

+ - * / ( ) i #
+ < < < <
-
*
/
(
)
i
#

然后再看>。
+ > lastvt(E),
即+ > + , - , * , / , ) , i。
>是從上到下,所以要在
( +,+) (-,+) (*,+) (/,+) (),+) (i,+)
這六個位置上標上>。
即:

+ - * / ( ) i #
+ > < < < <
- >
* >
/ >
(
) >
i >
#

前兩行文法:
E->E+T|E-T|T
T->T*F|T/F|F

其中的+ , - , * , /都和我上面說的情況一樣。
可得下表:

+ - * / ( ) i #
+ > > < < < <
- > > < < < <
* > > > > < <
/ > > > > < <
(
) > > > >
i > > > >
#

最后,我們來看最后一個文法:
F->(E)|i
i只是一個終結(jié)符,不存在大小關(guān)系,不看它。
而(E)就是
( < firstvt(E);
) > lastvt(E)。
并且(E)滿足…aBc…的情況,要在第(行,第)列的位置((,))上標上=。
可得下表:

+ - * / ( ) i #
+ > > < < < > <
- > > < < < > <
* > > > > < > <
/ > > > > < > <
( < < < < < = <
) > > > > >
i > > > > >
#

最后的最后,如果要考慮#。
我們按照#E#的樣子考慮。
即:
# < firstvt(E);
# > lastvt(E)。
并且#E#滿足…aBc…的情況,要在第#行,第#列的位置(#,#)上標上=。
可得最終表:

+ - * / ( ) i #
+ > > < < < > < >
- > > < < < > < >
* > > > > < > < >
/ > > > > < > < >
( < < < < < = <
) > > > > > >
i > > > > > >
# < < < < < < =

這就是我們要求的算符優(yōu)先分析表了。

5.對給定的表達式,給出準確與否的分析過程,給出表達式的計算結(jié)果。
在規(guī)約的時候我們其實可以直接看文法就行了(如果文法比較簡單的話),但我還是講一下如何根據(jù)算符優(yōu)先分析表來進行規(guī)約。

一句話:棧的最右邊的終結(jié)符,和輸入串的最左邊的終結(jié)符,在表中查出對應(yīng)位置為<,>還是=。<則移進,>則規(guī)約,=則先移進再規(guī)約。若表中對應(yīng)位置是空格,則表示該表達式是錯誤的。

舉個例子:#(i+i)/i+i-(i+i/i)#

步驟 輸入串 動作
0 # (i+i)/i+i-(i+i/i)# 預(yù)備
1 #( i+i)/i+i-(i+i/i)# 查表,(#,()=<,移進
2 #(i +i)/i+i-(i+i/i)# 查表,((,i)=<,移進
3 #(N +i)/i+i-(i+i/i)# 查表,(i,+)=>,規(guī)約(N可以換成其它大寫字母)
4 #(N+ i)/i+i-(i+i/i)# ((,+)=<,移進
5 #(N+i )/i+i-(i+i/i)# (+,i)=<,移進
6 #(N+N )/i+i-(i+i/i)# (i,))=>,規(guī)約
7 #(N )/i+i-(i+i/i)# (+,))=>,規(guī)約
8 #(N) /i+i-(i+i/i)# ((,))==,先移進
9 #N /i+i-(i+i/i)# 后規(guī)約
10 #N # 好了,偷個懶,不想寫了,反正<,>,=三種情況都有了,自己舉一反三吧

三、實驗代碼

//owner:junfuxiaotong
//date:2021/11/28
#include<bits/stdc++.h>
#include<cstdlib>
using namespace std;
#define N 100
#define true 1
#define false -1
char wenfa[N][N];
char VN[N],VT[N];
char firstvt[N][N],lastvt[N][N],table[N][N];
int vnvt(int n)//獲取vn vt
{
    int flag=true;
    for(int i=0;i<n;i++)
    {
        if((wenfa[i][0]>='A'&&wenfa[i][0]<='Z')&&wenfa[i][1]=='-'&&wenfa[i][2]=='>')
        {
            int sign=true;
            for(int j=0;j<strlen(VN);j++)
            {
                if(VN[j]==wenfa[i][0])
                {
                    sign=false;
                    break;
                }
            }
            if(sign==true)
            {
                VN[strlen(VN)]=wenfa[i][0];
            }
            else if(sign==false)
            {
                continue;
            }
        }
        else
        {
            flag=false;
            break;
        }
    }
    if(flag==false)
    {
        return flag;
    }
    else
    {
        int k=0;
        int l=0;
        for(int i=0;i<n;i++)
        {
            for(int j=3;wenfa[i][j]!='\0';j++)
            {
                if((wenfa[i][j]<'A'||wenfa[i][j]>'Z')&&wenfa[i][j]!='|')
                {
                    for(l=0;l<k;l++)
                    {
                        if(wenfa[i][j]==VT[l])
                        {
                            break;
                        }
                    }
                    if(l==k)
                    {
                        VT[k]=wenfa[i][j];
                        k++;
                    }
                }
            }
        }
        return flag;
    }
}
void getfirstvt(int n)
{
    // int point=0;//用于指向每一個產(chǎn)生式的前兩個符號
    for(int i=0;i<n;i++)//首先是找到每個產(chǎn)生式的前兩個符號是否是終結(jié)符,是就加入到對應(yīng)的firstvt集中。
    {
        int flag=true;
        for(int j=3;;)
        {
            for(int k=0;k<strlen(VT);k++)
            {
                if(wenfa[i][j]==VT[k])
                {
                    int mark=true;//用于檢查firstvt集中是否已經(jīng)存在該終結(jié)符。
                    for(int l=0;l<strlen(firstvt[i]);l++)
                    {
                        if(wenfa[i][j]==firstvt[i][l])
                        {
                            mark=false;
                            break;
                        }
                    }
                    if(mark==true)//若不存在,則加入到firstvt集中
                    {
                        int length=strlen(firstvt[i]);
                        firstvt[i][length]=wenfa[i][j];
                    }
                }
                if(wenfa[i][j+1]==VT[k])
                {
                    int mark=true;
                    for(int l=0;l<strlen(firstvt[i]);l++)
                    {
                        if(wenfa[i][j+1]==firstvt[i][l])
                        {
                            mark=false;
                            break;
                        }
                    }
                    if(mark==true)
                    {
                        int length=strlen(firstvt[i]);
                        firstvt[i][length]=wenfa[i][j+1];
                    }
                }
            }
            while(wenfa[i][j]!='|')
            {
                if(wenfa[i][j]=='\0')
                {
                    flag=false;
                    break;
                }
                j++;
            }
            j++;
            if(flag==false)
            {
                break;
            }
        }
    }
    //下面的代碼是循環(huán)查看哪些非終結(jié)符的firstvt集可以加入到另一些非終結(jié)符的firstvt集中,一直循環(huán)添加,直到每個非終結(jié)符的長度不再變化為止。
    int *origin=new int[n];//用于記錄遍歷之前的數(shù)組長度,看是否有變化。
    while(1)
    {
        int sign=true;//用于標識遍歷前后firstvt是否有變化。mark,symbol。
        for(int i=0;i<n;i++)
        {
            if(origin[i]!=strlen(firstvt[i]))
            {
                sign=false;//長度有變化
                origin[i]=strlen(firstvt[i]);
            }
        }
        if(sign==true)
        {
            break;
        }
        for(int i=0;i<n;i++)
        {
            for(int j=3;;)
            {
                for(int k=0;k<n;k++)
                {
                    if(k==i)
                    {
                        continue;
                    }
                    else if(wenfa[i][j]==wenfa[k][0])
                    {
                        for(int l=0;l<strlen(firstvt[k]);l++)
                        {
                            int flag=true;//用于標識一個終結(jié)符是否已經(jīng)在firstvt集中,true為不在其中的意思。
                            for(int m=0;m<strlen(firstvt[i]);m++)
                            {
                                if(firstvt[k][l]==firstvt[i][m])
                                {
                                    flag=false;
                                    break;
                                }
                            }
                            if(flag==false)
                            {
                                continue;
                            }
                            else
                            {
                                int length=strlen(firstvt[i]);
                                firstvt[i][length]=firstvt[k][l];
                            }
                        }
                    }
                }
                int flag=true;
                while(wenfa[i][j]!='|')
                {
                    if(wenfa[i][j]=='\0')
                    {
                        flag=false;
                        break;
                    }
                    j++;
                }
                if(flag==false)
                {
                    break;
                }
                j++;
            }
        }
    }
}
void getlastvt(int n)//獲取lastvt集,此函數(shù)下標我是從abc...這么開始的,我也不知道為啥要這么干
{
    for(int a=0;a<n;a++)
    {
        for(int b=0;;)
        {
            int sign=true;//用于標識是否到了一句分法的末尾
            while(wenfa[a][b]!='|')
            {
                if(wenfa[a][b]=='\0')
                {
                    sign=false;
                    break;
                }
                b++;
            }
            for(int c=0;c<strlen(VT);c++)
            {
                if(wenfa[a][b-1]==VT[c])
                {
                    int flag=true;
                    for(int e=0;e<strlen(lastvt[a]);e++)
                    {
                        if(wenfa[a][b-1]==lastvt[a][e])
                        {
                            flag=false;
                            break;
                        }
                    }
                    if(flag==true)
                    {
                        int length=strlen(lastvt[a]);
                        lastvt[a][length]=VT[c];
                    }
                }
                if(wenfa[a][b-2]==VT[c])
                {
                    int flag=true;
                    for(int e=0;e<strlen(lastvt[a]);e++)
                    {
                        if(wenfa[a][b-2]==lastvt[a][e])
                        {
                            flag=false;
                            break;
                        }
                    }
                    if(flag==true)
                    {
                        int length=strlen(lastvt[a]);
                        lastvt[a][length]=VT[c];
                    }
                }
            }
            if(sign==false)
            {
                break;
            }
            b++;//這里設(shè)置一個b++是因為wenfa[a][b]=='|',這樣的話前面的while循環(huán)無法進行前進下標掃描,所以在這先把下標跳一個。
        }
    }
    //下面的代碼和getfirstvt的后半段代碼一模一樣,只是把所有的firstvt改成lastvt就行了。
    int *origin=new int[n];//用于記錄遍歷之前的數(shù)組長度,看是否有變化。
    while(1)
    {
        int sign=true;//用于標識遍歷前后lastvt是否有變化。mark,symbol。
        for(int i=0;i<n;i++)
        {
            if(origin[i]!=strlen(lastvt[i]))
            {
                sign=false;//長度有變化
                origin[i]=strlen(lastvt[i]);
            }
        }
        if(sign==true)
        {
            break;
        }
        for(int i=0;i<n;i++)
        {
            for(int j=3;;)
            {
                for(int k=0;k<n;k++)
                {
                    if(k==i)
                    {
                        continue;
                    }
                    else if(wenfa[i][j]==wenfa[k][0])
                    {
                        for(int l=0;l<strlen(lastvt[k]);l++)
                        {
                            int flag=true;//用于標識一個終結(jié)符是否已經(jīng)在lastvt集中,true為不在其中的意思。
                            for(int m=0;m<strlen(lastvt[i]);m++)
                            {
                                if(lastvt[k][l]==lastvt[i][m])
                                {
                                    flag=false;
                                    break;
                                }
                            }
                            if(flag==false)
                            {
                                continue;
                            }
                            else
                            {
                                int length=strlen(lastvt[i]);
                                lastvt[i][length]=lastvt[k][l];
                            }
                        }
                    }
                }
                int flag=true;
                while(wenfa[i][j]!='|')
                {
                    if(wenfa[i][j]=='\0')
                    {
                        flag=false;
                        break;
                    }
                    j++;
                }
                if(flag==false)
                {
                    break;
                }
                j++;
            }
        }
    }
}
void gettable(int n)
{
    char data[N];//用于保存每個產(chǎn)生式
    for(int i=0;i<n;i++)//<
    {
        int dt=0;
        // int flag=true;
        for(int j=3;;)
        {
            if(wenfa[i][j]=='|'||wenfa[i][j]=='\0')
            {
                if(strlen(data)!=1)
                {
                    for(int k=0;k<strlen(data);k++)
                    {
                        if(data[k]<'A'||data[k]>'Z')
                        {
                            if(data[k+1]!='\0'&&data[k+1]>='A'&&data[k+1]<='Z')
                            {
                                int x;
                                int yk;
                                for(int l=0;l<strlen(VT);l++)
                                {
                                    if(data[k]==VT[l])
                                    {
                                        x=l;
                                        break;
                                    }
                                }
                                for(int l=0;l<strlen(VN);l++)
                                {
                                    if(data[k+1]==VN[l])
                                    {
                                        yk=l;
                                        break;
                                    }
                                }
                                for(int l=0;l<strlen(firstvt[yk]);l++)
                                {
                                    for(int m=0;m<strlen(VT);m++)
                                    {
                                        if(firstvt[yk][l]==VT[m])
                                        {
                                            if(table[x][m]=='\0')
                                            {
                                                table[x][m]='<';
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if(wenfa[i][j]=='\0')
                {
                    break;
                }
                j++;
                memset(data,'\0',sizeof(data));
                dt=0;
            }
            else
            {
                data[dt]=wenfa[i][j];
                j++;
                dt++;
            }
        }
    }
    for(int i=0;i<n;i++)//>,和上面的<差不多其實
    {
        int dt=0;
        // int flag=true;
        for(int j=3;;)
        {
            if(wenfa[i][j]=='|'||wenfa[i][j]=='\0')
            {
                if(strlen(data)!=1)
                {
                    for(int k=0;k<strlen(data);k++)
                    {
                        if(data[k]<'A'||data[k]>'Z')
                        {
                            if(k>=1&&data[k-1]>='A'&&data[k-1]<='Z')
                            {
                                int y;
                                int xk;
                                for(int l=0;l<strlen(VT);l++)
                                {
                                    if(data[k]==VT[l])
                                    {
                                        y=l;
                                        break;
                                    }
                                }
                                for(int l=0;l<strlen(VN);l++)
                                {
                                    if(data[k-1]==VN[l])
                                    {
                                        xk=l;
                                        break;
                                    }
                                }
                                for(int l=0;l<strlen(lastvt[xk]);l++)
                                {
                                    for(int m=0;m<strlen(VT);m++)
                                    {
                                        if(lastvt[xk][l]==VT[m])
                                        {
                                            if(table[m][y]=='\0')
                                            {
                                                table[m][y]='>';
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if(wenfa[i][j]=='\0')
                {
                    break;
                }
                j++;
                memset(data,'\0',sizeof(data));
                dt=0;
            }
            else
            {
                data[dt]=wenfa[i][j];
                j++;
                dt++;
            }
        }
    }
    for(int i=0;i<n;i++)//=
    {
        int dt=0;
        // int flag=true;
        for(int j=3;;)
        {
            if(wenfa[i][j]=='|'||wenfa[i][j]=='\0')
            {
                if(strlen(data)!=1)
                {
                    for(int k=0;k<strlen(data);k++)
                    {
                        if(data[k]<'A'||data[k]>'Z')
                        {
                            if(data[k+1]!='\0'&&(data[k+1]<'A'||data[k+1]>'Z'))
                            {
                                int x,y;
                                for(int l=0;l<strlen(VT);l++)
                                {
                                    if(data[k]==VT[l])
                                    {
                                        x=l;
                                    }
                                    if(data[k+1]==VT[l])
                                    {
                                        y=l;
                                    }
                                }
                                if(table[x][y]=='\0')
                                {
                                    table[x][y]='=';
                                }
                            }
                            if(data[k+2]!='\0'&&(data[k+2]<'A'||data[k+2]>'Z'))
                            {
                                int x,y;
                                for(int l=0;l<strlen(VT);l++)
                                {
                                    if(data[k]==VT[l])
                                    {
                                        x=l;
                                    }
                                    if(data[k+2]==VT[l])
                                    {
                                        y=l;
                                    }
                                }
                                if(table[x][y]=='\0')
                                {
                                    table[x][y]='=';
                                }
                            }
                        }
                    }
                }
                if(wenfa[i][j]=='\0')
                {
                    break;
                }
                j++;
                memset(data,'\0',sizeof(data));
                dt=0;
            }
            else
            {
                data[dt]=wenfa[i][j];
                j++;
                dt++;
            }
        }
    }
    int jinghao=strlen(VT);
    table[jinghao][jinghao]='=';
    for(int i=0;i<strlen(VT);i++)
    {
        for(int j=0;j<strlen(firstvt[0]);j++)
        {
            if(VT[i]==firstvt[0][j])
            {
                table[jinghao][i]='<';
                break;
            }
        }
    }
    for(int i=0;i<strlen(VT);i++)
    {
        for(int j=0;j<strlen(lastvt[0]);j++)
        {
            if(VT[i]==lastvt[0][j])
            {
                table[i][jinghao]='>';
                break;
            }
        }
    }
}
void fenxi(char *sentence)
{
    char in[N];
    in[0]='#';
    char out[N];
    for(int i=0;i<strlen(sentence);i++)
    {
        out[i]=sentence[i];
    }
    out[strlen(sentence)]='#';
    int step=0;
    int lin=1;
    int lout=strlen(sentence)+1;
    cout<<step<<'\t';
    for(int i=0;i<lin;i++)
    {
        cout<<in[i];
    }
    cout<<'\t';
    for(int i=0;i<lout;i++)
    {
        cout<<out[i];
    }
    cout<<'\t'<<"預(yù)備"<<endl;
    int flag=true;
    while(true)
    {
        int i=lin-1;
        while(in[i]=='N')
        {
            i--;
        }
        int j=0;
        int x,y;
        for(int k=0;k<strlen(VT);k++)
        {
            if(in[i]==VT[k])
            {
                x=k;
            }
            if(out[0]==VT[k])
            {
                y=k;
            }
        }
        if((in[i]>='a'&&in[i]<='z')||(in[i]>='0'&&in[i]<='9'))
        {
            for(int k=0;k<strlen(VT);k++)
            {
                if('i'==VT[k])
                {
                    x=k;
                }
            }
        }
        if((out[0]>='a'&&out[0]<='z')||(out[0]>='0'&&out[0]<='9'))
        {
            for(int k=0;k<strlen(VT);k++)
            {
                if('i'==VT[k])
                {
                    y=k;
                }
            }
        }
        if(in[i]=='#')
        {
            x=strlen(VT);
        }
        if(out[0]=='#')
        {
            y=strlen(VT);
        }
        if(x==y&&y==strlen(VT))
        {
            break;
        }
        if(table[x][y]=='<')
        {
            in[lin]=out[0];
            lin++;
            lout--;
            for(int l=0;l<lout;l++)
            {
                out[l]=out[l+1];
            }
            step++;
            cout<<step<<'\t';
            for(int l=0;l<lin;l++)
            {
                cout<<in[l];
            }
            cout<<'\t';
            for(int l=0;l<lout;l++)
            {
                cout<<out[l];
            }
            cout<<'\t'<<"移進"<<endl;
        }
        else if(table[x][y]=='=')
        {
            step++;
            cout<<step<<'\t';
            for(int l=0;l<lin;l++)
            {
                cout<<in[l];
            }
            cout<<out[0]<<'\t';
            for(int l=1;l<lout;l++)
            {
                cout<<out[l];
            }
            cout<<'\t'<<"移進"<<endl;
            in[i]='N';
            int lin1=lin;
            for(int k=i+1;k<lin1;k++)
            {
                in[k]='\0';
                lin--;
            }
            lout--;
            for(int k=0;k<lout;k++)
            {
                out[k]=out[k+1];
            }
            step++;
            cout<<step<<'\t';
            for(int l=0;l<lin;l++)
            {
                cout<<in[l];
            }
            cout<<'\t';
            if(out[0]=='#')
            {
                cout<<'#';
            }
            else
            {
                for(int l=1;l<lout;l++)
                {
                    cout<<out[l];
                }
            }
            cout<<'\t'<<"規(guī)約"<<endl;
        }
        else if(table[x][y]=='>')
        {
            while(true)
            {
                if(in[i-1]=='N')
                {
                    i--;
                }
                else
                {
                    break;
                }
            }
            in[i]='N';
            int lin1=lin;
            for(int k=i+1;k<lin1;k++)
            {
                in[k]='\0';
                lin--;
            }
            step++;
            cout<<step<<'\t';
            for(int k=0;k<lin;k++)
            {
                cout<<in[k];
            }
            cout<<'\t';
            if(out[0]=='#')
            {
                cout<<'#';
            }
            else
            {
                for(int k=0;k<lout;k++)
                {
                    cout<<out[k];
                }
            }
            cout<<'\t'<<"規(guī)約"<<endl;
        }
        else
        {
            flag=false;
            break;
        }
    }
    if(flag==true)
    {
        cout<<"恭喜你,你的句子沒有問題。"<<endl;
    }
    else if(flag==false)
    {
        cout<<"算符優(yōu)先分析表中沒有這倆非終結(jié)符的對應(yīng)關(guān)系,匹配失敗。"<<endl;
    }
}
int main()
{
    cout<<"請使用英文輸入法輸入文法,輸入#代表結(jié)束。另:此程序?qū)ξ姆ㄓ也繜o檢錯功能。"<<endl;
    int n;
    while(1)
    {
        int i=0;
        do
        {
            cin>>wenfa[i];
            i++;
        } while (wenfa[i-1][0]!='#');
        n=i-1;//文法數(shù)量
        // for(i=0;i<n;i++)
        // {
        //     cout<<wenfa[i]<<endl;
        // }
        if(vnvt(n)==false)
        {
            cout<<"您所輸入的文法左部可能有誤,請檢查后再重新輸入。"<<endl;
        }
        else
        {
            break;
        }
    }
    getfirstvt(n);
    getlastvt(n);
    gettable(n);
    cout<<"---------------------------------------------------"<<endl<<"非終結(jié)符有:VN={";
    for(int i=0;i<strlen(VN);i++)
    {
        cout<<VN[i];
        if(i!=strlen(VN)-1)
        {
            cout<<',';
        }
    }
    cout<<'}'<<endl<<"終結(jié)符有:VT={";
    for(int i=0;i<strlen(VT);i++)
    {
        cout<<VT[i];
        if(i!=strlen(VT)-1)
        {
            cout<<',';
        }
    }
    cout<<'}'<<endl<<"---------------------------------------------------"<<endl;
    for(int i=0;i<strlen(VN);i++)
    {
        cout<<"FIRSTVT("<<VN[i]<<")={";
        for(int j=0;j<strlen(firstvt[i]);j++)
        {
            cout<<firstvt[i][j];
            if(j!=strlen(firstvt[i])-1)
            {
                cout<<',';
            }
        }
        cout<<'}'<<endl;
    }
    cout<<endl;
    for(int i=0;i<strlen(VN);i++)
    {
        cout<<"LASTVT("<<VN[i]<<")={";
        for(int j=0;j<strlen(lastvt[i]);j++)
        {
            cout<<lastvt[i][j];
            if(j!=strlen(lastvt[i])-1)
            {
                cout<<',';
            }
        }
        cout<<'}'<<endl;
    }
    cout<<"---------------------------------------------------"<<endl<<"算符優(yōu)先分析表如下:"<<endl<<'\t';
    for(int i=0;i<strlen(VT);i++)
    {
        cout<<VT[i]<<'\t';
    }
    cout<<'#'<<endl;
    for(int i=0;i<strlen(VT)+1;i++)
    {
        if(i==strlen(VT))
        {
            cout<<'#'<<'\t';
        }
        else
        {
            cout<<VT[i]<<'\t';
        }
        
        for(int j=0;j<strlen(VT)+1;j++)
        {
            cout<<table[i][j]<<'\t';
        }
        cout<<endl;
    }
    char sentence[N];
    while(true)
    {
        cout<<"請輸入你要識別的句子,若輸入#則代表沒有需要識別的句子了:"<<endl;
        cin>>sentence;
        if(sentence[0]=='#')
        {
            break;
        }
        cout<<"步驟"<<'\t'<<"棧"<<'\t'<<"輸入串"<<'\t'<<"動作"<<endl;
        fenxi(sentence);
    }
    system("pause");
    return 0;
}

運行結(jié)果如下:

編譯原理:算符優(yōu)先分析算法的設(shè)計與實現(xiàn)(含代碼)

輸入幾個例子的結(jié)果如下:

說明一下,我的代碼把所有數(shù)字和小寫字母都看作了i。

eg1:1+2
編譯原理:算符優(yōu)先分析算法的設(shè)計與實現(xiàn)(含代碼)

eg2:(1+2)/3+4-(5+6/7) (其實就是我舉的例子,我為了簡單全部換成了i)

編譯原理:算符優(yōu)先分析算法的設(shè)計與實現(xiàn)(含代碼)

eg3:((1-2)/3+4 (錯誤的例子)

編譯原理:算符優(yōu)先分析算法的設(shè)計與實現(xiàn)(含代碼)

最后只要輸入#結(jié)束運行就行了。

好了,拜拜,祝大家生活愉快。

有什么錯誤的地方歡迎評論區(qū)指正。文章來源地址http://www.zghlxwxcb.cn/news/detail-495986.html

到了這里,關(guān)于編譯原理:算符優(yōu)先分析算法的設(shè)計與實現(xiàn)(含代碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【編譯原理實驗】 -- 詞法分析程序設(shè)計原理與實現(xiàn)(C語言實現(xiàn))

    【編譯原理實驗】 -- 詞法分析程序設(shè)計原理與實現(xiàn)(C語言實現(xiàn))

    目錄 目標任務(wù) 設(shè)計要求 一、程序功能描述 二、正則文法 三、程序結(jié)構(gòu)描述 四、代碼 ?五、程序測試 ?測試用例1 測試結(jié)果1 測試用例2 測試結(jié)果2 以下為正則文法所描述的 C 語言子集單詞符號的示例,請補充單詞符號:++,--, , , += , -= ,*=, /= ,(邏輯與),||(邏輯或),

    2024年02月02日
    瀏覽(579)
  • 編譯原理——語法分析器(C/C++代碼實現(xiàn))

    編譯原理——語法分析器(C/C++代碼實現(xiàn))

    編寫一個簡單的LL(1)語法分析器。(注意:此實驗是簡化版的LL(1)文法,已給出預(yù)測分析表,不需要求FIRST和FOLLOW集,直接根據(jù)預(yù)測分析表編寫程序即可) 根據(jù)編譯原理理論課中學(xué)習(xí)的算術(shù)表達式文法,以及該文法LL(1)分析表,用C語言編寫接受算術(shù)表達式為輸入的語法

    2023年04月26日
    瀏覽(65)
  • 編譯原理——SLR(1)語法分析器(C/C++代碼實現(xiàn))

    編譯原理——SLR(1)語法分析器(C/C++代碼實現(xiàn))

    設(shè)計、編制、實現(xiàn)并調(diào)試SLR(1)語法分析器,加深對語法分析的理解。 根據(jù)編譯原理理論課中學(xué)習(xí)的算術(shù)表達式文法以及該文法的LR分析表,用C語言編寫接受算術(shù)表達式為輸入的語法分析器,以控制臺(或文本文件,也可以結(jié)合詞法分析器完成)為輸入,控制臺(或文件)

    2024年02月11日
    瀏覽(24)
  • 【Python搜索算法】深度優(yōu)先搜索(DFS)算法原理詳解與應(yīng)用,示例+代碼

    【Python搜索算法】深度優(yōu)先搜索(DFS)算法原理詳解與應(yīng)用,示例+代碼

    目錄 1 基本原理 2 DFS算法流程 3 時間復(fù)雜度 4 空間復(fù)雜度 5 DFS算法應(yīng)用案例: 5.1 解決路徑查找問題? 5.2 解決圖的連通性問題 5.3? 拓撲排序 5.4? 在樹結(jié)構(gòu)中進行深度遍歷 深度優(yōu)先搜索(DFS)是一種重要的圖遍歷算法,用于探索圖中的節(jié)點和邊。 DFS 是一種遞歸或棧(堆棧)

    2024年02月06日
    瀏覽(45)
  • 【Python搜索算法】廣度優(yōu)先搜索(BFS)算法原理詳解與應(yīng)用,示例+代碼

    【Python搜索算法】廣度優(yōu)先搜索(BFS)算法原理詳解與應(yīng)用,示例+代碼

    目錄 1 廣度優(yōu)先搜索???? 2 應(yīng)用示例 2.1 迷宮路徑搜索 2.2 社交網(wǎng)絡(luò)中的關(guān)系度排序 2.3 查找連通區(qū)域 ????????廣度優(yōu)先搜索(Breadth-First Search,BFS)是一種圖遍歷算法,用于系統(tǒng)地遍歷或搜索圖(或樹)中的所有節(jié)點。BFS的核心思想是從起始節(jié)點開始,首先訪問其所有相

    2024年02月08日
    瀏覽(23)
  • 【編譯原理】詞法分析程序設(shè)計(C語言)

    【編譯原理】詞法分析程序設(shè)計(C語言)

    ??給定下表所示的一個簡單語言的詞法規(guī)則描述完成以下任務(wù): (1)畫出識別該語言詞法規(guī)則的 狀態(tài)轉(zhuǎn)換圖 ; (2)依據(jù)狀態(tài)轉(zhuǎn)換圖,設(shè)計并編制詞法分析程序,實現(xiàn)從輸入源程序中,識別出各類單詞,即 、標識符、常數(shù)、運算符、界符 五大類,并輸出各個單詞

    2024年02月15日
    瀏覽(99)
  • 編譯原理實驗三:預(yù)測分析法語法分析器的設(shè)計

    編譯原理實驗三:預(yù)測分析法語法分析器的設(shè)計

    ? 根據(jù)文法編制預(yù)測分析法語法分析程序,以便對輸入的符號串進行語法分析。通過編寫預(yù)測分析法語法分析程序掌握預(yù)測分析法的基本原理、FIRST和FOLLOW集的計算、預(yù)測分析表的構(gòu)造方法以及語法分析法主控程序的設(shè)計。 對于給定的上下文無關(guān)文法,編程完成以下功能:

    2024年02月05日
    瀏覽(92)
  • 編譯原理之LL(1)語法分析實驗(附完整C/C++代碼與測試)

    編譯原理之LL(1)語法分析實驗(附完整C/C++代碼與測試)

    先從鍵盤讀入要分析的文法,由程序自動構(gòu)造FIRST、FOLLOW 集以及SELECT集合,判斷是否為LL (1)文法。 分析文法為G[E]: (0)E→ TE’ ? (1)E’→ +TE’ (2)E’→ε??? (3)T→ FT’ (4)T’→ *FT’ ? (5)T’→ε???? (6)F→ (E)?? ?(7)F→a 若符合LL (1)文法,由程序自動構(gòu)

    2024年02月04日
    瀏覽(28)
  • 編譯原理(前端)的算法和實現(xiàn)

    編譯原理(前端)的算法和實現(xiàn)

    本文介紹從零實現(xiàn)Lex+YACC(即一鍵生成編譯器(前端))的算法。完整代碼在(https://gitee.com/bitzhuwei/grammar-mentor)和(https://github.com/bitzhuwei/GrammarMentor)。 下文將用“解析器”指代編譯器前端(即詞法分析和語法分析)。 本文主要以四則運算為例,其文法如下: 本文按如下

    2024年02月04日
    瀏覽(11)
  • 【編譯原理】 實驗一:詞法分析器的自動實現(xiàn)(Lex詞法分析)

    【編譯原理】 實驗一:詞法分析器的自動實現(xiàn)(Lex詞法分析)

    相關(guān)代碼實操移步視頻 https://www.bilibili.com/video/BV13x4y1o7FL 1.借助詞法分析工具Flex或Lex完成(參考網(wǎng)絡(luò)資源) 2.輸入:高級語言源代碼(如helloworld.c) 3.輸出:以二元組表示的單詞符號序列。 通過設(shè)計、編制、調(diào)試一個具體的詞法分析程序,加深對詞法分析原理的理解,并掌握

    2024年02月08日
    瀏覽(95)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包