Robot_Steve 发表于 2020-4-3 19:22:40

Python 编写一门“编程语言”

本帖最后由 Robot_Steve 于 2021-11-10 21:50 编辑

最近闲来无事,想着办法“玩”

于是写了一个“编程语言”,至少满足了编程语言三大特性:
1. 变量
2. 函数
3. 关键字

注:部分东西没有加上,如:函数的参数不是一个变量

先上源码(GUI 由 tkinter 完成):

import tkinter.messagebox as msg
from tkinter import *

root = Tk() # 创建主窗口
root.title("Title") # 设置标题
root.geometry("550x340+370+240") # 设置窗口大小
root.resizable(0, 0) # 设置窗口的尺寸不可改变

# 菜单
mb = Menu(root)
root.config(menu=mb)

# 定义 “主区块” 类
class WinMian:
    def __init__(self):
      self.home()
    def home(self):
      self.homefrome = Frame(root, bg="Black", width=530,height=340)
      self.homefrome.place(x=0,y=0)
      # 命令框
      self.text = Text(self.homefrome, width=74, height=20, bg="LightSlateGray",
                         fg="White")
      self.text.place(x=3,y=3)
      self.jg = Text(self.homefrome,width=74,height=5, bg="LightSlateGray")
      self.jg.place(x=3,y=270)

      def run(): # 运行函数
            commands_texts = (self.text.get("0.0","end").replace("\t","")).split("\n")
            commands_texts.pop()

            function_list = []# 储存函数名
            function_drit = {}# 储存函数相对应的参数
            function_code_drit = {}# 储存函数相对应的代码
            global_var = {}
            local_var= {}

            def RunMainStartFunction(infunction=False, code=None, functionname=None,
                                     parmeter=None):
                global functioncode, parmeters_lens
                # print("Coommands",commands_text)
                # 定义关键字
                def hhh(name):
                  name_list = []
                  error = False
                  for w2 in name:
                        name_list.append(w2)

                  commandd = list(commands_text)
                  while name_list != []:
                        if name_list == commandd:
                            name_list.pop(0)
                            commandd.pop(0)
                        else:
                            msg.showerror("Error", "SyntaxError"+"\nThe Wrong: "+commands_texts)
                            error = True
                            break
                  # print(commandd)
                  return_list = []
                  if error == False:
                        string = ""
                        while commandd != []:
                            # print(commandd)
                            if commandd != "^":
                              string = string + commandd
                              commandd.pop(0)

                              if commandd == []:
                                    return_list.append(string)
                                    break
                            else:
                              return_list.append(string)
                              string = ""
                              commandd.pop(0)
                              if commandd == []:
                                    break

                  return return_list
                if infunction == True:
                  commands_text = code
                  if "pm:" in commands_text:
                        r = hhh("pm:")
                        functionparmeter = function_drit
                        get_parmeters_list = functionparmeter.keys()
                        parmeters_list = []
                        for w5 in get_parmeters_list:
                            parmeters_list.append(w5)# 将键(函数参数)存入列表
                        parmeters_list_lens = len(parmeters_list)# 函数参数长度
                        set_parmeters_lens = len(r)# 设置参数的长度
                        # print(parmeters_list, parmeters_list_lens, set_parmeters_lens)
                        if set_parmeters_lens == parmeters_list_lens:# 当长度符合条件时...
                            while r != []:
                              if r == "None":# 当用户放弃设置当前参数时,恢复默认(None)
                                    function_drit2 = function_drit
                                    function_drit2] = None
                                    function_drit = function_drit2
                                    r.pop(0)
                                    parmeters_list.pop(0)
                              else:
                                    function_drit2 = function_drit
                                    function_drit2] = r
                                    function_drit = function_drit2
                                    r.pop(0)
                                    parmeters_list.pop(0)
                            commands_text.pop(0)
                        else:
                            msg.showerror("Error", "ParameterSettingFailedError"+"\nThe Wrong: "+commands_texts)

                  functionparmeters = function_drit
                  if functionparmeters != None:
                        get_parmeters = functionparmeters.keys()
                        parmeterslist = []
                        for w5 in get_parmeters:
                            parmeterslist.append(w5)
                        parmeters_lens = len(parmeterslist)# 参数长度
                        parmeter_lens = len(parmeter)
                        parmeterslist2 = parmeterslist.copy()
                        while parmeterslist2 != []:
                            if functionparmeters] == None:
                              parmeterslist2.pop(0)
                            else:
                              parmeterslist2.pop(0)
                              parmeters_lens = parmeters_lens - 1
                        if parmeters_lens == parmeter_lens:
                            while parmeter != []:
                              functionparmeters] = parmeter
                              parmeter.pop(0)
                              parmeterslist.pop(0)
                        else:
                            msg.showerror("Error", "SyntaxError"+"\nThe Wrong: "+commands_texts)
                else:
                  # ...
                  commands_text = commands_texts.copy()

                # 运行函数
                # print(commands_text)
                true= "True"
                false = "False"
                while commands_text != []:
                  if "printf:" in commands_text:
                        r = hhh("printf:")
                        string = r

                        while "/b" in string: # 转移符捕捉
                            string_list = list(string)
                            hindex = string_list.index("/")

                            if string_list == "b":
                              string_list.pop(hindex)
                              string_list.pop(hindex)
                              string_list.insert(hindex, "\n")
                              import_str = ""
                              for w3 in string_list:
                                    import_str = import_str + w3

                              string = import_str
                        # print(r)
                        if string in global_var:
                            if len(r) == 1:
                              self.jg.insert(END, str(global_var) + "\n")
                            if len(r) == 2:
                              if r in global_var:
                                    self.jg.insert(END, str(global_var) + str(global_var]))
                              elif r in local_var:
                                    self.jg.insert(END, str(global_var) + str(local_var]))
                              else:
                                    self.jg.insert(END, r + r)
                        elif string in local_var:
                            yesglobal = local_var
                            print(yesglobal)
                            if infunction == True:
                              if yesglobal == functionname or yesglobal == None:
                                    if len(r) == 1:
                                        self.jg.insert(END, str(local_var) + "\n")
                                    if len(r) == 2:
                                        if r in global_var:
                                          self.jg.insert(END, str(local_var) + str(global_var]))
                                        elif r in local_var:
                                          self.jg.insert(END, str(local_var) + str(local_var]))
                                        else:
                                          self.jg.insert(END, r + r)
                              else:
                                    msg.showerror("Error","NameError")
                            else:
                              if yesglobal == None:
                                    if len(r) == 1:
                                        self.jg.insert(END, str(local_var) + "\n")
                                    if len(r) == 2:
                                        if r in global_var:
                                          self.jg.insert(END, str(local_var) + str(global_var]))
                                        elif r in local_var:
                                          self.jg.insert(END, str(local_var) + str(local_var]))
                                        else:
                                          self.jg.insert(END, r + r)
                              else:
                                    msg.showerror("Error", "NameError")
                        else:
                            if len(r) == 1:
                              self.jg.insert(END,string+"\n")
                            if len(r) == 2:
                              if r in global_var:
                                        self.jg.insert(END, r + str(global_var]) )
                              elif r in local_var:
                                    yesglobal2 = local_var]
                                    if infunction == True:
                                        if yesglobal2 == functionname or yesglobal2 == None:
                                          self.jg.insert(END, r + str(local_var]))
                                        else:
                                          msg.showerror("Error", "NameError")
                                    else:
                                        self.jg.insert(END, r + str(local_var]))
                              else:
                                    self.jg.insert(END,r+r)
                        commands_text.pop(0)
                  elif "function:" in commands_text:
                        r = hhh("function:")
                        try:
                            function_name = r # 函数名
                        except:
                            msg.showerror("Error", "ParameterSettingFailedError"+"\nThe Wrong: "+commands_texts)
                        else:
                            r.pop(0)
                            function_parameter_drit = {} # 函数参数
                            have_parameter = False
                            if r == []:
                              # 如果没有设置参数,默认为 None
                              pass
                            else:
                              for w4 in r:
                                    function_parameter_drit = None
                              have_parameter = True
                            commands_text.pop(0)
                            code = []

                            if commands_text == "{":
                              commands_text.pop(0)
                              while commands_text != "}":
                                    code.append(commands_text.replace("\t",""))
                                    commands_text.pop(0)
                                    if commands_text == []:
                                        msg.showerror("Error", "SyntaxError")
                              function_code_drit = code
                              function_list.append(function_name)
                              if have_parameter == False:
                                    function_drit = None
                              else:
                                    function_drit = function_parameter_drit
                              # print(function_list,function_drit,function_code_drit)
                            else:
                              msg.showerror("Error", "SyntaxError"+"\nThe Wrong: "+commands_texts)
                            commands_text.pop(0)
                  elif "value:" in commands_text:
                        h2 = hhh("value:")
                        if len(h2) == 4:
                            if h2 == "int":
                              try:
                                    intnum = int(h2)
                              except:
                                    msg.showerror("Error", "TypeError")
                              else:
                                    if infunction == True:
                                        if h2 == true:
                                          global_var] = ["int",intnum,functionname]
                                        elif h2 == false:
                                          local_var] = ["int",intnum,functionname]
                                        else:
                                          msg.showerror("Error", "SyntaxError")
                                    else:
                                        if h2 == true:
                                          global_var] = ["int",intnum,None]
                                        elif h2 == false:
                                          local_var] = ["int",intnum,None]
                                        else:
                                          msg.showerror("Error", "SyntaxError")
                            elif h2 == "str":
                              try:
                                    strnum = str(h2)
                              except:
                                    msg.showerror("Error", "TypeError")
                              else:
                                    if infunction == True:
                                        if h2 == true:
                                          global_var] = ["str",strnum,functionname]
                                        elif h2 == false:
                                          local_var] = ["str",strnum,functionname]
                                        else:
                                          msg.showerror("Error", "SyntaxError")
                                    else:
                                        if h2 == true:
                                          global_var] = ["str",strnum,None]
                                        elif h2 == false:
                                          local_var] = ["str",strnum,None]
                                        else:
                                          msg.showerror("Error", "SyntaxError")
                            elif h2 == "float":
                              try:
                                    floatnum = float(h2)
                              except:
                                    msg.showerror("Error", "TypeError")
                              else:
                                    if infunction == True:
                                        if h2 == true:
                                          global_var] = ["float", floatnum, functionname]
                                        elif h2 == false:
                                          local_var] = ["float", floatnum, functionname]
                                        else:
                                          msg.showerror("Error", "SyntaxError")
                                    else:
                                        if h2 == true:
                                          global_var] = ["float", floatnum, None]
                                        elif h2 == false:
                                          local_var] = ["float", floatnum, None]
                                        else:
                                          msg.showerror("Error", "SyntaxError")
                            else:
                              msg.showerror("Error", "ValueError")
                        else:
                            msg.showerror("Error", "SyntaxError")
                        commands_text.pop(0)
                        print(global_var, local_var)
                  elif "#" in commands_text:
                        hhh("#") # 行注释
                        commands_text.pop(0)
                  elif commands_text == "":
                        # 当用户为了美观不写任何代码时,忽略此行
                        commands_text.pop(0)
                  else:
                        function_name_check = function_list.copy()
                        if function_name_check != []:
                            self.have = False
                            while function_name_check != []:
                              if function_name_check in commands_text:
                                    functioncode = function_code_drit]
                                    self.have = True
                                    break
                              else:
                                    function_name_check.pop(0)

                            if self.have != False:
                              r1 = hhh(function_name_check+":")
                              RunMainStartFunction(True, functioncode,function_name_check,r1)
                              commands_text.pop(0)
                            else:
                              msg.showerror("Error", "NameError1"+"\nThe Wrong: "+commands_texts)
                              break
                        else:
                            msg.showerror("Error", "NameError"+"\nThe Wrong: "+commands_texts)
                            break
                        self.have = False

            RunMainStartFunction()
      # 创建文件菜单
      file = Menu(mb, tearoff=False)
      file.add_command(label="Open   ", command="")
      file.add_command(label="Save   ", command="")
      file.add_command(label="Run   ", command=run)
      file.add_separator()
      file.add_command(label="Exit   ", command=root.quit)
      mb.add_cascade(label="File", menu=file)
