Parsing conditional statements in Lark + repeated execution of code

34 Views Asked by At

I'm trying to parse an own programming language in Lark. But how can I parse conditional statements like if or while statements? More specifically, how can I execute the code block only if the condition is true and how can I repeat the execution of the condition of while statements?

I have created a very simple example programming language to show my problems:

from lark import Lark, Transformer, v_args

gram = """

NUMBER: "0"|"1"

number: NUMBER

value: number|comparison

comparison: value "==" value

condition: comparison

print_func: "print" "(" value ")"

code: ((print_func|if_stmt|while_stmt) ";")*

if_stmt: "if" condition "{" code "}"

while_stmt: "while" condition "{" code "}"

file: code

%import common.WS
%ignore WS

"""

class Done:
    def __str__(self):
        return "[done!]"

    def __repr__(self):
        return "[done!]"

done = Done()

parser = Lark(gram, start="file")

@v_args(inline=True)
class trans(Transformer):
    number = int

    def comparison(self, a, b):
        return a == b

    def print_func(self, value):
        print(value)
        return done

    # ?????
    #def if_stmt(self, cond, code):
    #   pass

    condition = lambda self,x: x

    value = lambda self,x: x

    file = lambda self,x: x

tr = trans()


code = """

print(1 == 1);
print(1 == 0);

if 1 == 1 {
    print(1);
};

if 1 == 0 {
    print(0);
};

while 1 == 1 {
    print(1);
};

"""

print("Program output:\n")
tree = tr.transform(parser.parse(code))

print("\nDebug output:\n")
print(tree)
print("")
print(tree.pretty())

This gives me the following output:

Program output:

True
False
1
0
1

Debug output:

Tree(Token('RULE', 'code'), [[done!], [done!], Tree(Token('RULE', 'if_stmt'), [True, Tree(Token('RULE', 'code'), [[done!]])]), Tree(Token('RULE', 'if_stmt'), [False, Tree(Token('RULE', 'code'), [[done!]])]), Tree(Token('RULE', 'while_stmt'), [True, Tree(Token('RULE', 'code'), [[done!]])])])

code
  [done!]
  [done!]
  if_stmt
    True
    code        [done!]
  if_stmt
    False
    code        [done!]
  while_stmt
    True
    code        [done!]

The Done class is simply for debugging to see if a statement has been executed or not.

How can I prevent the code inside the if 1 == 0 (and generally the code in conditional statements whose condition evaluate as false) from being executed?

Additionally, how can I repeat the execution of the condition of the while statement (and other types of statements which need this, e.g. Lua's repeat ... until ... statement) each time the code block has finished to decide whether the loop should exit or run the block again? (I know, in the code above, while 1 == 1 {...} would cause an infinite loop, but that code is just for showing my problems and not intended for actual/practical use, thus I wanted to keep it as simple as possible)?

I'm use Windows 11, Python 3.11.1 and Lark 1.1.9.

The solutions given in this question and its comments did not solve my problem.

0

There are 0 best solutions below