Search code examples
pythonply

IF statement in PLY


I'm trying to write a parser for a simple programming language. I'm stuck at if statements. When I'm debugging I can see that instruction after if statement is handled before my if production. There's a sample program below where the problem I'm describing occurs for example input:

if 2>3 then print(3)

.

reserved = {
    'if': 'IF',
    'print': 'PRINT',
    'then':'THEN'
}

tokens = ['NUM', 'SEMICOLON', 'LPAR', 'RPAR', 'GT'] + list(reserved.values())

t_SEMICOLON = r';'
t_LPAR = r'\('
t_RPAR = r'\)'
t_GT = r'>'

t_ignore = r' '


def t_words(t):
    r'[a-zA-Z_][a-zA-Z0-9_]*'
    t.type = reserved.get(t.value, 'IDENT')
    return t


def t_NUM(t):
    r'\d+'
    t.value = int(t.value)
    return t


def t_error(t):
    print('Error at \'{}\''.format(t.value[0]))
    t.lexer.skip(1)


import ply.lex as lex
lex.lex()


def p_instruction(p):
    '''
    instr : instr SEMICOLON simple_instr
          | simple_instr
    '''


def p_simple_instruction(p):
    '''
    simple_instr : if_statement
                 | print_function
    '''


def p_if_statement(p):
    'if_statement : IF NUM GT NUM THEN simple_instr'


def p_print_function(p):
    '''print_function : PRINT LPAR NUM RPAR'''
    print(p[3])


def p_error(p):
    raise SyntaxError("Error at \'{}\'".format(p.value))


import ply.yacc as yacc
yacc.yacc()

while True:
    try:
        s = input('> ')
    except EOFError:
        break
    yacc.parse(s)

How to handle correctly if statements in PLY?


Solution

  • If you mean that print(3) is executed before 2<3 is evaluated, then that is certainly going to be the case. You cannot write an interpreter which immediately evaluates every statement because (if you have conditionals and loops and so on), every statement is not necessarily evaluated only once, or even once.

    The if statement is only reduced when the entire statement has been parsed, and the entire statement includes the then clause. So the interior statement must be parsed before the if statement is parsed.

    So immediate evaluation is only possible for simple calculators. Anything more complicated needs to convert the program into some data structure which can be executed or otherwise processed after the parse is finished.

    A common representation of a parsed program is an Abstract Syntax Tree (AST), which would be the output of the parser.