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

使用Python編寫(xiě)一個(gè)Lisp語(yǔ)言的解釋器

 更新時(shí)間:2023年11月22日 10:00:57   作者:skywalk8163  
這篇文章主要為大家詳細(xì)介紹了如何使用Python編寫(xiě)一個(gè)簡(jiǎn)單的Lisp語(yǔ)言的解釋器,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

一般的源代碼程序經(jīng)過(guò)編譯器解析生成解析樹(shù)。Lisp的奇特之處就在于,你可以完全卸除程序,控制這種解析樹(shù),進(jìn)行任意的存取操作,也就是可以用程序生成程序。

Python號(hào)稱最接近Lisp的語(yǔ)言,但它終究不是。但是因?yàn)閹缀跛姓Z(yǔ)言都是圖靈完備的,所以即使Python無(wú)法實(shí)現(xiàn)Lisp的某個(gè)功能,也可以通過(guò)在Python中寫(xiě)一個(gè)Lisp解釋器來(lái)實(shí)現(xiàn)那個(gè)功能。很奇妙是不是? 

我們來(lái)寫(xiě)一個(gè)簡(jiǎn)單的基于Scheme語(yǔ)法的Lisp解析器吧:

先導(dǎo)入庫(kù)

################ lis.py: Scheme Interpreter in Python 3.10
## (c) Peter Norvig, 2010-18; See http://norvig.com/lispy.html
## Type hints and minor additions by Luciano Ramalho
 
import math
import operator as op
from collections import ChainMap
from itertools import chain
from typing import Any, NoReturn
from typing import Union, List, MutableMapping, Optional, Iterator
 
Symbol = str
Atom = Union[float, int, Symbol]
Expression = Union[Atom, List]
 
Environment = MutableMapping[Symbol, object]
 
print(Atom, Expression)
print(Environment)

創(chuàng)建Parse解析

def parse(program: str) -> Expression:
    "Read a Scheme expression from a string."
    return read_from_tokens(tokenize(program))
 
def tokenize(s: str) -> List[str]:
    "Convert a string into a list of tokens."
    return s.replace('(', ' ( ').replace(')', ' ) ').split()
 
def read_from_tokens(tokens: List[str]) -> Expression:
    "Read an expression from a sequence of tokens."
    if len(tokens) == 0:
        raise SyntaxError('unexpected EOF while reading')
    token = tokens.pop(0)
    if '(' == token:
        exp = []
        while tokens[0] != ')':
            exp.append(read_from_tokens(tokens))
        tokens.pop(0)  # discard ')'
        return exp
    elif ')' == token:
        raise SyntaxError('unexpected )')
    else:
        return parse_atom(token)
 
def parse_atom(token: str) -> Atom:
    "Numbers become numbers; every other token is a symbol."
    try:
        return int(token)
    except ValueError:
        try:
            return float(token)
        except ValueError:
            return Symbol(token)

創(chuàng)建環(huán)境

def standard_env() -> Environment:
    "An environment with some Scheme standard procedures."
    env: Environment = {}
    env.update(vars(math))   # sin, cos, sqrt, pi, ...
    env.update(
        {
            '+': op.add,
            '-': op.sub,
            '*': op.mul,
            '/': op.truediv, # 小數(shù)除
            'quotient': op.floordiv, # 商 地板除法 整數(shù)除
            '>': op.gt,
            '<': op.lt,
            '>=': op.ge,
            '<=': op.le,
            '=': op.eq,
            'abs': abs,
            'append': lambda *args: list(chain(*args)),          
            'apply': lambda proc, args: proc(*args),
            'begin': lambda *x: x[-1],
            '起': lambda *x: x[-1],
            'car': lambda x: x[0],
            'cdr': lambda x: x[1:],
            'cons': lambda x, y: [x] + y,
            'eq?': op.is_,
            'equal?': op.eq,
            'filter': lambda *args: list(filter(*args)),
            'length': len,
            'list': lambda *x: list(x),
            'list?': lambda x: isinstance(x, list),
            'map': lambda *args: list(map(*args)),
            'max': max,
            'min': min,
            'not': op.not_,
            'null?': lambda x: x == [],
            'number?': lambda x: isinstance(x, (int, float)),
            'procedure?': callable,
            'round': round,
            'symbol?': lambda x: isinstance(x, Symbol),
            'display': lambda x: print(lispstr(x), end=''),
            '顯': lambda x: print(lispstr(x), end=''),
            'newline': lambda: print(),
        }
    )
    return env

