{"id":60553,"date":"2025-01-31T16:09:58","date_gmt":"2025-01-31T15:09:58","guid":{"rendered":"https:\/\/www.inovex.de\/?p=60553"},"modified":"2025-06-18T13:46:33","modified_gmt":"2025-06-18T11:46:33","slug":"building-a-simple-calculator-with-antlr-in-python","status":"publish","type":"post","link":"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/","title":{"rendered":"Building a simple calculator with ANTLR in Python"},"content":{"rendered":"<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Domain-specific_language\">Domain-specific languages (DSLs)<\/a> are individual computer languages designed to address specific problems within a particular domain, improving productivity and expressiveness. By providing a syntax and semantics that closely align with the needs of users in that domain, DSLs simplify complex tasks and improve code readability. They allow for more efficient communication between developers and domain experts, ultimately leading to better software solutions. To facilitate the creation of DSLs, tools like ANTLR (ANother Tool for Language Recognition) play a crucial role.<\/p>\n<p><a href=\"https:\/\/www.antlr.org\/\">ANTLR<\/a> is a powerful parser generator (i.e., a tool that supports you creating parsers) used for reading, processing, and executing structured text, binary text or binary files. It allows developers to define the grammar of a language and automatically generates code for parsing that language. ANTLR supports a variety of programming languages, including Java, JavaScript, C#, Python, and more, allowing developers to generate parsers in their language of choice.<\/p>\n<p>In this blog post, we will demonstrate how to build a simple calculator using ANTLR in the Python programming language, focusing on the listener and visitor design patterns.<!--more--><\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_79_2 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\"><p class=\"ez-toc-title\" style=\"cursor:inherit\"><\/p>\n<\/div><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#Motivation\" >Motivation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#Example-demo-Simple-calculator-using-listener-and-visitor\" >Example demo: Simple calculator using listener and visitor<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#ANTLR-and-Python-Setup\" >ANTLR and Python Setup<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#Grammar\" >Grammar<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#Lexer-and-parser\" >Lexer and parser<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#Parse-Tree\" >Parse Tree<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#Listener-and-visitor\" >Listener and visitor<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#Expression-evaluation-using-listener\" >Expression evaluation using listener<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#Expression-evaluation-using-visitor\" >Expression evaluation using visitor<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#Conclusion\" >Conclusion<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#References-and-useful-links\" >References and useful links<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Motivation\"><\/span>Motivation<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Using ANTLR to build a parser offers several significant advantages over writing a parser from scratch:<\/p>\n<ul>\n<li><strong>Ease of Use:<\/strong> ANTLR provides a high-level way to define grammars, allowing developers to focus on the language&#8217;s structure rather than the complexities of parsing algorithms.<\/li>\n<li><strong>Code Generation:<\/strong> ANTLR automatically generates the lexer and parser code from the specified grammar, saving time and reducing the potential for errors that can occur in manual implementations.<\/li>\n<li><strong>Robustness:<\/strong> ANTLR is designed to handle complex grammars and can manage ambiguities and errors easily, ensuring that your parser is both reliable and efficient.<\/li>\n<li><strong>Multi-Language Support:<\/strong> With support for various programming languages, ANTLR allows you to create parsers in the language that best suits your project needs.<\/li>\n<li><strong>Community and Documentation:<\/strong> ANTLR has a strong community and extensive documentation, making it easier to find resources and examples that can help you along the way.<\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Example-demo-Simple-calculator-using-listener-and-visitor\"><\/span>Example demo: Simple calculator using listener and visitor<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>In the following, we will demonstrate the steps necessary to build a simple calculator using ANTLR in Python. You can find the demo code in the following <a href=\"https:\/\/github.com\/inovex\/blog-antlr\">Git Repository<\/a>.<\/p>\n<p>During the demonstration of the steps, we will also explain key concepts of ANTLR like <strong>grammar<\/strong>, <strong>lexer<\/strong>, and <strong>parser<\/strong>, which are responsible for defining the language structure, breaking the input text into tokens, and organizing the tokens into a parse tree. Since we are implementing the calculator by following the ANTLR <a href=\"https:\/\/tomassetti.me\/listeners-and-visitors\/\">listener and visitor patterns<\/a> which are design approaches for processing the parse tree generated by a grammar, we will also explain in a later section the concepts behind <strong>listeners<\/strong> and <strong>visitors<\/strong> (and the steps necessary to realize the patterns).<\/p>\n<h3><span class=\"ez-toc-section\" id=\"ANTLR-and-Python-Setup\"><\/span>ANTLR and Python Setup<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>After cloning the project code from the repository, you can just follow the instructions in the <a href=\"https:\/\/github.com\/inovex\/blog-antlr\">README<\/a> file of the project to set up ANTLR and the Python environment. The only requirements for the setup are that Python3 and Java are installed on your machine.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Grammar\"><\/span>Grammar<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Grammar defines the rules and structure of a language. In ANTLR, you specify the syntax of the language you want to parse using a formal grammar notation. The ANTLR grammar shares some foundational concepts with the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Backus%E2%80%93Naur_form\">Backus-Naur Form (BNF)<\/a> which is a notation for context-free grammars to describe the syntax of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Domain-specific_language\">Domain-Specific Languages (DSL)<\/a>. But the ANTLR grammar has a more expressive and user-friendly syntax, allowing for a clearer definition of tokens (the smallest unit of meaning, also called lexer rules) and parser rules (in contrast, BNF typically does not distinguish between lexical and syntactic elements).<\/p>\n<p>The rules are defined in a g4 file, with the name of the grammar at the beginning, followed by parser rules defined in lowercase letters, followed by lexer rules (tokens) at the end, defined in uppercase letters.<\/p>\n<p>Below you can see the calculator grammar derived and simplified from the following <a href=\"https:\/\/github.com\/antlr\/grammars-v4\/blob\/master\/calculator\/calculator.g4\">grammar<\/a>.<\/p>\n<p>The grammar consists of a single parser rule called expression, which describes how expressions can be formed:<\/p>\n<ol>\n<li>An expression can be a single NUMBER.<\/li>\n<li>An expression can be wrapped in parentheses, allowing for the grouping of expressions.<\/li>\n<li>An expression can be formed by multiplying two sub-expressions.<\/li>\n<li>An expression can be formed by dividing one sub-expression by another.<\/li>\n<li>An expression can be formed by adding two sub-expressions.<\/li>\n<li>An expression can be formed by subtracting one sub-expression from another.<\/li>\n<\/ol>\n<p>The grammar also defines several tokens that are used in the expressions:<\/p>\n<ul>\n<li>Operators:\n<ul>\n<li><strong>PLUS:<\/strong> Represents the addition operator (+).<\/li>\n<li><strong>MINUS:<\/strong> Represents the subtraction operator (-).<\/li>\n<li><strong>TIMES:<\/strong> Represents the multiplication operator (*).<\/li>\n<li><strong>DIV:<\/strong> Represents the division operator (\/).<\/li>\n<\/ul>\n<\/li>\n<li>Number:\n<ul>\n<li><strong>NUMBER:<\/strong> Represents a sequence of digits (one or more digits)<\/li>\n<\/ul>\n<\/li>\n<li>Whitespace:\n<ul>\n<li><strong>WS:<\/strong> Matches whitespace characters (spaces, newlines, tabs) and is skipped during parsing.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre class=\"decode:true\" title=\"Calculator.g4\">grammar Calculator;\r\n\r\nexpression \r\n\t: NUMBER\t\t\t\t\t\t# Number\r\n\t| '(' expression ')'\t\t\t# Parentheses\r\n\t| expression TIMES expression\t# Multiplication\r\n\t| expression DIV expression\t\t# Division\r\n\t| expression PLUS expression\t# Addition\r\n\t| expression MINUS expression\t# Subtraction\r\n;\r\n\r\nPLUS : '+';\r\nMINUS: '-';\r\nTIMES: '*';\r\nDIV  : '\/';\r\nNUMBER : [0-9]+;\r\nWS : [ \\r\\n\\t]+ -&gt; skip;\r\n<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"Lexer-and-parser\"><\/span>Lexer and parser<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Using the defined grammar file, you can create lexer and parser classes, with ANTLR using the following command. The command will also generate listener and visitor classes which we will use later for the evaluation of the expressions.<\/p>\n<p>As you can see in the command below, we are specifying the language as Python to create the classes in the Python programming language. It is also necessary to pass the visitor argument, since the default execution without the argument does not generate the visitor class automatically. Finally, we also need to specify the grammar file to be considered during the generation of the classes.<\/p>\n<p>All the generated classes have the prefix with the name of the grammar (<em>Calculator*<\/em>).<\/p>\n<pre class=\"decode:true\" title=\"Generating lexer, parser, listener, and visitor classes\">antlr4 -Dlanguage=Python3 -visitor antlr\/Calculator.g4\r\n<\/pre>\n<p>The <strong>lexer<\/strong>, or lexical analyzer, is responsible for breaking the input text into a stream of tokens based on the grammar rules. It identifies keywords, operators, identifiers, and other relevant symbols, allowing the parser to understand the input at a higher level.<\/p>\n<p>The <strong>parser<\/strong> takes the stream of tokens produced by the lexer and organizes them into a <strong>parse tree<\/strong> according to the grammar rules. This structure represents the hierarchical relationships between the tokens and is essential for evaluating expressions or executing commands.<\/p>\n<p>You can see in the image below an example of how the lexer breaks the input text into tokens and how the parser organizes them into a parse tree.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-60578 size-full\" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/antlr_lexer_parser.png\" alt=\"\" width=\"772\" height=\"160\" srcset=\"https:\/\/www.inovex.de\/wp-content\/uploads\/antlr_lexer_parser.png 772w, https:\/\/www.inovex.de\/wp-content\/uploads\/antlr_lexer_parser-300x62.png 300w, https:\/\/www.inovex.de\/wp-content\/uploads\/antlr_lexer_parser-768x160.png 768w, https:\/\/www.inovex.de\/wp-content\/uploads\/antlr_lexer_parser-400x83.png 400w, https:\/\/www.inovex.de\/wp-content\/uploads\/antlr_lexer_parser-360x75.png 360w\" sizes=\"auto, (max-width: 772px) 100vw, 772px\" \/><\/p>\n<h3><span class=\"ez-toc-section\" id=\"Parse-Tree\"><\/span>Parse Tree<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>In ANTLR, you can also visualize the parse tree for an input text.<\/p>\n<p>To visualize the parse tree, we are using the Python library <a href=\"https:\/\/github.com\/antlr\/antlr4-tools\">antlr4-tools<\/a>. After installing the library using pip, the parse tree can be visualized with the following command. Here, as an example, the expression 3+5*(2-8) was considered.<\/p>\n<pre class=\"decode:true\">antlr4-parse antlr\/Calculator.g4 expression -gui\r\n3+5*(2-8)\r\n<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-60580 size-full\" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/antlr4_parse_tree.png\" alt=\"\" width=\"444\" height=\"297\" srcset=\"https:\/\/www.inovex.de\/wp-content\/uploads\/antlr4_parse_tree.png 444w, https:\/\/www.inovex.de\/wp-content\/uploads\/antlr4_parse_tree-300x201.png 300w, https:\/\/www.inovex.de\/wp-content\/uploads\/antlr4_parse_tree-400x268.png 400w, https:\/\/www.inovex.de\/wp-content\/uploads\/antlr4_parse_tree-360x241.png 360w\" sizes=\"auto, (max-width: 444px) 100vw, 444px\" \/><\/p>\n<h3><span class=\"ez-toc-section\" id=\"Listener-and-visitor\"><\/span>Listener and visitor<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>In ANTLR, there are two primary methods for handling the results of parsing: listeners and visitors. Both approaches facilitate the traversal of the parse tree generated from the input, but they serve different purposes and offer distinct functionalities.<\/p>\n<p><strong>Why use listeners and visitors?<\/strong><\/p>\n<p>As shown previously, when you successfully parse an input, the result is a parse tree that starts with a root node and branches out to multiple child nodes. Each node in the tree has a single parent, except for the root node, which has none. Traversing this tree can be accomplished using a depth-first search approach:<\/p>\n<ol>\n<li>Start with the root node as your current node.<\/li>\n<li>If the node has no children, backtrack to the parent node.<\/li>\n<li>If there are unvisited child nodes, select the first one and repeat the process.<\/li>\n<\/ol>\n<p>While this traversal method is straightforward, ANTLR simplifies the process by automatically generating listeners and visitors for you.<\/p>\n<p><strong>Similarities between listeners and visitors:<\/strong><\/p>\n<ul>\n<li>Both utilize a depth-first traversal algorithm.<\/li>\n<li>They provide a standardized way to process a parse tree, eliminating the need to devise your own traversal strategy.<\/li>\n<li>By offering a consistent approach, listeners and visitors enhance the reusability of your grammar across different programs and languages. You can apply the same grammar to various listeners and visitors to address different problems, even in different programming languages.<\/li>\n<li>This standardization saves time and ensures that anyone working with the parse tree can easily understand and utilize the provided methods.<\/li>\n<\/ul>\n<p><strong>Differences between listeners and visitors:<\/strong><\/p>\n<p>While both listeners and visitors serve the purpose of traversing the parse tree, they differ in functionality:<\/p>\n<p><strong>Listeners:<\/strong><\/p>\n<ul>\n<li>Automatically invoke functions when the walker encounters a node in the tree.<\/li>\n<li>Do not allow for control over the traversal process; the order of traversal is predefined.<\/li>\n<li>Recommended when you do not need to alter the structure of the parse tree to achieve your goals. They are ideal for scenarios where the output can be generated without modifying the tree.<\/li>\n<\/ul>\n<p><strong>Visitors:<\/strong><\/p>\n<ul>\n<li>Provide more control over the traversal process, allowing you to dictate the order and manner in which nodes are visited.<\/li>\n<li>Enable the return of values from each visitor function, which can be useful for extracting information or performing calculations based on multiple nodes.<\/li>\n<li>Best suited for situations where you need to return results from each node or require more complex interactions with the parse tree.<\/li>\n<\/ul>\n<p>By understanding the roles of listeners and visitors, you can choose the appropriate method based on your specific needs when working with ANTLR-generated parse trees.<\/p>\n<p>In the following sections, we will compare listeners and visitors by implementing a calculator using both approaches.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Expression-evaluation-using-listener\"><\/span>Expression evaluation using listener<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>As shown in the code below, the provided listeners class from ANTLR contains a pair of <em>enter<\/em>\/<em>exit<\/em> methods for each parser rule. Thus, a listener includes <em>enter<\/em> and <em>exit<\/em> methods that will be executed when the listener enters and exits a node, respectively. These methods accept as arguments the same <em>Context<\/em> object. For example, <em>enterMultiplication<\/em> and <em>exitMultiplication<\/em> methods both accept a <em>MultiplicationContext<\/em> object as an argument.<\/p>\n<pre class=\"lang:python decode:true\" title=\"CalculatorListener.py\"># Generated from antlr\/Calculator.g4 by ANTLR 4.13.1\r\nfrom antlr4 import *\r\nif \".\" in __name__:\r\n    from .CalculatorParser import CalculatorParser\r\nelse:\r\n    from CalculatorParser import CalculatorParser\r\n\r\n# This class defines a complete listener for a parse tree produced by CalculatorParser.\r\nclass CalculatorListener(ParseTreeListener):\r\n\r\n    # Enter a parse tree produced by CalculatorParser#Multiplication.\r\n    def enterMultiplication(self, ctx:CalculatorParser.MultiplicationContext):\r\n        pass\r\n\r\n    # Exit a parse tree produced by CalculatorParser#Multiplication.\r\n    def exitMultiplication(self, ctx:CalculatorParser.MultiplicationContext):\r\n        pass\r\n\r\n    # Enter a parse tree produced by CalculatorParser#Addition.\r\n    def enterAddition(self, ctx:CalculatorParser.AdditionContext):\r\n        pass\r\n\r\n    # Exit a parse tree produced by CalculatorParser#Addition.\r\n    def exitAddition(self, ctx:CalculatorParser.AdditionContext):\r\n        pass\r\n\r\n    # Enter a parse tree produced by CalculatorParser#Subtraction.\r\n    def enterSubtraction(self, ctx:CalculatorParser.SubtractionContext):\r\n        pass\r\n\r\n    # Exit a parse tree produced by CalculatorParser#Subtraction.\r\n    def exitSubtraction(self, ctx:CalculatorParser.SubtractionContext):\r\n        pass\r\n\r\n    # Enter a parse tree produced by CalculatorParser#Number.\r\n    def enterNumber(self, ctx:CalculatorParser.NumberContext):\r\n        pass\r\n\r\n    # Exit a parse tree produced by CalculatorParser#Number.\r\n    def exitNumber(self, ctx:CalculatorParser.NumberContext):\r\n        pass\r\n\r\n    # Enter a parse tree produced by CalculatorParser#Division.\r\n    def enterDivision(self, ctx:CalculatorParser.DivisionContext):\r\n        pass\r\n\r\n    # Exit a parse tree produced by CalculatorParser#Division.\r\n    def exitDivision(self, ctx:CalculatorParser.DivisionContext):\r\n        pass\r\n\r\n    # Enter a parse tree produced by CalculatorParser#Parentheses.\r\n    def enterParentheses(self, ctx:CalculatorParser.ParenthesesContext):\r\n        pass\r\n\r\n    # Exit a parse tree produced by CalculatorParser#Parentheses.\r\n    def exitParentheses(self, ctx:CalculatorParser.ParenthesesContext):\r\n        pass\r\n\r\ndel CalculatorParser\r\n<\/pre>\n<p>To realize the calculation evaluation of an expression with a listener, it is first necessary to create a class which extends the default listener class.<\/p>\n<p>As represented in the code below, we are naming the extended class <em>EvaluationListener<\/em>. In the extended class, first a stack list is considered for storing and extracting the results for each step.<\/p>\n<p>Then, we are overwriting the <em>exit<\/em> methods provided by the default listener class as follows:<\/p>\n<ul>\n<li>If a number node is exited, then the number context is appended to the stack.<\/li>\n<li>For the multiplication\/division\/addition\/substraction, first the right and left expressions are extracted from the stack. Then the expressions are multiplicated\/divided\/added\/subtracted together, and the result is appended to the stack.<\/li>\n<\/ul>\n<p>The <em>EvaluationListener<\/em> class also implements its own method (<em>getResult<\/em>) to extract the final evaluation result from the stack.<\/p>\n<pre class=\"lang:python decode:true\" title=\"EvaluationListener.py\">from antlr.CalculatorLexer import CalculatorLexer\r\nfrom antlr.CalculatorParser import CalculatorParser\r\nfrom antlr.CalculatorListener import CalculatorListener\r\nfrom antlr4 import *\r\n\r\nclass EvaluationListener(CalculatorListener):\r\n    def __init__(self):\r\n        self.stack = []\r\n\r\n    def exitNumber(self, ctx: CalculatorParser.NumberContext):\r\n        # Push the number onto the stack\r\n        number = int(ctx.getText())\r\n        self.stack.append(number)\r\n\r\n    def exitParentheses(self, ctx: CalculatorParser.ParenthesesContext):\r\n        # Evaluate the expression inside the parentheses\r\n        pass  # No action needed; the result will be handled in the parent operation\r\n\r\n    def exitMultiplication(self, ctx: CalculatorParser.MultiplicationContext):\r\n        right = self.stack.pop()\r\n        left = self.stack.pop()\r\n        result = left * right\r\n        self.stack.append(result)\r\n\r\n    def exitDivision(self, ctx: CalculatorParser.DivisionContext):\r\n        right = self.stack.pop()\r\n        left = self.stack.pop()\r\n        result = left \/ right\r\n        self.stack.append(result)\r\n\r\n    def exitAddition(self, ctx: CalculatorParser.AdditionContext):\r\n        right = self.stack.pop()\r\n        left = self.stack.pop()\r\n        result = left + right\r\n        self.stack.append(result)\r\n\r\n    def exitSubtraction(self, ctx: CalculatorParser.SubtractionContext):\r\n        right = self.stack.pop()\r\n        left = self.stack.pop()\r\n        result = left - right\r\n        self.stack.append(result)\r\n\r\n    def getResult(self):\r\n        # The final result will be the last item on the stack\r\n        return self.stack.pop() if self.stack else None\r\n<\/pre>\n<p>Now, to use the implemented <em>EvaluationListener<\/em>, the following scripts can be executed.<\/p>\n<p>For the execution of the script, an expression needs to be passed. Using the passed expression, first, a parse tree object is generated (by parsing the expression into an input stream, creating a <em>CalculatorLexer<\/em> object from the input stream, creating a <em>CommonTokenStream<\/em> object from the lexer object, creating a <em>CalculatorParser<\/em> object from the token stream, and generating a parse tree from the parser).<\/p>\n<p>Then, an object for the implemented listener needs to be created. After that, a walker object can be created using the <em>ParseTreeWalker<\/em> class from the antlr4 library.<\/p>\n<p>We can use the walker to traverse the parse tree with the implemented listener using the <em>walk<\/em> method. Finally, we can get from the listener the evaluation result and print the result for the user.<\/p>\n<pre class=\"lang:python decode:true\" title=\"calculate_with_listener.py\">import sys\r\nfrom antlr4 import *\r\nfrom antlr.CalculatorLexer import CalculatorLexer\r\nfrom antlr.CalculatorParser import CalculatorParser\r\nfrom custom.EvaluationListener import EvaluationListener\r\n\r\ndef main(argv):\r\n    input_expr = \"\".join(argv)\r\n    input_stream = InputStream(input_expr)\r\n    \r\n    lexer = CalculatorLexer(input_stream)\r\n    stream = CommonTokenStream(lexer)\r\n    parser = CalculatorParser(stream)\r\n    \r\n    # Start parsing at the 'expression' rule\r\n    tree = parser.expression()\r\n    \r\n    # Create a listener and walk the tree\r\n    listener = EvaluationListener()\r\n    walker = ParseTreeWalker()\r\n    walker.walk(listener, tree)\r\n    \r\n    # Get the result from the listener\r\n    result = listener.getResult()\r\n    \r\n    print(f\"The result of '{input_expr}' is: {result}\")\r\n\r\nif __name__ == \"__main__\":\r\n    if len(sys.argv) &lt; 2:\r\n        print(\"Usage: python calculate_with_listener.py \")\r\n        sys.exit(1)\r\n    main(sys.argv[1:])\r\n<\/pre>\n<p>Below, you can see an example for the execution of the script with the expression: 3+5*(2-8).<\/p>\n<p>The script evaluates the expression with the implemented listener and prints the correct calculation result.<\/p>\n<pre class=\"decode:true\">$ python3 calculate_with_listener.py\r\nThe result of '3+5*(2-8)' is: -27\r\n<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"Expression-evaluation-using-visitor\"><\/span>Expression evaluation using visitor<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>In the code below, you can see the default visitor class generated by ANTLR using the defined calculator grammar file. The visitor class contains, in contrast to the listener class, only one visit method for each node. The input arguments for the methods are similarly structured as the listener methods.<\/p>\n<pre class=\"lang:python decode:true\" title=\"CalculatorVisitor.py\"># Generated from antlr\/Calculator.g4 by ANTLR 4.13.1\r\nfrom antlr4 import *\r\nif \".\" in __name__:\r\n    from .CalculatorParser import CalculatorParser\r\nelse:\r\n    from CalculatorParser import CalculatorParser\r\n\r\n# This class defines a complete generic visitor for a parse tree produced by CalculatorParser.\r\n\r\nclass CalculatorVisitor(ParseTreeVisitor):\r\n\r\n    # Visit a parse tree produced by CalculatorParser#Multiplication.\r\n    def visitMultiplication(self, ctx:CalculatorParser.MultiplicationContext):\r\n        return self.visitChildren(ctx)\r\n\r\n    # Visit a parse tree produced by CalculatorParser#Addition.\r\n    def visitAddition(self, ctx:CalculatorParser.AdditionContext):\r\n        return self.visitChildren(ctx)\r\n\r\n    # Visit a parse tree produced by CalculatorParser#Subtraction.\r\n    def visitSubtraction(self, ctx:CalculatorParser.SubtractionContext):\r\n        return self.visitChildren(ctx)\r\n\r\n    # Visit a parse tree produced by CalculatorParser#Number.\r\n    def visitNumber(self, ctx:CalculatorParser.NumberContext):\r\n        return self.visitChildren(ctx)\r\n\r\n    # Visit a parse tree produced by CalculatorParser#Division.\r\n    def visitDivision(self, ctx:CalculatorParser.DivisionContext):\r\n        return self.visitChildren(ctx)\r\n\r\n    # Visit a parse tree produced by CalculatorParser#Parentheses.\r\n    def visitParentheses(self, ctx:CalculatorParser.ParenthesesContext):\r\n        return self.visitChildren(ctx)\r\n\r\ndel CalculatorParser\r\n<\/pre>\n<p>Now, to realize the calculations function with the visitor class, we first need to create a class which extends the default visitor class, similarly to the approach with the listener.<\/p>\n<p>Then, we can again overwrite the methods like we did in the listener approach. But the difference here is that it is not necessary to provide a stack list and an additional method to return the final result. As mentioned in the previous section, with visitors, it is possible to define the return value for each <em>visit<\/em> method.<\/p>\n<p>In the extended visitor class, we are overwriting the <em>visit<\/em> methods as follows:<\/p>\n<ul>\n<li>If the number node is visited, just return the number context at the end of the method.<\/li>\n<li>If the parentheses node is visited, just return the expression of the input context to evaluate the expression inside the parentheses. By calling the <em>self.visit<\/em> method of the <em>ParseTreeVisitor<\/em> class (which is the parent class of the <em>CalculatorVisitor<\/em> class), the expression can be evaluated recursively (here the expression inside the parentheses can be evaluated).<\/li>\n<li>For multiplication\/division\/addition\/subtraction, first extract the evaluation result of each of the left and right expressions by calling again the <em>visit<\/em> method of the <em>ParseTreeVisitor<\/em> class on the left and right expressions, respectively. After extracting the left and right evaluation results, these can be multiplied\/divided\/added\/subtracted together and can be returned as the result of the <em>visit<\/em> method.<\/li>\n<\/ul>\n<pre class=\"lang:python decode:true\" title=\"EvaluationVisitor.py\">from antlr.CalculatorLexer import CalculatorLexer\r\nfrom antlr.CalculatorParser import CalculatorParser\r\nfrom antlr.CalculatorVisitor import CalculatorVisitor\r\nfrom antlr4 import *\r\n\r\nclass EvaluationVisitor(CalculatorVisitor):\r\n    def visitNumber(self, ctx: CalculatorParser.NumberContext):\r\n        # Convert the NUMBER token to an integer\r\n        return int(ctx.getText())\r\n\r\n    def visitParentheses(self, ctx: CalculatorParser.ParenthesesContext):\r\n        # Evaluate the expression inside the parentheses\r\n        return self.visit(ctx.expression())\r\n\r\n    def visitMultiplication(self, ctx: CalculatorParser.MultiplicationContext):\r\n        # Evaluate left and right expressions and multiply them\r\n        left = self.visit(ctx.expression(0))\r\n        right = self.visit(ctx.expression(1))\r\n        return left * right\r\n\r\n    def visitDivision(self, ctx: CalculatorParser.DivisionContext):\r\n        # Evaluate left and right expressions and divide them\r\n        left = self.visit(ctx.expression(0))\r\n        right = self.visit(ctx.expression(1))\r\n        return left \/ right\r\n\r\n    def visitAddition(self, ctx: CalculatorParser.AdditionContext):\r\n        # Evaluate left and right expressions and add them\r\n        left = self.visit(ctx.expression(0))\r\n        right = self.visit(ctx.expression(1))\r\n        return left + right\r\n\r\n    def visitSubtraction(self, ctx: CalculatorParser.SubtractionContext):\r\n        # Evaluate left and right expressions and subtract them\r\n        left = self.visit(ctx.expression(0))\r\n        right = self.visit(ctx.expression(1))\r\n        return left - right\r\n<\/pre>\n<p>Now, to execute the calculation with the implemented <em>EvaluationVisitor<\/em> class, the following scripts can be used.<\/p>\n<p>Similarly to the script for the listener, an expression needs to be passed. The steps for generating a parse tree are again similar to the script for the listener approach. But for the visitor approach, it is not necessary to use a walker object to get the final evaluation result of the input expression. Instead, the <em>visit<\/em> method of the <em>EvaluationVisitor<\/em> object can be executed directly on the tree to get the final calculation result.<\/p>\n<pre class=\"lang:python decode:true\" title=\"calculate_with_visitor.py\">import sys\r\nfrom antlr4 import *\r\nfrom antlr.CalculatorLexer import CalculatorLexer\r\nfrom antlr.CalculatorParser import CalculatorParser\r\nfrom custom.EvaluationVisitor import EvaluationVisitor\r\n\r\ndef main(argv):\r\n    input_expr = \"\".join(argv)\r\n    input_stream = InputStream(input_expr)\r\n    \r\n    lexer = CalculatorLexer(input_stream)\r\n    stream = CommonTokenStream(lexer)\r\n    parser = CalculatorParser(stream)\r\n    \r\n    # Start parsing at the 'expression' rule\r\n    tree = parser.expression()\r\n    \r\n    # Create a visitor and evaluate the expression\r\n    evaluator = EvaluationVisitor()\r\n    result = evaluator.visit(tree)\r\n    \r\n    print(f\"The result of '{input_expr}' is: {result}\")\r\n\r\nif __name__ == \"__main__\":\r\n    if len(sys.argv) &lt; 2:\r\n        print(\"Usage: python calculate_with_visitor.py \")\r\n        sys.exit(1)\r\n    main(sys.argv[1:])\r\n\r\n<\/pre>\n<p>Below, you can see an example for the execution of the script with the expression: 3+5*(2-8).<\/p>\n<p>The script evaluates the expression using the implemented visitor and prints the correct calculation result.<\/p>\n<pre class=\"decode:true\">$ python3 calculate_with_visitor.py\r\nThe result of '3+5*(2-8)' is: -27\r\n<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>In this blog post, we demonstrated the most important concepts behind ANTLR by presenting the implementation of a simple calculator in Python. ANTLR allows the developer to specify the syntax of a language you want to parse using a formal grammar notation, and for the evaluation of the input expression, listener and visitor classes provided by ANTLR can be used. Listeners and visitors provide a standard way to traverse the parse tree and developers can select one of the approaches by considering the differences between these concepts.<\/p>\n<p>For simplicity, we considered the calculator example in this blog post, but with ANTLR you can also easily implement other use cases, like compiler creation, custom domain-specific languages, or data transformation.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"References-and-useful-links\"><\/span>References and useful links<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<ul>\n<li><a href=\"https:\/\/tomassetti.me\/antlr-mega-tutorial\/\">The ANTLR Mega Tutorial<\/a><\/li>\n<li><a href=\"https:\/\/tomassetti.me\/listeners-and-visitors\/\">Listeners And Visitors<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Domain-specific languages (DSLs) are individual computer languages designed to address specific problems within a particular domain, improving productivity and expressiveness. By providing a syntax and semantics that closely align with the needs of users in that domain, DSLs simplify complex tasks and improve code readability. They allow for more efficient communication between developers and domain [&hellip;]<\/p>\n","protected":false},"author":422,"featured_media":60628,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"ep_exclude_from_search":false,"footnotes":""},"tags":[],"service":[420,425],"coauthors":[{"id":422,"display_name":"Hiroshi Hamano","user_nicename":"hhamano"},{"id":302,"display_name":"Marvin Klossek","user_nicename":"mklossek"},{"id":52,"display_name":"Florian Wilhelm","user_nicename":"fwilhelm"}],"class_list":["post-60553","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","service-apps","service-backend"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Building a simple calculator with ANTLR in Python - inovex GmbH<\/title>\n<meta name=\"description\" content=\"This blog post demonstrates how to build a simple calculator using ANTLR in the Python programming language.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building a simple calculator with ANTLR in Python - inovex GmbH\" \/>\n<meta property=\"og:description\" content=\"This blog post demonstrates how to build a simple calculator using ANTLR in the Python programming language.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/\" \/>\n<meta property=\"og:site_name\" content=\"inovex GmbH\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/inovexde\" \/>\n<meta property=\"article:published_time\" content=\"2025-01-31T15:09:58+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-18T11:46:33+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.inovex.de\/wp-content\/uploads\/Building-a-simple-calculator-with-ANTLR-in-Python.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1500\" \/>\n\t<meta property=\"og:image:height\" content=\"880\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Hiroshi Hamano, Marvin Klossek, Florian Wilhelm\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.inovex.de\/wp-content\/uploads\/Building-a-simple-calculator-with-ANTLR-in-Python-1024x601.png\" \/>\n<meta name=\"twitter:creator\" content=\"@inovexgmbh\" \/>\n<meta name=\"twitter:site\" content=\"@inovexgmbh\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Hiroshi Hamano\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"17\u00a0Minuten\" \/>\n\t<meta name=\"twitter:label3\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data3\" content=\"Hiroshi Hamano, Marvin Klossek, Florian Wilhelm\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/\"},\"author\":{\"name\":\"Hiroshi Hamano\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/person\/b0921cc978dcada26aa16b69ce672c02\"},\"headline\":\"Building a simple calculator with ANTLR in Python\",\"datePublished\":\"2025-01-31T15:09:58+00:00\",\"dateModified\":\"2025-06-18T11:46:33+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/\"},\"wordCount\":2429,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/Building-a-simple-calculator-with-ANTLR-in-Python.png\",\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/\",\"url\":\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/\",\"name\":\"Building a simple calculator with ANTLR in Python - inovex GmbH\",\"isPartOf\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/Building-a-simple-calculator-with-ANTLR-in-Python.png\",\"datePublished\":\"2025-01-31T15:09:58+00:00\",\"dateModified\":\"2025-06-18T11:46:33+00:00\",\"description\":\"This blog post demonstrates how to build a simple calculator using ANTLR in the Python programming language.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#primaryimage\",\"url\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/Building-a-simple-calculator-with-ANTLR-in-Python.png\",\"contentUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/Building-a-simple-calculator-with-ANTLR-in-Python.png\",\"width\":1500,\"height\":880,\"caption\":\"Graphic: Woman sitting at desk with a computer typing in a calculator.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.inovex.de\/de\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Building a simple calculator with ANTLR in Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.inovex.de\/de\/#website\",\"url\":\"https:\/\/www.inovex.de\/de\/\",\"name\":\"inovex GmbH\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.inovex.de\/de\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.inovex.de\/de\/#organization\",\"name\":\"inovex GmbH\",\"url\":\"https:\/\/www.inovex.de\/de\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png\",\"contentUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png\",\"width\":1921,\"height\":1081,\"caption\":\"inovex GmbH\"},\"image\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/inovexde\",\"https:\/\/x.com\/inovexgmbh\",\"https:\/\/www.instagram.com\/inovexlife\/\",\"https:\/\/www.linkedin.com\/company\/inovex\",\"https:\/\/www.youtube.com\/channel\/UC7r66GT14hROB_RQsQBAQUQ\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/person\/b0921cc978dcada26aa16b69ce672c02\",\"name\":\"Hiroshi Hamano\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/person\/image\/70b3a60f7894026d95e6f14cd72b737d\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/cbb1895c495a1f191aa5803cf2f821975c8b7f369afa3c4409f2c507befca32b?s=96&d=retro&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/cbb1895c495a1f191aa5803cf2f821975c8b7f369afa3c4409f2c507befca32b?s=96&d=retro&r=g\",\"caption\":\"Hiroshi Hamano\"},\"url\":\"https:\/\/www.inovex.de\/de\/blog\/author\/hhamano\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Building a simple calculator with ANTLR in Python - inovex GmbH","description":"This blog post demonstrates how to build a simple calculator using ANTLR in the Python programming language.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/","og_locale":"de_DE","og_type":"article","og_title":"Building a simple calculator with ANTLR in Python - inovex GmbH","og_description":"This blog post demonstrates how to build a simple calculator using ANTLR in the Python programming language.","og_url":"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/","og_site_name":"inovex GmbH","article_publisher":"https:\/\/www.facebook.com\/inovexde","article_published_time":"2025-01-31T15:09:58+00:00","article_modified_time":"2025-06-18T11:46:33+00:00","og_image":[{"width":1500,"height":880,"url":"https:\/\/www.inovex.de\/wp-content\/uploads\/Building-a-simple-calculator-with-ANTLR-in-Python.png","type":"image\/png"}],"author":"Hiroshi Hamano, Marvin Klossek, Florian Wilhelm","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.inovex.de\/wp-content\/uploads\/Building-a-simple-calculator-with-ANTLR-in-Python-1024x601.png","twitter_creator":"@inovexgmbh","twitter_site":"@inovexgmbh","twitter_misc":{"Verfasst von":"Hiroshi Hamano","Gesch\u00e4tzte Lesezeit":"17\u00a0Minuten","Written by":"Hiroshi Hamano, Marvin Klossek, Florian Wilhelm"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#article","isPartOf":{"@id":"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/"},"author":{"name":"Hiroshi Hamano","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/b0921cc978dcada26aa16b69ce672c02"},"headline":"Building a simple calculator with ANTLR in Python","datePublished":"2025-01-31T15:09:58+00:00","dateModified":"2025-06-18T11:46:33+00:00","mainEntityOfPage":{"@id":"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/"},"wordCount":2429,"commentCount":0,"publisher":{"@id":"https:\/\/www.inovex.de\/de\/#organization"},"image":{"@id":"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#primaryimage"},"thumbnailUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/Building-a-simple-calculator-with-ANTLR-in-Python.png","inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/","url":"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/","name":"Building a simple calculator with ANTLR in Python - inovex GmbH","isPartOf":{"@id":"https:\/\/www.inovex.de\/de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#primaryimage"},"image":{"@id":"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#primaryimage"},"thumbnailUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/Building-a-simple-calculator-with-ANTLR-in-Python.png","datePublished":"2025-01-31T15:09:58+00:00","dateModified":"2025-06-18T11:46:33+00:00","description":"This blog post demonstrates how to build a simple calculator using ANTLR in the Python programming language.","breadcrumb":{"@id":"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#primaryimage","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/Building-a-simple-calculator-with-ANTLR-in-Python.png","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/Building-a-simple-calculator-with-ANTLR-in-Python.png","width":1500,"height":880,"caption":"Graphic: Woman sitting at desk with a computer typing in a calculator."},{"@type":"BreadcrumbList","@id":"https:\/\/www.inovex.de\/de\/blog\/building-a-simple-calculator-with-antlr-in-python\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.inovex.de\/de\/"},{"@type":"ListItem","position":2,"name":"Building a simple calculator with ANTLR in Python"}]},{"@type":"WebSite","@id":"https:\/\/www.inovex.de\/de\/#website","url":"https:\/\/www.inovex.de\/de\/","name":"inovex GmbH","description":"","publisher":{"@id":"https:\/\/www.inovex.de\/de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.inovex.de\/de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/www.inovex.de\/de\/#organization","name":"inovex GmbH","url":"https:\/\/www.inovex.de\/de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png","width":1921,"height":1081,"caption":"inovex GmbH"},"image":{"@id":"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/inovexde","https:\/\/x.com\/inovexgmbh","https:\/\/www.instagram.com\/inovexlife\/","https:\/\/www.linkedin.com\/company\/inovex","https:\/\/www.youtube.com\/channel\/UC7r66GT14hROB_RQsQBAQUQ"]},{"@type":"Person","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/b0921cc978dcada26aa16b69ce672c02","name":"Hiroshi Hamano","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/image\/70b3a60f7894026d95e6f14cd72b737d","url":"https:\/\/secure.gravatar.com\/avatar\/cbb1895c495a1f191aa5803cf2f821975c8b7f369afa3c4409f2c507befca32b?s=96&d=retro&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cbb1895c495a1f191aa5803cf2f821975c8b7f369afa3c4409f2c507befca32b?s=96&d=retro&r=g","caption":"Hiroshi Hamano"},"url":"https:\/\/www.inovex.de\/de\/blog\/author\/hhamano\/"}]}},"_links":{"self":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/60553","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/users\/422"}],"replies":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/comments?post=60553"}],"version-history":[{"count":5,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/60553\/revisions"}],"predecessor-version":[{"id":62650,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/60553\/revisions\/62650"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/media\/60628"}],"wp:attachment":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/media?parent=60553"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/tags?post=60553"},{"taxonomy":"service","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/service?post=60553"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/coauthors?post=60553"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}