一门基于宏替换的编程语言

本文档介绍了一种自定义的编程语言,其解释器虽然简陋但具备基本运算功能,如整数加法、条件判断等。作者通过示例展示了如何执行加法操作,并探讨了该语言的图灵完备性,即能够模拟图灵机,证明其理论上可以执行任何可计算函数。此外,还提供了一个简单的解释器实现(RUN.PY)来演示规则替换的过程。
摘要由CSDN通过智能技术生成

设计了一门编程语言,说来惭愧,解释器相当简陋低效。这东西有什么用我也不知道,总之先设计出来再说。语法是极其简单的。

示例程序

RULE.TXT

规定了所有宏替换规则,规则十分简单,替换的进行顺序是从上至下的。现在实现了四位整数的加法,两位整数的前缀和运算,以及相关的一些其他运算。

$ AND ( 1 , #VAR ) : #VAR
$ AND ( 0 , #VAR ) : 0

$ OR ( 0 , #VAR ) : #VAR
$ OR ( 1 , #VAR ) : 1

$ IF ( 1 , #VAR ) : #VAR
$ IF ( 0 , #VAR ) : 
$ IF ( 1 , #VAR1 , #VAR2 ) : #VAR1
$ IF ( 0 , #VAR1 , #VAR2 ) : #VAR2

$ IF ( 1 , ( #T1 , #T2 ) , ( #F1 , #F2 ) ) : ( #T1 , #T2 )
$ IF ( 0 , ( #T1 , #T2 ) , ( #F1 , #F2 ) ) : ( #F1 , #F2 )

$ INC ( 0 ) : 1
$ INC ( 1 ) : 2
$ INC ( 2 ) : 3
$ INC ( 3 ) : 4
$ INC ( 4 ) : 5
$ INC ( 5 ) : 6
$ INC ( 6 ) : 7
$ INC ( 7 ) : 8
$ INC ( 8 ) : 9
$ INC ( 9 ) : 0

$ INC ( #V , 9 ) : INC ( #V ) , 0
$ INC ( #V1 , #V2 ) : #V1 , INC ( #V2 )

$ DEC ( 9 ) : 8
$ DEC ( 8 ) : 7
$ DEC ( 7 ) : 6
$ DEC ( 6 ) : 5
$ DEC ( 5 ) : 4
$ DEC ( 4 ) : 3
$ DEC ( 3 ) : 2
$ DEC ( 2 ) : 1
$ DEC ( 1 ) : 0
$ DEC ( 0 ) : 9

$ DEC ( #V , 0 ) : DEC ( #V ) , 9
$ DEC ( #V1 , #V2 ) : #V1 , DEC ( #V2 )

$ NOT ( 0 ) : 1
$ NOT ( #VAR ) : 0

$ LEQ ( 0 , 0 ) : 1
$ LEQ ( 0 , #_ ) : 1
$ LEQ ( 1 , 0 ) : 0
$ LEQ ( #VAR1 , #VAR2 ) : LEQ ( DEC ( #VAR1 ) , DEC ( #VAR2 ) )

$ EQU ( 0 , 0 ) : 1
$ EQU ( 0 , #VAR ) : 0
$ EQU ( #VAR , 0 ) : 0
$ EQU ( #VAR1 , #VAR2 ) : EQU ( DEC ( #VAR1 ) , DEC ( #VAR2 ) )
$ EQU ( ( #A1 , #A2 ) , ( #B1 , #B2 ) ) : AND ( EQU ( #A1 , #B1 ) , EQU ( #A2 , #B2 ) )

$ MIN ( #A , #B ) : IF ( LEQ ( #A , #B ) , #A , #B )
$ MAX ( #A , #B ) : IF ( LEQ ( #A , #B ) , #B , #A )

$ ADD ( 0 , #A ) : 0 , #A
$ ADD ( #A , 0 ) : 0 , #A
$ ADD ( #A , 9 ) : 1 , DEC ( #A )
$ ADD ( 9 , #A ) : 1 , DEC ( #A )
$ ADD ( #A , #B ) : ADD ( DEC ( #A ) , INC ( #B ) )


% warning : this version of "ADD" is without carry in 
    $ SECOND ( #A , #B ) : #B
    $ ADD ( ( #A1 , #A2 ) , ( #B1 , #B2 ) ) :  ADDTOP ( SECOND ( ADD ( #A1 , #B1 ) ) , ADD ( #A2 , #B2 ) )
    $ ADDTOP ( #H1 , #H2 , #L ) : SECOND ( ADD ( #H1 , #H2 ) ) , #L


$ REPEAT ( #VAL , 0 ) :
$ REPEAT ( #VAL , 1 ) : #VAL
$ REPEAT ( #VAL , #TIME ) : #VAL , REPEAT ( #VAL , DEC ( #TIME ) )
$ REPEAT ( ( #V1 , #V2 ) , 0 ) :
$ REPEAT ( ( #V1 , #V2 ) , 1 ) : ( #V1 , #V2 )
$ REPEAT ( ( #V1 , #V2 ) , #TIME ) : ( #V1 , #V2 ) , REPEAT ( ( #V1 , #V2 ) , DEC ( #TIME ) )

$ DELETE ( 0 ) :
$ DELETE ( #CNT ) #A , : DELETE ( DEC ( #CNT ) ) 

% deprecated : MAXLIST
    $ MAXLIST #A , #B : MAXLIST MAX ( #A , #B )
    $ MAXLIST #A ; : #A

% warning : Pay attention to the char ";"
%    $ TO_END ( #VAL ) , #A : #A , TO_END ( #VAL )
%    $ , TO_END ( #VAL ) ; : ; #VAL
%    $ TO_END ( #VAL ) ; : #VAL

% warning : You must ban the OPTIMIZE for "REVERSE"
%    $ REVERSE ; : ;
%    $ REVERSE , #A ; : ; #A
%    $ REVERSE , #A , : TO_END ( #A ) , REVERSE ,

$ DELETE_FIRST ( #1 , #2 , #3 , #4 , #5 ) : #2 , #3 , #4 , #5
$ SUM ( 0 ) : 0 , 0 , 0 , 0
$ SUM ( 1 ) : 0 , 0 , 0 , 1
$ SUM ( #V ) : DELETE_FIRST ( ADD4 ( ( SUM ( DEC ( #V ) ) ) , ( 0 , 0 , 0 , #V ) ) )
$ SUM ( 0 , #L ) : SUM ( #L )
$ SUM ( #H , #L ) : DELETE_FIRST ( ADD4 ( ( SUM ( DEC ( #H , #L ) ) ) , ( 0 , 0 , #H , #L ) ) )

$ ADD3 ( ( #A2 , #A1 , #A0 ) , ( #B2 , #B1 , #B0 ) ) : MERGE_SUM ( ADD ( #A2 , #B2 ) , ADD ( #A1 , #B1 ) , ADD ( #A0 , #B0 ) )
$ MERGE_SUM ( #B6 , #B5 , #B4 , #B3 , #B2 , #B1 ) : MERGE_SUM ( #B6 , #B5 , #B4 , ADD ( #B3 , #B2 ) ) , #B1
$ MERGE_SUM ( #B6 , #B5 , #B4 , #B3 , #B2 ) : MERGE_SUM ( #B6 , ADD ( ( ADD ( ( 0 , #B5 ) , ( 0 , #B4 ) ) ) , ( 0 , #B3 ) ) ) , #B2
$ MERGE_SUM ( #B6 , #B5 , #B4 ) : SECOND ( ADD ( #B6 , #B5 ) ) , #B4

$ ADD4 ( ( #1 , #2 , #3 , #4 ) , ( #5 , #6 , #7 , #8 ) ) : MERGE_SUM_4 ( ADD ( #1 , #5 )  , ADD3 ( ( #2 , #3 , #4 ) , ( #6 , #7 , #8 ) ) )
$ MERGE_SUM_4 ( #1 , #2 , #3 , #4 , #5 , #6 ) : ADD ( ( #1 , #2 ) , ( 0 , #3 ) ) , #4 , #5 , #6

PROGRAM.TXT

程序中计算了两个数的加法。

ADD ( ( 4 , 3 ) , ( 1 , 7 ) ) ;

运行效果:

PROGRAM = ADD ( ( 4 , 3 ) , ( 1 , 7 ) ) ;
PROGRAM = ADDTOP ( SECOND ( ADD ( 4 , 1 ) ) , ADD ( 3 , 7 ) ) ;
PROGRAM = ADDTOP ( SECOND ( ADD ( DEC ( 4 ) , INC ( 1 ) ) ) , ADD ( DEC ( 3 ) , INC ( 7 ) ) ) ;
PROGRAM = ADDTOP ( SECOND ( ADD ( DEC ( 3 ) , INC ( 2 ) ) ) , ADD ( DEC ( 2 ) , INC ( 8 ) ) ) ;
PROGRAM = ADDTOP ( SECOND ( ADD ( DEC ( 2 ) , INC ( 3 ) ) ) , 1 , DEC ( 1 ) ) ;
PROGRAM = ADDTOP ( SECOND ( ADD ( DEC ( 1 ) , INC ( 4 ) ) ) , 1 , 0 ) ;
PROGRAM = SECOND ( ADD ( 5 , 1 ) ) , 0 ;
PROGRAM = SECOND ( ADD ( DEC ( 5 ) , INC ( 1 ) ) ) , 0 ;
PROGRAM = SECOND ( ADD ( DEC ( 4 ) , INC ( 2 ) ) ) , 0 ;
PROGRAM = SECOND ( ADD ( DEC ( 3 ) , INC ( 3 ) ) ) , 0 ;
PROGRAM = SECOND ( ADD ( DEC ( 2 ) , INC ( 4 ) ) ) , 0 ;
PROGRAM = SECOND ( ADD ( DEC ( 1 ) , INC ( 5 ) ) ) , 0 ;
PROGRAM = 6 , 0 ;
PROGRAM = 6 , 0 ; AFTER 13 ITERATION

解释器 RUN.PY

import traceback
import json
import os

def LOAD_RULES(FILE_NAME = 'RULE.TXT'): # INPUT RULE.TXT
    FPIN = open(FILE_NAME, "r")
    RULES_RAW = FPIN.readlines() # READ BY LINES
    FPIN.close()

    RULES = [] # RULES OF THE PROGRAM
    LINE_ID = 1
    for LINE in RULES_RAW:
        LINE_LIST = LINE.split() # SPLIT INTO ELEMENTS
        if len(LINE_LIST) != 0:
            if(LINE_LIST[0] == '$'): # THIS IS A RULE
                if ":" not in LINE_LIST:
                    raise Exception("ERROR ':' NOT FOUND IN LINE %d IN RULE.TXT" % LINE_ID)

                LEFT = []
                RIGHT = []
                LEFT_FLAG = True

                for STR in LINE_LIST[1:]: # DO NOT CARE ABOUT '$'
                    if STR == ":":
                        LEFT_FLAG = False
                    elif LEFT_FLAG:
                        LEFT.append(STR) # APPEND ON LEFT SIDE
                    else:
                        RIGHT.append(STR) # APPEND ON RIGHT SIDE

                RULES.append((LEFT, RIGHT)) # ADD A RULE
                pass
            elif(LINE_LIST[0] == '%'): # THIS IS A COMMENT
                pass
        LINE_ID += 1

    return RULES
    
def LOAD_PROGRAM(FILE_NAME = "PROGRAM.TXT"): # LOAD PROGRAM FROM FILE
    FPIN = open(FILE_NAME, "r")
    PROGRAM = FPIN.read().split() # MAKE STR
    FPIN.close()
    return PROGRAM

def MATCH(OLD_PROGRAM, POS, LEFT): # CHECK IF IT IS MATCH
    for OFFSET in range(0, len(LEFT)):
        if POS + OFFSET >= len(OLD_PROGRAM): # CAN NOT MATCH
            return False
        if LEFT[OFFSET][0] != '#' and LEFT[OFFSET] != OLD_PROGRAM[POS + OFFSET]:
            return False
    return True

def LOAD_VAR(OLD_PROGRAM, POS, LEFT): # LOAD '#' VAR FROM OLD_PROGRAM
    MESSAGE = {}
    for OFFSET in range(0, len(LEFT)):
        if LEFT[OFFSET][0] == '#': # FIND A #VAR
            MESSAGE[LEFT[OFFSET]] = OLD_PROGRAM[POS + OFFSET] # SAVE TO DICT
    return MESSAGE

def WRITE_PROGRAM(OLD_PROGRAM, POS, LEFT, RIGHT, MESSAGE):
    SEGMENT = []
    for OFFSET in range(0, len(RIGHT)):
        if RIGHT[OFFSET][0] == '#':
            SEGMENT.append(MESSAGE[RIGHT[OFFSET]]) # APPEND VAR VALUE
        else:
            SEGMENT.append(RIGHT[OFFSET]) # APPEND STR
    return OLD_PROGRAM[:POS] + SEGMENT + OLD_PROGRAM[POS + len(LEFT):]


def REPLACE(OLD_PROGRAM, RULES): # REPLACE BY RULES
    CNT = 0
    for RULE in RULES:
        LEFT, RIGHT = RULE # SEPERATE INTO TWO PARTS
        FLAG = True
        while FLAG: # FLAG = True MEANS FIND A MATCH POSITION
            FLAG = False
            NEW_PROGRAM = []
            for POS in range(0, len(OLD_PROGRAM)):
                if MATCH(OLD_PROGRAM, POS, LEFT):
                    FLAG = True
                    CNT += 1
                    MESSAGE = LOAD_VAR(OLD_PROGRAM, POS, LEFT)
                    NEW_PROGRAM = WRITE_PROGRAM(OLD_PROGRAM, POS, LEFT, RIGHT, MESSAGE)
                    break
            if FLAG:
                OLD_PROGRAM = NEW_PROGRAM
    return OLD_PROGRAM

if __name__ == "__main__":
    RULES = LOAD_RULES()
    # print(json.dumps(RULES, indent = 4)) # OUTPUT TO CHECK
    PROGRAM = LOAD_PROGRAM()
    print("PROGRAM = " + " ".join(PROGRAM))
    CNT = 1
    while True:
        TMP_PROGRAM = REPLACE(PROGRAM, RULES) # MAKE AN ITERATION
        if TMP_PROGRAM == PROGRAM:
            break
        else:
            PROGRAM = TMP_PROGRAM
            print("PROGRAM = " + " ".join(PROGRAM))
            CNT += 1
    print("PROGRAM = " + " ".join(PROGRAM) + " AFTER %d ITERATION" % CNT)

图灵完备

闲的无聊,证明一下这种替换算法是图灵完备的,因为可以模拟图灵机的运行(其实实质上就是一个图灵机的强化版而已)。在PROGRAM.TXT中构造一条“纸带:”,最开始存放的是初始的数据:

; Value[1] , Value[2] , ... , Value[i] , ... Value[n] ;

将定位器 PTR \text{PTR} PTR 放在纸带上:

; PTR ( id ,  Value[1] ) , Value[2] , ... , Value[i] , ... Value[n] ;

其中 i d id id 表示当前图灵机控制部分的 D F A DFA DFA 中所在结点的编号/名称。针对 i d id id 进行对 PTR \text{PTR} PTR 替换的设计即可模拟图灵机的全部功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值