一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

手寫詞法分析器

冬至子 ? 來源:趙同學(xué)的代碼時間 ? 作者:Jun. ? 2023-05-23 11:20 ? 次閱讀

在開始手寫詞法分析器之前呢,我們得先準(zhǔn)備好一些零件,規(guī)劃好將要使用哪些函數(shù),如果函數(shù)沒有現(xiàn)成的,那還得自己寫。

輸入

由于我們需要從流中讀出,有時還需要放回流,詞法分析器顯然每次讀入都是按字符讀入,所以使用getchar函數(shù)一般沒有問題,然后對于放回流,C中提供了一個ungetc的后悔函數(shù),首先先來嘗試一下這個函數(shù):

int main()
{
    char t;
    t = getchar();
    cout << t;
    ungetc(t, stdin);
    t = 'a';
    t = getchar();
    cout << t;
    // input : 12, output : 11
}

其實(shí)也就是把這個字符放回到標(biāo)準(zhǔn)輸入流的最前面。

判斷

我們需要判斷一個字符它是字符還是數(shù)字,參考實(shí)驗(yàn)指導(dǎo)中的代碼,有一個頭文件ctype.h可以幫上忙 。

isalnum() 判斷一個字符是否是字母或數(shù)字

isalpha() 判斷一個字符是否是字母

isdigit() 判斷一個字符是否是十進(jìn)制數(shù)字

islower() 判斷一個字符是否是小寫字母

isspace() 判斷一個字符是否是空白符(包含\\n等空白效果的控制字符)

返回值:如果滿足,返回非0,不滿足,返回0;

子問題1:識別關(guān)鍵字、標(biāo)識符、數(shù)據(jù)類型

圖片

這一步要完成上面這一個分支,計(jì)劃使用Trie樹保存關(guān)鍵字,然后按照以下步驟進(jìn)行,完成一個函數(shù)就可以:

圖片

建樹過程:

// 預(yù)設(shè)的keywords和basic
string keyword[] = {"if", "while", "do", "break", "float", "true", "false"};
string basic[] = {"int", "char", "bool", "float"};
// 宏定義,使代碼更可讀
#define KEYWORD 1
#define BASIC 2
#define IDENTITY 3
// 定義全局變量
const int N = 128;
int son[N][N], idx;
int token[N * N]; // 定義這個idx對應(yīng)的token
// insert函數(shù),詳見Trie樹
void insert(string s, int mode)
{
    int p = 0; // 從根節(jié)點(diǎn)開始
    for(int i = 0; i < s.size(); i ++)
    {
        if(!son[p][s[i]]) son[p][s[i]] = ++ idx;
        p = son[p][s[i]];
    }
    token[idx] = mode;
}
// 查詢函數(shù),返回token類型
int query(string s)
{
    int p = 0;
    for(int i = 0; i < s.size(); i ++)
    {
        if(!son[p][s[i]]) return IDENTITY;
        p = son[p][s[i]];
    }
    return token[p];
}
// 初始化函數(shù)
void initialize()
{
    for(int i = 0; i < 7; i ++) insert(keyword[i], KEYWORD);
    for(int i = 0; i < 4; i ++) insert(basic[i], BASIC);
}

查詢測試:

圖片

已經(jīng)成功的可以使用了。

我們可以發(fā)現(xiàn),不光是keyword和basic和identity,其他的字符也可以存到Trie樹里面去,比如以下專用符號:

= + - * / < <= > >= == != ; , ( ) [ ] { }

甚至是注釋符號:

/* */

子問題2:識別數(shù)字

首先,為了識別數(shù)字,我們先給出數(shù)字的正則表達(dá)式:

圖片

嘗試給出NFA

圖片

轉(zhuǎn)化為DFA

圖片

分析狀態(tài)轉(zhuǎn)移表:

1.jpg

上標(biāo)轉(zhuǎn)化為代碼表示:

int st[11][5] = {{0, 0, 0, 0, 0},
                 {2, 3, 4, 0, 0},
                 {0, 0, 4, 0, 0},
                 {0, 0, 4, 0, 0},
                 {0, 0, 4, 5, 7},
                 {0, 0, 6, 0, 0},
                 {0, 0, 6, 0, 7},
                 {8, 9, 10, 0, 0},
                 {0, 0, 10, 0, 0},
                 {0, 0, 10, 0, 0},
                 {0, 0, 10, 0, 0}};

根據(jù)狀態(tài)轉(zhuǎn)移表完成編程

string num() // 輸入一個數(shù)字字符串
{
    string s;
    char t;

    int status = 1;
    int last_status;
    while(1){
        t = getchar();
        switch (t)
        {
        case '+':
            last_status = status;
            status = st[status][0];
            break;
        case '-':
            last_status = status;
            status = st[status][1];
            break;
        case '.':
            last_status = status;
            status = st[status][3];
            break;
        case 'E':
            last_status = status;
            status = st[status][4];
            break;
        case 'e':
            last_status = status;
            status = st[status][4];
            break;

        default:
            if(isdigit(t))
            {
                last_status = status;
                status = st[status][2];
            }
            else {
                last_status = status;
                status = 0;
            }
            break;
        }
        if(!status)
        {
            ungetc(t, stdin);
            break;
        }
        s += t;
    }
    status = last_status;
    if(status != 4 && status != 6 && status != 10) return "";
    return s;
}

結(jié)果測試:

圖片

于是乎我們又實(shí)現(xiàn)了一個有限狀態(tài)自動機(jī),從而實(shí)現(xiàn)了數(shù)字字符串的輸入。

子問題3:將輸入分割為小字符串

要實(shí)現(xiàn)將輸入分割為小字符串,且向前看的步長僅為1步。首先我們需要分析出究竟在什么時候,才應(yīng)該將他們分開。

