最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Python編寫個(gè)語(yǔ)法解析器

 更新時(shí)間:2023年07月30日 10:20:48   作者:Huterox  
這篇文章主要為大家詳細(xì)介紹了如何基于Python編寫個(gè)語(yǔ)法解析器,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下

前言

目的純粹,基于Python做一個(gè)簡(jiǎn)單的新的簡(jiǎn)單的編程語(yǔ)言。一方面是開(kāi)拓視野,另一方面是作為畢設(shè)的臨時(shí)過(guò)渡方案(沒(méi)錯(cuò),先前提到的算法平臺(tái),沒(méi)有把握快速開(kāi)發(fā)完畢,即便我使用大量的腳手架完成開(kāi)發(fā),但是算法容器,rpc算法調(diào)度中間件都需要自己造輪子,難度較大,此外還有用戶部分的UI設(shè)計(jì)等等,最重要的是,那幫老師根本無(wú)法理解這種項(xiàng)目。沒(méi)有必要搞太“花里胡哨”但是盡管如此,這個(gè)項(xiàng)目我后期還是要開(kāi)發(fā)的,主要原因在于算法容器和rpc算法調(diào)度中間件,這個(gè)對(duì)我來(lái)說(shuō)是非常值得去做的。里面涉及到的思想是非常受用的。雖然我現(xiàn)在在腦子里面構(gòu)思好了,要怎么做,但是這個(gè)編碼量實(shí)在太大。并且目標(biāo)院校改考11408,現(xiàn)在導(dǎo)致我很被動(dòng),因此,我決定寫一個(gè)sample computer language。同時(shí)為了加快開(kāi)發(fā)進(jìn)度,直接使用Python進(jìn)行編寫,后期轉(zhuǎn)到Pypy,然后編譯出這個(gè)語(yǔ)言的編譯器。

那么目標(biāo)的話,就是做到簡(jiǎn)單,直接做中文的,給小孩子鍛煉思維的。當(dāng)然,這也是為了方便給我講故事。能在那幫尸位素餐的老師面前多說(shuō)點(diǎn)他們能夠理解的東西。沒(méi)辦法一個(gè)普通院校,很多老師水平也就那樣,很無(wú)奈,但是沒(méi)有辦法改變。

選型

針對(duì)人群

有樣沒(méi)樣,樣子要像,那么這個(gè)編程語(yǔ)言的主要目的話,就是易學(xué)易用。推出中文編程,兼容Python,方便培養(yǎng)小學(xué)生鍛煉編程思維,適合一到兩年級(jí)的小學(xué)生進(jìn)行學(xué)習(xí)。不同于圖形化編程,Hlang可以體驗(yàn)到更加真實(shí)的編程環(huán)境,并且不會(huì)增加難度。既可以培養(yǎng)孩子的邏輯思維,同時(shí)還可以。。。 算了,編不下去了,就是個(gè)dome,同時(shí)用來(lái)應(yīng)付應(yīng)付畢設(shè)。

目標(biāo)

沒(méi)有目標(biāo),就是混~~ 本文目標(biāo),實(shí)現(xiàn)一個(gè)簡(jiǎn)單的語(yǔ)法解析器。反正隨便寫個(gè)幾千行代碼就能交個(gè)差,一幫混子!

技術(shù)實(shí)現(xiàn)

基于Python,體現(xiàn)體現(xiàn)思想,不追求運(yùn)行效率,重在好學(xué),給小孩子玩玩兒。不是總有某些家長(zhǎng)說(shuō)啥,英語(yǔ)難計(jì)算機(jī)簡(jiǎn)單的嘛?來(lái),那就用用這個(gè)~~

本文目標(biāo)

寫一個(gè)簡(jiǎn)單的語(yǔ)法解析器,然后下班~ 高數(shù)玩膩了,就玩這個(gè),這個(gè)玩膩了就學(xué)英語(yǔ)。

效果

ok,我們先來(lái)看到我們的實(shí)現(xiàn)效果:

這個(gè)就是一個(gè)簡(jiǎn)易的語(yǔ)法解析器。

實(shí)現(xiàn)

扯遠(yuǎn)了,我們來(lái)看看是如何進(jìn)行實(shí)現(xiàn)的。

首先是定義好我們的標(biāo)準(zhǔn)合法字符:

TT_INT = "整數(shù)"
TT_FLOAT = "浮點(diǎn)數(shù)"
TT_PLUS = "加號(hào)"
TT_DIV = "除號(hào)"
TT_MINUS = "減號(hào)"
TT_LPAREN = "左括號(hào)"
TT_RPAREN = "右括號(hào)"
TT_MUL = "乘"
TT_POWER = "次冪"
DIGITS = "123456789"

然后我們定義一個(gè)Token把這些對(duì)象封裝起來(lái)

class Token:
    def __init__(self,is_type,is_value=None):
        self.is_type = is_type
        self.is_value = is_value
    def __repr__(self):
        if self.is_value:
            return "|類型:{},值:{}|".format(self.is_type,self.is_value)
        return "|類型:{}|".format(self.is_type)
    def __str__(self):
        if(self.is_value):
            return "|{}|".format(self.is_value)
        return "|這個(gè)對(duì)象沒(méi)有值,類型為:{}|".format(self.is_type)

在這里我們要做的目的很簡(jiǎn)單,那就是,把接下來(lái)輸入的內(nèi)容,或者文本內(nèi)容,進(jìn)行讀取,然后解析出東西,把合法的字符收集起來(lái)。注意,我們這里還沒(méi)有什么變量的概念,在這里只是負(fù)責(zé)解析好基本的合法字符。至于變量的引入要到后面,因?yàn)檫@個(gè)時(shí)候要設(shè)計(jì)清楚基本的語(yǔ)法規(guī)范,然后就是照著一頓借鑒就完了。

