使用两个不同的函数后,全局变量不会保持其状态

Global variables don't mantain their status after the usage of two distinct functions

所以我这几天都遇到了麻烦。基本上,我正在为使用 python 创建的语言制作编译器。我们得到了 sintax 和 lexic 部分,现在正在创建目录过程和变量 table(符号 table)。在我的 Yacc 文件中,我有:

Yacc.py

import ply.yacc as yacc
import sys

tokens = Lex.tokens
#Global variables
procs = { }
current_fid = ""

# add new value to the procedure directory
def add_procs_to_dict(fid, ftipo, fparams, fdict):
    proc_dict = {}
    proc_dict[fid] = {
        'Tipo' : ftipo,
        'Params' : fparams,
        'Var_dict' : fdict
    }
    return proc_dict

# add new variable value to the procedure directory
def add_vars_to_dict(vid, vtipo, vparams):
    var_dict = {
        'Nombre' : vid,
        'Tipo' : vtipo,
        'Params' : vparams
        }
    print(current_fid)
    print(procs)    
    return proc_dict


# Parsing Rules    
def p_juego(p):
    '''Juego : JUEGO ID DOSP JuegoA JuegoB MainProgram'''
    current_fid = p[2]
    procs = add_procs_to_dict( p[2], p[1], 'void', {})

def p_vars(p):
    '''Vars : VAR ID COR_I Exp COR_D VarSizeA Vars2 DOSP Tipo PCOMA'''
    add_vars_to_dict( p[2], p[9], p[4])

这里要注意的重要一点是,我正在创建一个变量来保存当前 ID(名为 current_fid,这是在字典中插入的最后一个过程的名称)和一个字典变量(名为 procs,即 procedure/function 目录)作为全局范围。

当解析器输入解析规则 p_juego(p):(假设它被输入的代码是正确的,而且我已经 运行 它一个人)它假设设置为变量(current_fidprocs) 它在解析器进程中找到的值。它确实设置了正确的值。我可以打印函数内的变量和 returns 预期值。

一旦解析器退出函数 p_juego(p) 并进入另一个函数,如 p_vars(p) (此函数在字典上写入符号 table 作为最后插入的 procedure/function在全局目录上)全局变量(current_fidprocs)在其中没有值。 p_vars(p) 中有 2 个打印,始终显示变量为 null。

我对 python 比较陌生,也许我对这门语言有所了解。我的意图是,如果我在所有内容之前(在代码的顶部)定义一个变量,那么使用这些 "global" 变量的函数将更新它们的值并始终保留它们,即使另一个函数试图访问它们也是如此。 我尝试在名为 Semantics.py 的新 python 文件中添加过程,但变量的值在先前设置值的函数之外始终为 null。

我在这里错过了什么?

为了避免这样的范围界定问题并且为了更明确,我建议您使用 class。然后您可以使用 self.variable 在 class 方法调用之间保存信息。

[编辑] 您的代码中有很多问题。

首先:

你的函数add_vars_to_dict,定义并分配了一个你永远不会使用的字典(var_dict)并尝试 return 函数范围内不存在的东西 (proc_dict).

第二个:

函数p_juego,每次调用时,都会重新分配dict的值,这让你失去了procs[=的先例值31=]

procs = add_procs_to_dict( p[2], p[1], 'void', {})

但是,正如 majodi 所建议的,通常您可以使用 class 解决全局变量问题,在其中您使用实例变量,而不是全局变量

像这样:

class ClassTest(object):

    def __init__(self):
        self.procs = {}
        self.current_fid = ""

    # add new value to the procedure directory
    def add_procs_to_dict(self, fid, ftipo, fparams, fdict):
        # do something

    # add new variable value to the procedure directory
    def add_vars_to_dict(self, vid, vtipo, vparams):
        # do something

    # Parsing Rules
    def p_juego(self, p):
        # do something

    def p_vars(self, p):
        # do something

感谢大家的快速回复。我确实按照你们大多数人的建议做了另一个 class 但我没有保留我的全局值的原因是因为这些函数是按照我没有预料到的顺序调用的。 PLY 库使用自下而上的过程来导航语法树。实际上,在设置 even 之前读取值时调用了这些函数。

我感谢大家的回复,因为这是我第一次 post 在 SO 中,我受到所有回复答案、问我问题甚至更正我的 post 以继续使用的人的鼓励网站。

再次感谢。