執(zhí)行函數(shù)

def evaluate(x: Expression, env: Environment) -> Any:
    "Evaluate an expression in an environment."
    if isinstance(x, str):                       # variable reference
        return env[x]
    elif not isinstance(x, list):                # constant literal
        return x
    elif x[0] == 'define':                       # (define var exp)
        _, var, exp = x
        env[var] = evaluate(exp, env)
    elif x[0] == 'lambda':                       # (lambda (var...) body)
        _, parms, body = x
        return Procedure(parms, body, env)
    elif x[0] == 'quote':                        # (quote exp)
        _, exp = x
        return exp
    elif x[0] == 'if':                           # (if test consequence alternative)
        _, test, consequence, alternative = x
        if evaluate(test, env):
            return evaluate(consequence, env)
        else:
            return evaluate(alternative, env)
    elif x[0] == '設(shè)':                       # (define var exp)
        _, var, exp = x
        env[var] = evaluate(exp, env)
    elif x[0] == '函':                       # (lambda (var...) body)
        _, parms, body = x
        return Procedure(parms, body, env)
    elif x[0] == '引':                        # (quote exp)
        _, exp = x
        return exp
    elif x[0] == '若':                           # (if test consequence alternative)
        _, test, consequence, alternative = x
        if evaluate(test, env):
            return evaluate(consequence, env)
        else:
            return evaluate(alternative, env)
    else:                                        # (proc arg...)
        proc_exp, *args = x
        proc = evaluate(proc_exp, env)
        arg_values = [evaluate(exp, env) for exp in args]
        return proc(*arg_values)

交互執(zhí)行函數(shù)

def run_lines(source: str, env: Optional[Environment] = None) -> Iterator[Any]:
    global_env: Environment = ChainMap({}, standard_env())
    if env is not None:
        global_env.update(env)
    tokens = tokenize(source)
    while tokens:
        exp = read_from_tokens(tokens)
        yield evaluate(exp, global_env)
 
 
def run(source: str, env: Optional[Environment] = None) -> Any:
    # 實(shí)際上,這個(gè)函數(shù)只是簡(jiǎn)單地迭代了run_lines的所有結(jié)果,并沒(méi)有對(duì)其進(jìn)行任何操作。
    # 最后,返回run_lines的最后一個(gè)結(jié)果。
    for result in run_lines(source, env):
        pass
    return result

運(yùn)行測(cè)試

percent = """
(define a 126)
(define b (* 6 50))
(* (/ a b) 100)
"""
run(percent)

輸出:42

當(dāng)然我們也可以用中文關(guān)鍵字:

percent = """
(設(shè) a 126)
(設(shè) b (* 6 50))
(* (/ a b) 100)
"""
run(percent)

這樣看起來(lái)是不是更親切一些了呢?

以上代碼節(jié)選自:https://github.com/fluentpython/lispy

附:

scheme學(xué)習(xí)資料:The Scheme Programming Language, 4th Edition

