欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

我們來寫一個(gè)簡(jiǎn)單的基于Scheme語法的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é)果,并沒有對(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)

這樣看起來是不是更親切一些了呢?

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

附:

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

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

相關(guān)文章

  • pycharm配置Anaconda虛擬環(huán)境全過程

    pycharm配置Anaconda虛擬環(huán)境全過程

    這篇文章主要介紹了pycharm配置Anaconda虛擬環(huán)境全過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Python+Appium實(shí)現(xiàn)自動(dòng)搶微信紅包

    Python+Appium實(shí)現(xiàn)自動(dòng)搶微信紅包

    不知從何時(shí)開始微信紅包橫空出世,對(duì)于網(wǎng)速和手速慢的人只能在一旁觀望,做為python的學(xué)習(xí)者就是要運(yùn)用編程解決生活和工作上的事情。于是我用python解決我們的手速問題python實(shí)現(xiàn)自動(dòng)搶微信紅包,至于網(wǎng)速慢得那就只能自己花錢提升了。
    2021-05-05
  • Python封裝成可帶參數(shù)的EXE安裝包實(shí)例

    Python封裝成可帶參數(shù)的EXE安裝包實(shí)例

    今天小編就為大家分享一篇Python封裝成可帶參數(shù)的EXE安裝包實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • Python3.5裝飾器原理及應(yīng)用實(shí)例詳解

    Python3.5裝飾器原理及應(yīng)用實(shí)例詳解

    這篇文章主要介紹了Python3.5裝飾器原理及應(yīng)用,結(jié)合具體實(shí)例形式詳細(xì)分析了Python3.5裝飾器的概念、原理、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-04-04
  • python輸出決策樹圖形的例子

    python輸出決策樹圖形的例子

    今天小編就為大家分享一篇python輸出決策樹圖形的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • 自己使用總結(jié)Python程序代碼片段

    自己使用總結(jié)Python程序代碼片段

    這篇文章主要介紹了自己使用總結(jié)Python程序代碼片段,本文收集了如反向讀取文件、往文件中所有添加指定的前綴、匿名函數(shù)作為返回值、將二進(jìn)制數(shù)轉(zhuǎn)為10進(jìn)制數(shù)等實(shí)用代碼片段,需要的朋友可以參考下
    2015-06-06
  • Python數(shù)據(jù)分析庫(kù)pandas基本操作方法

    Python數(shù)據(jù)分析庫(kù)pandas基本操作方法

    下面小編就為大家分享一篇Python數(shù)據(jù)分析庫(kù)pandas基本操作方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • Python設(shè)計(jì)模式之原型模式實(shí)例詳解

    Python設(shè)計(jì)模式之原型模式實(shí)例詳解

    這篇文章主要介紹了Python設(shè)計(jì)模式之原型模式,結(jié)合實(shí)例形式較為詳細(xì)的分析了Python原型模式的概念、原理、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-01-01
  • Python+PyQt5實(shí)現(xiàn)自動(dòng)點(diǎn)擊神器

    Python+PyQt5實(shí)現(xiàn)自動(dòng)點(diǎn)擊神器

    這篇文章主要為大家詳細(xì)介紹了如何利用Python和PyQt5實(shí)現(xiàn)自動(dòng)點(diǎn)擊神器,旨在解決重復(fù)性的點(diǎn)擊工作,解放雙手,具有及時(shí)性和準(zhǔn)確性,需要的可以參考下
    2024-01-01
  • python基于opencv 實(shí)現(xiàn)圖像時(shí)鐘

    python基于opencv 實(shí)現(xiàn)圖像時(shí)鐘

    這篇文章主要介紹了python基于opencv 實(shí)現(xiàn)圖像時(shí)鐘的方法,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2021-01-01

最新評(píng)論