字符指針

之后的話,我們定義好了Token,那么就要去讀取解析文本,這個(gè)沒(méi)有辦法,我們只能一個(gè)字符一個(gè)字符進(jìn)行掃描。為了方便,因此,這里對(duì)字符指針進(jìn)行一個(gè)簡(jiǎn)單封裝。

class Position:
    def __init__(self, idx, ln, col):
        self.idx = idx
        self.ln = ln
        self.col = col
    def advance(self, cur_char):
        self.idx += 1
        self.col += 1
        if cur_char == '\n':
            self.ln += 1
            self.col = 0
        return self

錯(cuò)誤類型

之后的話,我們還要去定義錯(cuò)誤。比如,當(dāng)我輸入一個(gè)非法字符之后要報(bào)個(gè)錯(cuò),就像Python一樣:

所以我們也要來(lái)個(gè)這個(gè)東西:

"""
頂級(jí)錯(cuò)誤(老大)
"""
class HlangError:
    def __init__(self, pos_ln,in_fn,error_name, details):
        """
        :param pos_ln: 錯(cuò)誤行
        :param in_fn: 輸入文件
        :param error_name: 錯(cuò)誤名稱
        :param details: 錯(cuò)誤細(xì)節(jié),說(shuō)明
        """
        self.pos_ln = pos_ln
        self.in_fn = in_fn
        self.error_name = error_name
        self.details = details
    def as_string(self):
        red_code = "\033[91m"
        reset_code = "\033[0m"
        result = f'{self.error_name}: {self.details}\n'
        result += f'來(lái)自 {self.in_fn}, line {self.pos_ln + 1}'
        return red_code+result+reset_code
class IllegalCharError(HlangError):
    """
    非法字符錯(cuò)誤
    """
    def __init__(self, pos_ln,in_fn, details):
        super().__init__(pos_ln, in_fn, '非法字符', details)

語(yǔ)法解析

那么之后的話,就可以開(kāi)始我們的語(yǔ)法解析了

這個(gè)代碼的話,很簡(jiǎn)單,就是往死里加入就好了