到此這篇關(guān)于使用Python編寫(xiě)一個(gè)Lisp語(yǔ)言的解釋器的文章就介紹到這了,更多相關(guān)Python Lisp語(yǔ)言解釋器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python3中在Anaconda環(huán)境下安裝basemap包

    Python3中在Anaconda環(huán)境下安裝basemap包

    今天小編就為大家分享一篇關(guān)于Python3中在Anaconda環(huán)境下安裝basemap包的文章,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-10-10
  • Python實(shí)現(xiàn)TCP/IP協(xié)議下的端口轉(zhuǎn)發(fā)及重定向示例

    Python實(shí)現(xiàn)TCP/IP協(xié)議下的端口轉(zhuǎn)發(fā)及重定向示例

    這篇文章主要介紹了Python實(shí)現(xiàn)TCP/IP協(xié)議下的端口轉(zhuǎn)發(fā)及重定向示例,以一個(gè)webpy站點(diǎn)在本機(jī)的兩個(gè)端口雙向通信下演示,需要的朋友可以參考下
    2016-06-06
  • Python?numpy視圖與副本

    Python?numpy視圖與副本

    這篇文章主要介紹了Python?numpy視圖與副本,繼上一篇對(duì)numpy?模塊之ndarray一文中對(duì)?ndarray?內(nèi)存結(jié)構(gòu)主要分為兩部分metdata?、raw?bata,下面來(lái)一起學(xué)習(xí)文章具體內(nèi)容吧,需要的小伙伴也可以參考一下
    2022-01-01
  • 如何將python中的List轉(zhuǎn)化成dictionary

    如何將python中的List轉(zhuǎn)化成dictionary

    這篇文章主要介紹在python中如何將list轉(zhuǎn)化成dictionary,通過(guò)提出兩個(gè)問(wèn)題來(lái)告訴大家如何解決,有需要的可以參考借鑒。
    2016-08-08
  • Django單元測(cè)試的具體使用

    Django單元測(cè)試的具體使用

    Django提供了一套強(qiáng)大的測(cè)試工具來(lái)幫助開(kāi)發(fā)者編寫(xiě)和運(yùn)行單元測(cè)試,本文就來(lái)介紹一下Django中的單元測(cè)試,包括測(cè)試原理、編寫(xiě)測(cè)試用例和運(yùn)行測(cè)試,感興趣的可以了解一下
    2023-11-11
  • Python中的迭代器你了解嗎

    Python中的迭代器你了解嗎

    迭代器是一種特殊的對(duì)象,它實(shí)現(xiàn)了迭代協(xié)議,允許按照一定的順序逐個(gè)訪問(wèn)元素,本文就來(lái)帶大家深入了解一下Python中迭代器的使用,需要的可以參考下
    2023-05-05
  • 使用Python?openpyxl批量處理Excel的操作指南

    使用Python?openpyxl批量處理Excel的操作指南

    本文詳細(xì)介紹了如何使用Python的openpyxl庫(kù)自動(dòng)化處理Excel文件,從環(huán)境搭建到數(shù)據(jù)讀寫(xiě)、樣式設(shè)置、公式和圖表生成,再到批量處理多個(gè)文件,通過(guò)一個(gè)綜合實(shí)戰(zhàn)案例,展示了如何自動(dòng)生成月度部門(mén)薪資報(bào)告,需要的朋友可以參考下
    2026-03-03
  • Python實(shí)現(xiàn)繪制置信區(qū)間

    Python實(shí)現(xiàn)繪制置信區(qū)間

    置信區(qū)間是從觀測(cè)數(shù)據(jù)的統(tǒng)計(jì)量計(jì)算的一種估計(jì)值,它給出了一個(gè)可能包含具有特定置信水平的總體參數(shù)的值范圍,下面我們就來(lái)看看如何使用Python繪制置信區(qū)間吧
    2024-02-02
  • 從基礎(chǔ)到高級(jí)詳解Python數(shù)值格式化輸出的完全指南

    從基礎(chǔ)到高級(jí)詳解Python數(shù)值格式化輸出的完全指南

    在數(shù)據(jù)分析、金融計(jì)算和科學(xué)報(bào)告領(lǐng)域,數(shù)值格式化是提升可讀性和專業(yè)性的關(guān)鍵技術(shù),本文將深入解析Python中數(shù)值格式化輸出的相關(guān)方法,感興趣的小伙伴可以了解下
    2025-08-08
  • Python選擇網(wǎng)卡發(fā)包及接收數(shù)據(jù)包

    Python選擇網(wǎng)卡發(fā)包及接收數(shù)據(jù)包

    今天小編就為大家分享一篇關(guān)于Python選擇網(wǎng)卡發(fā)包及接收數(shù)據(jù)包,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-04-04

最新評(píng)論

炎陵县| 桦甸市| 印江| 襄樊市| 南投县| 集安市| 梁河县| 德江县| 邓州市| 兴宁市| 天全县| 玉环县| 斗六市| 延津县| 黄骅市| 梁河县| 东丰县| 措勤县| 独山县| 原平市| 绥宁县| 安塞县| 万安县| 东乡族自治县| 老河口市| 海原县| 兴安盟| 永安市| 湖南省| 惠水县| 高阳县| 鹤岗市| 遂昌县| 祁东县| 凌云县| 道真| 孝义市| 峡江县| 祁门县| 沙洋县| 上饶县|