WinMian()

mainloop()

运行后在最上边的文本文档里边儿输入此代码,可以看到解析的结果哟(可以加上缩进,但注意一定要是缩进):
value:e1^int^123^False
function:hhh^a^b
{
pm:None^abcdefg
printf:hello, world
value:ints^int^123^False
printf:ints
printf:e1
}

# ...
hhh:12
printf:========

function:exercise
{
value:e2^str^hello123456^False
printf:e2
printf:e1^e2
}
exercise:

你也可以由此源代码继续发展,获得一个真正的编程语言。
我有注释,你可以查看代码进行继续编写


static/image/hrline/4.gif


定义关键字的函数: hhh()
我把它单独提炼了出来
代码:
# 定义关键字
def hhh(name):
    name_list = []
    error = False
    for w2 in name:
      name_list.append(w2)
   
    """
    commands_text 是一个列表是用户输入的内容。
    commands_text = self.text.get("0.0","end").split("\n")
    """
    commandd = list(commands_text)
    while name_list != []:
    if name_list == commandd:
      name_list.pop(0)
      commandd.pop(0)
    else:
      msg.showerror("Error", "SyntaxError"+"\nThe Wrong: "+commands_texts)
      error = True
      break
    # print(commandd)
    return_list = []
    if error == False:
    string = ""
    while commandd != []:
      # print(commandd)
      if commandd != "^": # 我在这儿以“^”作为分隔符
            string = string + commandd
            commandd.pop(0)
   
            if commandd == []:
                return_list.append(string)
                break
      else:
            return_list.append(string)
            string = ""
            commandd.pop(0)
            if commandd == []:
                break
   
    return return_list # 返回值是一个列表
    # 例如: printf:hello, world^12345
    # 返回: ["hello, world", 12345]

