Build a Simple Arithmetic Interpreter in Python Using PLY

This article walks through creating a Python arithmetic interpreter with the PLY library, covering token definitions, lexer rules, BNF grammar, parser implementation, operator precedence, and a runnable REPL, providing complete code and explanations for each step.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Build a Simple Arithmetic Interpreter in Python Using PLY

Computers only understand machine code; programming languages are textual abstractions that let humans describe tasks for computers, while compilers and interpreters translate them into machine code. This article designs an interpreter that can evaluate arithmetic expressions.

We use the PLY (Python Lex‑Yacc) library, which can be installed via: $ pip install ply First, we define the set of tokens that the interpreter will recognize:

tokens = (
    "NUM",
    "FLOAT",
    "PLUS",
    "MINUS",
    "MUL",
    "DIV",
    "POW",
    "LPAREN",
    "RPAREN",
)

Next, we write regular expressions for each token and actions to convert matched text into Python values:

t_PLUS   = r"\+"
t_MINUS  = r"\-"
t_MUL    = r"\*"
t_DIV    = r"/"
t_LPAREN = r"\("
t_RPAREN = r"\)"
t_POW    = r"\^"

t_ignore = " \t"

def t_FLOAT(t):
    r"\d+\.\d+"
    t.value = float(t.value)
    return t

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

def t_error(t):
    print(f"keyword not found: {t.value[0]}
line {t.lineno}")
    t.lexer.skip(1)

def t_newline(t):
    r"
+"
    t.lexer.lineno += t.value.count("
")

We import the lexer with: import ply.lex as lex The lexer turns the input string into a stream of LexToken objects. Example usage:

data = 'a = 2 + (10 -8)/1.0'
lexer = lex.lex()
lexer.input(data)
while tok := lexer.token():
    print(tok)

For parsing, we use YACC (Yet Another Compiler Compiler) from PLY: import ply.yacc as yacc We define the operator list and the grammar rules in Backus‑Naur Form (BNF):

from operator import add, sub, mul, truediv, pow

ops = {
    "+": add,
    "-": sub,
    "*": mul,
    "/": truediv,
    "^": pow,
}

def p_expression(p):
    """expression : expression PLUS expression
                 | expression MINUS expression
                 | expression DIV expression
                 | expression MUL expression
                 | expression POW expression"""
    if (p[2], p[3]) == ("/", 0):
        p[0] = float("INF")
    else:
        p[0] = ops[p[2]](p[1], p[3])

def p_expression_uplus_or_expr(p):
    """expression : PLUS expression %prec UPLUS
                 | LPAREN expression RPAREN"""
    p[0] = p[2]

def p_expression_uminus(p):
    """expression : MINUS expression %prec UMINUS"""
    p[0] = -p[2]

def p_expression_num(p):
    """expression : NUM
                 | FLOAT"""
    p[0] = p[1]

def p_error(p):
    print(f"Syntax error in {p.value}")

Operator precedence and associativity are declared as:

precedence = (
    ("left", "PLUS", "MINUS"),
    ("left", "MUL", "DIV"),
    ("left", "POW"),
    ("right", "UPLUS", "UMINUS"),
)

Finally, the main program creates the lexer and parser, reads expressions from the console, parses them, and prints the result:

if __name__ == "__main__":
    lexer = lex.lex()
    parser = yacc.yacc()
    while True:
        try:
            result = parser.parse(input(">>> "), debug=getLogger())
            print(result)
        except AttributeError:
            print("invalid syntax")

The article concludes that, although the topic is extensive, the provided overview gives a solid foundation for building a simple arithmetic interpreter.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PythonparsingBNFinterpreterlexical analysisPLY
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.