"""
語(yǔ)法解析器
"""
class Lexer:
    def __init__(self, in_fn, text):
        """
        :param in_fn: 從哪里輸入的文本(文本所在文件,標(biāo)準(zhǔn)輸入,輸出也是一個(gè)文件)
        其實(shí)就是文件名~~~
        :param text: 待解析文本
        """
        self.in_fn = in_fn
        self.text = text
        self.pos = Position(-1, 0, -1)
        self.cur_char = None
        self.advance()
        #基本的符號(hào)處理
        self.char_pro_base = {
            '+':TT_PLUS,
            '-':TT_MINUS,
            '*':TT_MUL,
            '/':TT_DIV,
            '^':TT_POWER,
            '(':TT_LPAREN,
            ')':TT_RPAREN
        }
    def advance(self):
        self.pos.advance(self.cur_char)
        self.cur_char = self.text[self.pos.idx] if self.pos.idx < len(self.text) else None
    def __char_process(self,tokens,TT):
        """
        處理基本字符的方法,
        添加Token,并且移動(dòng)字符指針
        :return:
        """
        tokens.append(Token(TT))
        self.advance()
    def make_tokens(self):
        """
        將文本當(dāng)中的字符添加到語(yǔ)法解析器當(dāng)中,將符合語(yǔ)法規(guī)范的內(nèi)容,封裝為Token,
        (就像Spring將對(duì)象信息再封裝為Wapper一樣,方便后續(xù)進(jìn)行操作。)
        :return:
        """
        tokens = []
        while self.cur_char != None:
            if self.cur_char in ' \t':
                #制表符(空格),沒(méi)有意義,往前移動(dòng)
                self.advance()
            elif self.cur_char in DIGITS:
                #如果是數(shù)字,自動(dòng)往前搜索,并且將數(shù)字進(jìn)行添加,并且判斷類型,
                #數(shù)字比較特殊,不是一個(gè)字符一個(gè)字符參與的(后面還要定義關(guān)鍵字也是類似的)
                tokens.append(self.make_number())
            else:
                TT = self.char_pro_base.get(self.cur_char)
                if(TT):
                    self.__char_process(tokens,TT)
                else:
                    char = self.cur_char
                    self.advance()
                    return [], IllegalCharError(self.pos.ln,self.in_fn, "'" + char + "'")
        return tokens, None
    def make_number(self):
        num_str = ''
        dot_count = 0
        while self.cur_char != None and self.cur_char in DIGITS + '.':
            if self.cur_char == '.':
                if dot_count == 1: break
                dot_count += 1
                num_str += '.'
            else:
                num_str += self.cur_char
            self.advance()
        if dot_count == 0:
            return Token(TT_INT, int(num_str))
        else:
            return Token(TT_FLOAT, float(num_str))

之后的話,別忘了還需要要一個(gè)run作為入口,run起來(lái):

"""
語(yǔ)言解析,運(yùn)行入口
"""
def run(fn, text):
    lexer = Lexer(fn, text)
    tokens, error = lexer.make_tokens()
    return tokens, error

交互

最后的最后,就是我們的交互了:

"""
Hlang is a Sample Language shell
Just a sample example for learning by Huterox
"""
import basic
while True:
    input_text = input("交互終端:")
    result, error = basic.run('<標(biāo)準(zhǔn)輸入>', input_text)
    if error: print(error.as_string())
    else: print(result)

然后搞定,so 簡(jiǎn)單