1) 以下劃線、字母開頭,使用Trie樹搜索;

2) 以+ -開頭,再看一步為數(shù)字,放回加減后使用DFA搜索;

3) 除+ -專用符號開頭,使用Trie樹搜索;

4) 注釋符號開頭,一直接收到遇到注釋尾。

子問題4:處理注釋

此處做一個簡化,不考慮注釋中的轉(zhuǎn)義字符,匹配到 */ 則結(jié)束。

string comments()
{
    string s;
    char last_c, c;

    while(last_c != '*' || c != '/')
    {
        last_c = c;
        c = getchar();
        s += c;
    }


    return s;
}

驗(yàn)證:

圖片

可以看到,它自動截取了注釋的前面部分。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 分析器
    +關(guān)注

    關(guān)注

    0

    文章

    93

    瀏覽量

    12646
  • 狀態(tài)機(jī)
    +關(guān)注

    關(guān)注

    2

    文章

    493

    瀏覽量

    27979
  • NFA
    NFA
    +關(guān)注

    關(guān)注

    0

    文章

    4

    瀏覽量

    7190
收藏 人收藏

    評論

    相關(guān)推薦

    偏振分析器

    摘要 線柵偏振,可以使透射光產(chǎn)生線性偏振狀態(tài),是眾多應(yīng)用中常見的一種光學(xué)元件。由于它們的結(jié)構(gòu)在亞波長范圍內(nèi),因此必須對光的傳播進(jìn)行嚴(yán)格的處理。VirtualLab的偏振分析器及其內(nèi)置的RCWA
    發(fā)表于 01-13 08:59

    #硬聲創(chuàng)作季 4.2.1 詞法分析器的結(jié)構(gòu)

    編譯原理詞法分析
    Mr_haohao
    發(fā)布于 :2022年09月01日 06:50:51

    關(guān)于antlr詞法分析器的使用

    剛剛接觸antlr詞法分析器只略看了些基本理論知識,關(guān)于做實(shí)例就完全不懂了,我想知道他需要什么樣的環(huán)境和軟件,以及軟件的下載地址.多謝各位了
    發(fā)表于 11-12 16:29

    Hanlp分詞之CRF中文詞法分析詳解

    這是另一套基于CRF的詞法分析系統(tǒng),類似感知機(jī)詞法分析器,提供了完善的訓(xùn)練與分析接口。CRF的效果比感知機(jī)稍好一些,然而訓(xùn)練速度較慢,也不支
    發(fā)表于 02-18 15:28

    postgreSQL命令的詞法分析和語法分析

    PostgreSQL查詢SQL的語法分析(1)——詞法分析
    發(fā)表于 05-16 16:33

    手寫SQL編譯詞法分析

    精讀《手寫 SQL 編譯 - 詞法分析
    發(fā)表于 05-26 16:27

    一種實(shí)用的脈沖幅度分析器

    摘要:通過對高精度脈沖幅度分析器的電路分析,得出了在使用過程中,采用高精度和低溫系數(shù)的電壓基準(zhǔn)集成塊,可保證該脈沖幅度分析器比傳統(tǒng)脈沖幅度分析器靈敏度高、穩(wěn)定
    發(fā)表于 05-25 08:39 ?29次下載

    C語言詞法分析器的代碼

    C語言詞法分析器的代碼#include #include #include #include <
    發(fā)表于 10-10 15:32 ?85次下載

    遙控分析器

    遙控分析器
    發(fā)表于 09-18 14:14 ?658次閱讀
    遙控<b class='flag-5'>分析器</b>

    諧波失真分析器

    諧波失真分析器 電路包括一個1KHZ的低失真
    發(fā)表于 09-23 14:34 ?857次閱讀
    諧波失真<b class='flag-5'>分析器</b>

    網(wǎng)絡(luò)分析器,網(wǎng)絡(luò)分析器原理是什么?

    網(wǎng)絡(luò)分析器,網(wǎng)絡(luò)分析器原理是什么? 網(wǎng)絡(luò)分析器   具有發(fā)現(xiàn)并解決各種故障特性的硬件或軟件設(shè)備
    發(fā)表于 03-22 11:25 ?1100次閱讀

    協(xié)議分析器在WLAN中的應(yīng)用

    協(xié)議分析器在WLAN中的應(yīng)用 協(xié)議分析器廣泛應(yīng)用于有線網(wǎng)絡(luò),成為一類極有用的測試和維護(hù)工具。然而,在WLAN領(lǐng)域,這個問題很有可
    發(fā)表于 03-29 17:11 ?550次閱讀

    靜態(tài)代碼分析器

    Fortify的靜態(tài)代碼分析器(Static Code Analyzer,SCA)是組成Fortify 360的三個分析器之一。SCA工作在開發(fā)階段,以用于分析應(yīng)用程序的源代碼是否存在安全漏洞。這種類型的
    發(fā)表于 04-07 20:32 ?22次下載

    Python-寫個可轉(zhuǎn)債分析器

    用Python寫個可轉(zhuǎn)債分析器
    的頭像 發(fā)表于 02-16 15:13 ?1517次閱讀
    Python-寫個可轉(zhuǎn)債<b class='flag-5'>分析器</b>

    自頂向下的語法分析器—采用遞歸下降方法

    在之前已經(jīng)通過手寫的方式實(shí)現(xiàn)了一個詞法分析器,現(xiàn)在,我將利用之前手寫詞法分析器,使用遞歸下降的
    的頭像 發(fā)表于 05-23 11:24 ?2268次閱讀
    自頂向下的語法<b class='flag-5'>分析器</b>—采用遞歸下降方法