qiuyouzhi 发表于 2020-4-3 19:28:20

复制运行后,连续甩出7个错误。。。

Robot_Steve 发表于 2020-4-3 19:29:34

qiuyouzhi 发表于 2020-4-3 19:28
复制运行后,连续甩出7个错误。。。

你用的是Python3还是Python2

qiuyouzhi 发表于 2020-4-3 19:30:29

Robot_Steve 发表于 2020-4-3 19:29
你用的是Python3还是Python2

Python3鸭

Robot_Steve 发表于 2020-4-3 19:31:20

本帖最后由 Robot_Steve 于 2020-4-3 19:32 编辑

qiuyouzhi 发表于 2020-4-3 19:30
Python3鸭

我的是能运行的呀,要不你把错误信息发给我。

qiuyouzhi 发表于 2020-4-3 19:33:08

Robot_Steve 发表于 2020-4-3 19:31
我的是能运行的呀

emmmm
{} {'e1': ['int', 123, None]}
{} {'e1': ['int', 123, None]}
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\rzzl\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
File "C:\Users\rzzl\Desktop\test2.py", line 350, in run
    RunMainStartFunction()
File "C:\Users\rzzl\Desktop\test2.py", line 340, in RunMainStartFunction
    RunMainStartFunction(True, functioncode,function_name_check,r1)
