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.