user5428937
user5428937

Reputation:

Setting variables with regex

I am creating a language with regex this is my code so far:

    import re

    outputf=r'output (.*)'
    inputf=r'(.*) = input (.*)'
    intf=r'int (.*) = (\d)'
    floatf=r'float (.*) = (\d\.\d)'

    def check_line(line):
        outputq=re.match(outputf, line)
        if outputq:
            exec ("print (%s)" % outputq.group(1))

        inputq=re.match(inputf, line)
        if inputq:
            exec ("%s=raw_input(%s)"%(inputq.group(1), inputq.group(2)))

        intq=re.match(intf, line)
        if intq:
            exec ("%s = %s"%(intq.group(1), intq.group(2)))
            print x

        floatq=re.match(floatf, line)
        if floatq:
            exec ("%s = %s"%(floatq.group(1), floatq.group(2)))


    code=open("code.psu", "r").readlines()

    for line in code:
        check_line(line) 

So it works great but in my file, here is my code:

int x = 1
output "hi"
float y = 1.3
output x

But when i read line 4, it says the variable x is not defined. How can I set it up so it can also print variables?

Upvotes: 2

Views: 56

Answers (1)

Brian
Brian

Reputation: 2242

When exec() is called it optionally can be passed the global and local dictionaries of variables that it will use. By default, it uses globals() and locals().

The problem is, you are using exec() to set a variable like x = 1 in your example. That does get set, and you can will see it in locals(). But after you leave the function, that variable is gone.

So, you'll need to save the locals() after each exec() call.

EDIT:

I was writing this addendum as you answered it yourself, so I figured I post it anyway...

Here's a simple example that fails (same error as your example):

def locals_not_saved(firsttime):
    if firsttime:
        exec("x = 1")
    else:
        exec("print(x)")

locals_not_saved(True)
locals_not_saved(False)

And here's a modified version that saves and reuses the locals() by saving them as an attribute to the the function - that's just one way to do it, YMMV.

def locals_saved(firsttime):
    if not hasattr(locals_saved, "locals"):
        locals_saved.locals = locals()

    if firsttime:
        exec("x = 1", globals(), locals_saved.locals)
    else:
        exec("print(x)", globals(), locals_saved.locals)

locals_saved(True)
locals_saved(False)

Upvotes: 2

Related Questions