File "C:\Users\rzzl\Desktop\test2.py", line 141, in RunMainStartFunction
    string = r
IndexError: list index out of range
还有这么一个错误

Robot_Steve 发表于 2020-4-3 19:36:06

qiuyouzhi 发表于 2020-4-3 19:33
emmmm
{} {'e1': ['int', 123, None]}
{} {'e1': ['int', 123, None]}


emmmmmm
太奇怪了,我的能运行。

qiuyouzhi 发表于 2020-4-3 19:37:19

Robot_Steve 发表于 2020-4-3 19:36
emmmmmm
太奇怪了,我的能运行。

那好吧,我再看看别的鱼油可不可以运行
要是他们都行就是我这里的问题了{:10_266:}
顺便问下,为啥是一本编程语言呢?

Robot_Steve 发表于 2020-4-3 19:38:26

qiuyouzhi 发表于 2020-4-3 19:37
那好吧,我再看看别的鱼油可不可以运行
要是他们都行就是我这里的问题了

你在里边儿输了代码是什么呀?
我这个只是,测试阶段。也许输你输的命令有一点点错误它就会报错。{:10_266:}

qiuyouzhi 发表于 2020-4-3 19:42:47

Robot_Steve 发表于 2020-4-3 19:38
你在里边儿输了代码是什么呀?
我这个只是,测试阶段。也许输你输的命令有一点点错误它就会报错。{:10_2 ...

我就直接复制了你写的代码鸭

Robot_Steve 发表于 2020-4-3 19:44:40

qiuyouzhi 发表于 2020-4-3 19:42
我就直接复制了你写的代码鸭

我刚上网查了查。系统的不一样,有可能导致异常{:10_266:}

qiuyouzhi 发表于 2020-4-3 19:45:01

Robot_Steve 发表于 2020-4-3 19:44
我刚上网查了查。系统的不一样,有可能导致异常


好吧

隔壁繁星吖 发表于 2020-4-3 19:52:14

我这里运行没问题

Robot_Steve 发表于 2020-4-3 19:54:04

qiuyouzhi 发表于 2020-4-3 19:45

好吧

等等,我反复试验了好几次,终于发现错误。
跟你那个错误差不多。
等一下,我解决一下。
一会儿把正常的发给你。

Robot_Steve 发表于 2020-4-3 19:56:47

qiuyouzhi 发表于 2020-4-3 19:45

好吧

你试一试这个吧:
value:e1^int^123^False
function:hhh^a^b
{
        pm:None^abcdefg
        printf:hello, world
        value:ints^int^123^False
        printf:ints
        printf:e1
}

# ...
hhh:12
printf:========

function:exercise
{
        value:e2^str^hello123456^False
        printf:e2
        printf:e1^e2
}
exercise:

qiuyouzhi 发表于 2020-4-3 20:00:04

Robot_Steve 发表于 2020-4-3 19:56
你试一试这个吧:
value:e1^int^123^False
function:hhh^a^b


还是不行{:10_266:}
算了,就这样吧

Robot_Steve 发表于 2020-4-3 20:04:47

qiuyouzhi 发表于 2020-4-3 20:00
还是不行
算了,就这样吧

我终于知道了!!!!!!!!
你把里边的缩进都去掉,再试一次。

qiuyouzhi 发表于 2020-4-3 20:32:20

Robot_Steve 发表于 2020-4-3 20:04
我终于知道了!!!!!!!!
你把里边的缩进都去掉,再试一次。

Wow,成功了!
谢谢!

Robot_Steve 发表于 2020-4-3 20:35:13

粘贴出来的代码,里边的缩进都不是缩进,是空格。
换算:
一个缩进= 四个空格
四个空格 != 于四个缩进
以后像这样的代码我还是去掉缩进吧。{:10_266:}
页: [1]
查看完整版本: Python 编写一门“编程语言”