{"id":3958,"date":"2024-02-26T13:44:33","date_gmt":"2024-02-26T12:44:33","guid":{"rendered":"https:\/\/oopm.org\/?page_id=3958"},"modified":"2024-11-29T13:58:11","modified_gmt":"2024-11-29T12:58:11","slug":"10-1-2-an-expression-parser","status":"publish","type":"page","link":"https:\/\/oopm.org\/?page_id=3958","title":{"rendered":"10.1.2 An expression parser"},"content":{"rendered":"<div class=\"pdfprnt-buttons pdfprnt-buttons-page pdfprnt-top-right\"><a href=\"https:\/\/oopm.org\/index.php?rest_route=wpv2pages3958&print=pdf\" class=\"pdfprnt-button pdfprnt-button-pdf\" target=\"_blank\"><img decoding=\"async\" src=\"https:\/\/oopm.org\/wp-content\/plugins\/pdf-print\/images\/pdf.png\" alt=\"image_pdf\" title=\"View PDF\" \/><\/a><a href=\"https:\/\/oopm.org\/index.php?rest_route=wpv2pages3958&print=print\" class=\"pdfprnt-button pdfprnt-button-print\" target=\"_blank\"><img decoding=\"async\" src=\"https:\/\/oopm.org\/wp-content\/plugins\/pdf-print\/images\/print.png\" alt=\"image_print\" title=\"Print Content\" \/><\/a><\/div>\n<p class=\"wp-block-paragraph\">In this section, we show how to write a parser for our simple expression grammar. The parser reads a string of characters and checks whether or not the string is a valid expression as described by the grammar.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We assume that the input string to the parser is in the String  <code>inn<\/code>. We define a method <code>nextChar<\/code> that assigns the next character in <code>inn<\/code> to the variable <code>ch<\/code>, but skipping all blank characters. The variable <code>pos<\/code> keeps track of the current position in <code>inn<\/code>. When the end of <code>inn<\/code> is reached, the null-character is assigned to <code>ch<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>inn: <strong>ref<\/strong> String\npos: <strong>var<\/strong> integer\nch: <strong>var<\/strong> integer    \nnextChar:\n   -- read the next character from inn and assign it to ch\n   -- skip white space like blanks and end-of-lines\n   -- return ch = 0, if at the end of inn\n   pos := pos + 1\n   if (pos &lt;= inn.length) :then\n      ch :=  inn.get&#91;pos]\n      if (ch = ' ') :then\t\n         restart(nextChar)\t\n    else\n      ch := 0<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The parser is based on a technique of so-called <em>recursive<\/em> methods &#8211; we return to recursion later.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For each nonterminal symbol of the grammar we define a method that checks if the input is in accordance with the nonterminal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the nonterminal <code>&lt;Exp&gt;<\/code> , we define the method <code>exp<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>   exp:\n      -- parse an expression generated from &lt;Exp&gt;\n      term\n      if (ch = '+') :then\n         nextChar\n         restart(exp)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>exp<\/code>-method starts by calling the <code>term<\/code>-method, which we assume parses an expression as generated by <code>&lt;Term&gt;<\/code>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the next character is a <code>'+'<\/code>, <code>nextChar<\/code> is called to assign the next char into <code>ch<\/code> and then execution of <code>exp<\/code> Is restarted. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Given that <code>term<\/code> actually parses a string described by <code>&lt;Term&gt;<\/code>, <code>exp<\/code> will parse an sequence:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;term&gt; + &lt;term&gt; + ... + &lt;term&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We may now show the <code>term<\/code>-method, which is similar to <code>exp<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>term:\n    primary\n    if (ch = '*') :then\n        nextChar\n        restart(term)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>term<\/code>-method assumes that the method <code>primary<\/code> parses a string described by <code>&lt;Primary&gt;<\/code> and will then parse a sequence:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;Primary&gt; * &lt;Primary&gt; * ... * &lt;Primary&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Next we look at the <code>&lt;Primary&gt; <\/code>rule, which has  the form:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;Primary&gt; ::= \"(\" &lt;Exp&gt; \")\" | &lt;Number&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This give us the following <code>primary<\/code>-method:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>primary:\n   -- parse an expression generated from &lt;Primary&gt;\n   if (ch = '(') :then\n      nextChar        \n      exp\n      if (ch = ')') :then\n         nextChar\n      :else\n         syntaxError(1)\n   :else\n        number<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the next character (<code>ch<\/code>) is a left-bracket (<code>\"(\"<\/code>), it calls <code>nextChar<\/code> and then <code>exp<\/code>. When <code>exp<\/code> returns, the next character must be a right-bracket (<code>\")\"<\/code>), otherwise we have an error in the string &#8211; and a syntax error is reported.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the next character is not a left-bracket, the <code>number<\/code>-method is called and again we assume that <code>number<\/code> parses a string as described by <code>&lt;Number&gt;<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The call of the <code>exp<\/code>-method is an example of a recursive call. We return to recursion in the section below.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next we show the <code>number<\/code>-method and the <code>digit<\/code>-method:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>number:\n   -- parse an expression generated from &lt;Number>\n   digit\n   moreDigits: <strong>do<\/strong>\n      if (ascii.isDigit(ch)) :then\n         digit\n         restart(moreDigits)\ndigit:\n   -- parse an expression generated from &lt;Digit>\n   if (ascii.isDigit(ch)) :then\n      nextChar\n   :else\n      syntaxError(3)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>number<\/code>-method expects at least one digit, which is reflected in the <code>digit<\/code>-method that repoerts a syntax error if <code>ch<\/code> is not a digit. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Finally we may show how to start parsing:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>parse:\n   -- parse the expression assigned to inn below\n   inn :=  \"10 + 11 * (1 + 9)\"\n   console.print(\"Parse: \" + inn + \"\\n\")\n   nextChar\n   exp      \n   if (ch &lt;&gt; ascii.null) :then\n          syntaxError(3)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>parse<\/code>-method calls <code>exp<\/code> and when <code>exp<\/code> returns, <code>ch<\/code> must be the <code>ascii.null<\/code> character.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Recursion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Recursion is a technique for defining an entity in terms of a simpler version of itself. In order for this to work, there must be a terminating condition that can be defined without applying recursion, i.e. a recursive definition must be to a part of the entity that is simpler than the original entity.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The expression grammar is and example of a recursive definition. A nonterminal like <code>&lt;Exp&gt;<\/code> is defined using <code>&lt;Exp&gt;<\/code> on the rigt side of the rule, the same is the case for <code>&lt;Term&gt;<\/code>. The rule for <code>&lt;Primary&gt;<\/code> is an example of an indirect recursion, since <code>&lt;Primary&gt;<\/code> is defined by means of <code>&lt;Exp&gt;<\/code> which in turn is defined by means of <code>&lt;Primary&gt;<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The terminating conditions here is that an <code>&lt;Exp&gt;<\/code> can be a <code>&lt;Term&gt;<\/code>, a <code>&lt;Term&gt;<\/code> can be a <code>&lt;Primary&gt;<\/code>, which can be a <code>&lt;Number&gt;<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The methods of the parser are example recursive methods and they follow the same scheme as the grammar except that only the indirect recursion of <code>exp<\/code> via <code>primary<\/code> is explicitly encoded.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The snapshot below shows the situation of the the invocation of parse of the string <code>\"11 * (1 + 9) + 12\"<\/code> at the point where the substring <code>\"11 * (\" <\/code>has been parsed and <code>primary<\/code> has made a recursive invocation of <code>exp<\/code> which has invoked <code>term<\/code>. The red arrow (<code><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-custom-color-3-color\">--&gt;<\/mark><\/code>) shows the point of execution in <code>exp<\/code> and the black arrow (<code>--&gt;<\/code>) shows the point of invocation of <code>exp<\/code> in <code>primary<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-7387b849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60%\">\n<pre class=\"wp-block-code\"><code>  primary:\n     -- parse an expression generated from &lt;Primary&gt;\n     if (ch = '(') :then\n        nextChar        \n--&gt;     exp\n        if (ch = ')') :then\n           nextChar\n        :else\n           syntaxError(1)\n     :else\n        number\n  exp:\n     -- parse an expression generated from &lt;Exp&gt;\n<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-custom-color-3-color\">--&gt;<\/mark> term\n    if (ch = '+') :then\n       nextChar\n       restart(exp)<\/code><\/pre>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:40%\">\n<figure class=\"wp-block-image size-large is-resized\"><img fetchpriority=\"high\" decoding=\"async\" width=\"951\" height=\"1024\" src=\"https:\/\/oopm.org\/wp-content\/uploads\/2024\/10\/ExpParser-951x1024.png\" alt=\"\" class=\"wp-image-8945\" style=\"width:417px;height:auto\" srcset=\"https:\/\/oopm.org\/wp-content\/uploads\/2024\/10\/ExpParser-951x1024.png 951w, https:\/\/oopm.org\/wp-content\/uploads\/2024\/10\/ExpParser-279x300.png 279w, https:\/\/oopm.org\/wp-content\/uploads\/2024\/10\/ExpParser-768x827.png 768w, https:\/\/oopm.org\/wp-content\/uploads\/2024\/10\/ExpParser.png 1042w\" sizes=\"(max-width: 951px) 100vw, 951px\" \/><\/figure>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n<div style=\"display:flex; gap:10px;justify-content:center\" class=\"wps-pgfw-pdf-generate-icon__wrapper-frontend\">\n\t\t<a  href=\"https:\/\/oopm.org?action=genpdf&amp;id=3958\" class=\"pgfw-single-pdf-download-button\" ><img src=\"https:\/\/oopm.org\/wp-content\/plugins\/pdf-generator-for-wp\/admin\/src\/images\/PDF_Tray.svg\" title=\"Generate PDF\" style=\"width:auto; height:45px;\"><\/a>\n\t\t<\/div>","protected":false},"excerpt":{"rendered":"<p>In this section, we show how to write a parser for our simple expression grammar. The parser reads a string of characters and checks whether or not the string is a valid expression as described by the grammar. We assume that the input string to the parser is in the String inn. We define a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":1282,"menu_order":2,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-3958","page","type-page","status-publish","hentry"],"mb":[],"mfb_rest_fields":["title","gutenberg_elementor_mode"],"_links":{"self":[{"href":"https:\/\/oopm.org\/index.php?rest_route=\/wp\/v2\/pages\/3958","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oopm.org\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/oopm.org\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/oopm.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/oopm.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3958"}],"version-history":[{"count":36,"href":"https:\/\/oopm.org\/index.php?rest_route=\/wp\/v2\/pages\/3958\/revisions"}],"predecessor-version":[{"id":9981,"href":"https:\/\/oopm.org\/index.php?rest_route=\/wp\/v2\/pages\/3958\/revisions\/9981"}],"up":[{"embeddable":true,"href":"https:\/\/oopm.org\/index.php?rest_route=\/wp\/v2\/pages\/1282"}],"wp:attachment":[{"href":"https:\/\/oopm.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3958"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}