以上就是基于Python編寫個(gè)語(yǔ)法解析器的詳細(xì)內(nèi)容,更多關(guān)于Python語(yǔ)法解析器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python代碼注釋規(guī)范代碼實(shí)例解析

    Python代碼注釋規(guī)范代碼實(shí)例解析

    這篇文章主要介紹了Python代碼注釋規(guī)范代碼實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 使用Python實(shí)現(xiàn)文本英文統(tǒng)計(jì)功能

    使用Python實(shí)現(xiàn)文本英文統(tǒng)計(jì)功能

    這篇文章主要為大家詳細(xì)介紹了如何使用Python來(lái)實(shí)現(xiàn)文本英文統(tǒng)計(jì),包括單詞頻率統(tǒng)計(jì)、詞匯量統(tǒng)計(jì)以及文本情感分析等,感興趣的小伙伴可以參考下
    2024-05-05
  • python3中No module named _ssl的問(wèn)題解決

    python3中No module named _ssl的問(wèn)題解決

    本文主要介紹了python3中No module named _ssl的問(wèn)題解決,這個(gè)錯(cuò)誤表示Python導(dǎo)入_ssl模塊時(shí)失敗,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • 詳解Django通用視圖中的函數(shù)包裝

    詳解Django通用視圖中的函數(shù)包裝

    這篇文章主要介紹了詳解Django通用視圖中的函數(shù)包裝,Django是最具人氣的Python web開(kāi)發(fā)框架,需要的朋友可以參考下
    2015-07-07
  • Python OpenCV直方圖均衡化詳解

    Python OpenCV直方圖均衡化詳解

    本文中將介紹如何使用OpenCV函數(shù)執(zhí)行直方圖均衡,并將其應(yīng)用于灰度和彩色圖像,以及將亮度歸一化并提高圖像的對(duì)比度。感興趣的小伙伴可以了解一下
    2022-02-02
  • 淺析Python數(shù)字類型和字符串類型的內(nèi)置方法

    淺析Python數(shù)字類型和字符串類型的內(nèi)置方法

    這篇文章主要介紹了Python數(shù)字類型和字符串類型的內(nèi)置方法,本文通過(guò)實(shí)例代碼講解的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Python descriptor(描述符)的實(shí)現(xiàn)

    Python descriptor(描述符)的實(shí)現(xiàn)

    這篇文章主要介紹了Python descriptor(描述符)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • python實(shí)現(xiàn)楊輝三角的3種方法(迭代、生成器和遞歸)

    python實(shí)現(xiàn)楊輝三角的3種方法(迭代、生成器和遞歸)

    這篇文章主要給大家介紹了關(guān)于python實(shí)現(xiàn)楊輝三角的3種方法,分別是迭代、生成器和遞歸的相關(guān)資料,楊輝三角形的規(guī)則就是每行的第一個(gè)數(shù)字和最后一個(gè)數(shù)字為1之外,其余每個(gè)數(shù)字等于上一行對(duì)應(yīng)兩個(gè)數(shù)字的和,需要的朋友可以參考下
    2023-11-11
  • python機(jī)器學(xué)習(xí)Logistic回歸原理推導(dǎo)

    python機(jī)器學(xué)習(xí)Logistic回歸原理推導(dǎo)

    這篇文章主要為大家介紹了python機(jī)器學(xué)習(xí)Logistic回歸原理推導(dǎo),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 使用Python實(shí)現(xiàn)在PDF中添加空白頁(yè)面的方法

    使用Python實(shí)現(xiàn)在PDF中添加空白頁(yè)面的方法

    在日常辦公和數(shù)據(jù)處理中,PDF文件因其格式穩(wěn)定性被廣泛使用,本文將介紹Python如何使用Spire.PDF for Python實(shí)現(xiàn)為PDF添加空白頁(yè)面,感興趣的小伙伴可以了解下
    2025-11-11

最新評(píng)論

无极县| 军事| 麟游县| 江北区| 建水县| 浙江省| 巍山| 军事| 山阳县| 清新县| 灵台县| 莲花县| 蓬溪县| 岐山县| 瑞昌市| 图们市| 阳原县| 遂川县| 新营市| 荔波县| 额济纳旗| 和田市| 垦利县| 翁源县| 开阳县| 额济纳旗| 诸城市| 溧阳市| 新源县| 天气| 左云县| 宝坻区| 舒城县| 茌平县| 潢川县| 新郑市| 和田县| 梁河县| 乌海市| 江华| 太康县|