<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Khanh&apos;s Blog</title><description>A programmer, a learner, a dreamer</description><link>https://dqkqd.github.io/</link><item><title>A year of Colemak</title><link>https://dqkqd.github.io/blog/colemak/</link><guid isPermaLink="true">https://dqkqd.github.io/blog/colemak/</guid><description>I had been a happy QWERTY user for 2 decades, but a year ago, I decided to switch to Colemak, and I don&apos;t regret it.</description><content:encoded>&lt;p&gt;&lt;em&gt;I had been a happy QWERTY user for 2 decades, but a year ago, I decided to switch to Colemak
and I don’t regret it.
In this post, I’ll share the reason, how I practiced, and my setup.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;why-i-made-the-switch&quot;&gt;Why I made the switch&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#why-i-made-the-switch&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I love typing - I love dancing my fingers on the keyboard.
There was only one problem: I could never use all ten of them!
Even after spending months studying touch typing,
my dear muscle memory always kicks in at the wrong time using the wrong fingers for each key.&lt;/p&gt;
&lt;p&gt;The most frustrating part was I couldn’t even notice
if I didn’t fully focus on my hand movement.
There was no &lt;strong&gt;punishment system&lt;/strong&gt; notifying me when I did the wrong thing.
I believe switching to a different layout would force me to reset my muscle memory,
giving me a very good built-in notification mechanism,
yelling at me every time I violate the rules.&lt;/p&gt;
&lt;h2 id=&quot;why-did-i-choose-colemak&quot;&gt;Why did I choose Colemak&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#why-did-i-choose-colemak&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Lucky for me, only two popular layouts came up when I searched for QWERTY alternatives:
Dvorak and Colemak. I picked Colemak because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It is modern, &lt;a href=&quot;https://en.wikipedia.org/wiki/Colemak&quot;&gt;created in 2006&lt;/a&gt;,
newer compared to &lt;a href=&quot;https://en.wikipedia.org/wiki/Dvorak_keyboard_layout&quot;&gt;Dvorak (1936)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The learning overhead is lower than Dvorak’s for people coming from QWERTY.
You can see the comparison image below&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/colemak_20260327081309.ftDaAexV_1INh8q.png&quot; alt=&quot;Colemak vs Dvorak layout&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;3080&quot; height=&quot;776&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;Colemak vs Dvorak layout&lt;/figcaption&gt; &lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;how-did-i-learn&quot;&gt;How did I learn&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#how-did-i-learn&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I began the journey in early 2025, the total progress spanned over 6 months.
Below is the breakdown.&lt;/p&gt;
&lt;p&gt;I spent the first three months getting myself familiar with the layout.
I used &lt;a href=&quot;https://gnusenpai.net/colemakclub/&quot;&gt;gnusenpai&lt;/a&gt; to practice,
30 minutes a day, no skipping.
It was super fun, pleasant, more like playing games rather than fighting with the keyboard.
At the time, I was still using QWERTY for my daily tasks,
but I didn’t get confused very often as my brain knew where and when to switch to &lt;em&gt;Colemak mode&lt;/em&gt;.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/colemak_20260328000827.DQsC1sZ8_YCntA.png&quot; alt=&quot;I practiced on gnusenpai for basic layout&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;1916&quot; height=&quot;953&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;I practiced on gnusenpai for basic layout&lt;/figcaption&gt; &lt;/figure&gt;
&lt;p&gt;Then, I moved to &lt;a href=&quot;https://monkeytype.com/&quot;&gt;monkeytype&lt;/a&gt; for practicing,
roughly 30 minutes a day but in “quote mode” - full quotes or short passages.
I found that typing this way is more practical and enjoyable than playing with disconnected words.
This was the transition phase closest to what I type every day, and yes, I got confused quite a lot.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/colemak_20260328011154.DuFJ3zdp_Z15ly3y.png&quot; alt=&quot;I used monkeytype for full quotes practices&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;1899&quot; height=&quot;937&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;I used monkeytype for full quotes practices&lt;/figcaption&gt; &lt;/figure&gt;
&lt;p&gt;One month after that,
I went berserk and switched everything to Colemak, both at work and at home.
It was a disaster, things got mixed up, my performance instantly dropped by half.
But I was happy as it proved that the &lt;strong&gt;punishment system&lt;/strong&gt; was working - pretty well indeed.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/colemak_20260328001033.CJCJwswZ_KttuA.png&quot; alt=&quot;I was training for 3 months on monkeytype&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;1536&quot; height=&quot;200&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;I was training for 3 months on monkeytype&lt;/figcaption&gt; &lt;/figure&gt;
&lt;p&gt;I don’t actively practice much nowadays.
However, as I keep typing in Colemak,
my performance improves steadily. At first, it was just 30 WPM,
but now I can type comfortably with 90 WPM (my fastest QWERTY was around 100 WPM).&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/colemak_20260327235919.MkmKg6tc_Z1uOcK7.png&quot; alt=&quot;I had 30 WPM on Colemak typing on monkeytype, and it keeps improving over time&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;1536&quot; height=&quot;400&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;I had 30 WPM on Colemak typing on monkeytype, and it keeps improving over time&lt;/figcaption&gt; &lt;/figure&gt;
&lt;h2 id=&quot;my-setup&quot;&gt;My setup&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#my-setup&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I have my external keyboard remapped instead of using the logical layout from &lt;a href=&quot;https://colemak.com&quot;&gt;the official site&lt;/a&gt;.
This comes in handy as &lt;a href=&quot;https://forum.colemak.com/topic/2630-japanese-colemak-keyboard-windows&quot;&gt;I don’t have to mess around with layout software&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I’m a vim user,
and the question about whether I should remap the vim keybinding crossed my mind quite often.
I decided to relearn the vim keymap because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I don’t have to reconfigure vim on every computer I need to access
(work computer, ssh servers, etc.)&lt;/li&gt;
&lt;li&gt;The only thing that seems unreasonable on the new layout is the hjkl keys,
but if you use vim &lt;a href=&quot;https://stackoverflow.com/questions/8750275/vim-super-fast-navigation&quot;&gt;you shouldn’t rely on hjkl for vim movement anyway&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;closing-thoughts&quot;&gt;Closing thoughts&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#closing-thoughts&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It took me 6 months to learn before Colemak became my primary layout.
This was one of the best investments of my life.
Every key press to me now is a joy, I don’t type faster compared to QWERTY,
but it feels more comfortable, and I no longer have wrist pain.&lt;/p&gt;
&lt;p&gt;One small note: even after switching, I haven’t lost my QWERTY skill.
It is just not as efficient as before, with one minor issue:
I have to constantly look at the keyboard while typing.&lt;/p&gt;</content:encoded></item><item><title>Top down operator precedence parsing</title><link>https://dqkqd.github.io/blog/tdop/</link><guid isPermaLink="true">https://dqkqd.github.io/blog/tdop/</guid><description>Implement a top down operator precedence parser from scratch in Rust</description><content:encoded>&lt;p&gt;Top down operator precedence (TDOP) is
a simple yet powerful algorithm for parsing
arithmetic expressions.
It is applied in &lt;a href=&quot;https://matklad.github.io/2020/04/13/simple-but-powerful-pratt-parsing.html&quot;&gt;rust analyzer&lt;/a&gt;,
and &lt;a href=&quot;https://github.com/ziglang/zig/blob/738d2be9d6b6ef3ff3559130c05159ef53336224/lib/std/zig/Parse.zig#L1554-L1591&quot;&gt;the Zig parser appears to use it as well&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this post, I’ll implement a TDOP
parser for a toy expression programming language (&lt;code&gt;1 + 2 * (3 + 4) - 5&lt;/code&gt;).
I’ll try to keep it simple such that no background on parsing
is required.&lt;/p&gt;
&lt;h2 id=&quot;background&quot;&gt;Background&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#background&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The purpose of a parser is to transform a stream of tokens
into a parse tree. It inspects each token
and predicts which expression should be used,
for example, when a parser sees &lt;code&gt;print&lt;/code&gt;, it knows the
expression might be &lt;code&gt;print(&amp;lt;something&amp;gt;)&lt;/code&gt;, and applies
that pattern to create a parse tree.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/tdop-parser-background.BMa3zSDJ_2egtCH.png&quot; alt=&quot;Source code is tokenized, then the tokens are fed into the parser&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;619&quot; height=&quot;838&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;Source code is tokenized, then the tokens are fed into the parser&lt;/figcaption&gt; &lt;/figure&gt;
&lt;p&gt;We can parse &lt;code&gt;print(&amp;quot;Hello World&amp;quot;)&lt;/code&gt; like this, just walk straight
from left to right, consuming tokens as we move forward.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt; TOKENS&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; str&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt; 4&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;  &amp;quot;print&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;(&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; r#&amp;quot;&amp;quot;Hello World&amp;quot;&amp;quot;#&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;)&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; parse_print&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; PrintExpr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  expect_token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;print&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  expect_token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;(&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; string &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;unwrap&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  expect_token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  PrintExpr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;to_string&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, this doesn’t play well with arithmetic expressions,
there are two main reasons.&lt;/p&gt;
&lt;h3 id=&quot;associativity-problem&quot;&gt;&lt;strong&gt;Associativity problem&lt;/strong&gt;&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#associativity-problem&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When a parser sees &lt;code&gt;2&lt;/code&gt; in &lt;code&gt;1 + 2 * 3&lt;/code&gt;, it must determine which operator &lt;code&gt;2&lt;/code&gt; is associated with.
From our perspective, we know it must be &lt;code&gt;*&lt;/code&gt;, which gives us this tree.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/tdop_20260319201749.B5C7vV5J_ZutERQ.png&quot; alt=&quot;Parse tree for 1 + (2 * 3)&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;241&quot; height=&quot;176&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;Parse tree for 1 + (2 * 3)&lt;/figcaption&gt; &lt;/figure&gt;
&lt;p&gt;But our parser doesn’t know about this, it sees &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;*&lt;/code&gt; as simply tokens.
and since it consumes tokens left-to-right, it hasn’t seen &lt;code&gt;*&lt;/code&gt; yet when it reaches &lt;code&gt;2&lt;/code&gt;.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/tdop_20260319202201.C7uSmMKt_1uBuiz.png&quot; alt=&quot;The parser hasn&apos;t seen * when it reaches 2&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;314&quot; height=&quot;57&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;The parser hasn&amp;#39;t seen * when it reaches 2&lt;/figcaption&gt; &lt;/figure&gt;
&lt;h3 id=&quot;prefix-and-infix-operators-problem&quot;&gt;&lt;strong&gt;Prefix and infix operators problem&lt;/strong&gt;&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#prefix-and-infix-operators-problem&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In arithmetic expressions, tokens have
different meanings based on their position.
For example, &lt;code&gt;-&lt;/code&gt; can be interpreted as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Minus operator (prefix operator) in &lt;code&gt;-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Subtraction operator (infix operator) in &lt;code&gt;1 - 2&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The parser must distinguish which operator to apply based on the context,
not from the token itself.&lt;/p&gt;
&lt;h2 id=&quot;tdop-parser&quot;&gt;TDOP parser&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#tdop-parser&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The TDOP parser overcomes the above challenges by
treating operators as first class, i.e.
it sees &lt;code&gt;-&lt;/code&gt; in &lt;code&gt;-1&lt;/code&gt; and &lt;code&gt;1 - 2&lt;/code&gt; differently.
Let’s implement one to see how it can be done.&lt;/p&gt;
&lt;h3 id=&quot;boilerplate&quot;&gt;Boilerplate&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#boilerplate&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h4 id=&quot;tokenizer&quot;&gt;Tokenizer&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#tokenizer&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The parser needs to consume tokens somewhere,
we create a tokenizer for that purpose. It helps
us transform source code into a stream of tokens,
which our parser can use.&lt;/p&gt;
&lt;p&gt;Our toy programming language consists of
numbers, &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, and parentheses,
we define an enum &lt;code&gt;Token&lt;/code&gt; to represent them.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;derive&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Debug&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Copy&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Clone&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;enum&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  Number&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;u32&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;  Add&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;  Sub&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;  Mul&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;  LParen&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;  RParen&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We don’t need a perfect tokenizer (our goal isn’t writing one anyway),
just a simple regex that can parse all of the
above tokens is enough: &lt;code&gt;[0-9]+|[+\-*()]&lt;/code&gt;.
It also needs to support querying the next token (&lt;code&gt;next&lt;/code&gt; method)
and looking ahead without consuming (&lt;code&gt;peek&lt;/code&gt; method),
we use &lt;a href=&quot;https://doc.rust-lang.org/std/iter/struct.Peekable.html&quot;&gt;Peekable&amp;lt;Iterator&amp;gt;&lt;/a&gt;
to accommodate that.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; regex&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Regex&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; std&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt;iter&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Peekable&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;std&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;vec&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;IntoIter&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;program&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; re &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Regex&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;r&amp;quot;[0-9]+|[+\-*()]&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;unwrap&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokens&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; re&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;find_iter&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;program&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; m&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;as_str&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;      &amp;quot;+&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Add&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;      &amp;quot;-&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Sub&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;      &amp;quot;*&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Mul&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;      &amp;quot;(&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;LParen&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;      &amp;quot;)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;RParen&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;      s&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; s&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;parse&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;u32&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;        Ok&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;Number&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;        Err&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; panic!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;bad token &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; s&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;collect&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;  tokens&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;into_iter&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;peekable&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Given an expression &lt;code&gt;(3 + 4)&lt;/code&gt;, the tokenizer produces this stream:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;LParen&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; Number&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Add&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; Number&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; RParen&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;expressions&quot;&gt;Expressions&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#expressions&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;We have the parser’s input - which are tokens.
But what about its output - the parse tree?
Recall from &lt;a href=&quot;#associativity-problem&quot;&gt;the tree earlier&lt;/a&gt;,
its leaf nodes are just literal numbers, while its
internal nodes are expressions.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/tdop_20260319201749.B5C7vV5J_ZutERQ.png&quot; alt=&quot;Parse tree for 1 + (2 * 3)&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;241&quot; height=&quot;176&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;Parse tree for 1 + (2 * 3)&lt;/figcaption&gt; &lt;/figure&gt;
&lt;p&gt;To represent this tree, an enum with different
types of nodes is a perfect fit.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; std&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;fmt&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;enum&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  Literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;u32&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;  BinaryAdd&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; },&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt; // lhs + rhs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;  BinarySub&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; },&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt; // lhs - rhs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;  BinaryMul&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; },&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt; // lhs * rhs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To debug the parse tree, our expressions need to be printable
and evaluable.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;For printing, we implement &lt;code&gt;Display&lt;/code&gt;
using &lt;a href=&quot;https://en.wikipedia.org/wiki/Polish_notation&quot;&gt;Polish Notation&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; fmt&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Display&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; fmt&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#D20F39;--shiki-dark:#F38BA8&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; fmt&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Formatter&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; fmt&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Result&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    match&lt;/span&gt;&lt;span style=&quot;color:#D20F39;--shiki-dark:#F38BA8&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;      Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;Literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; write!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;      Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;BinaryAdd&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; write!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;(+ &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;rhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;      Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;BinarySub&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; write!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;(- &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;rhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;      Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;BinaryMul&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; write!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;(* &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;rhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For evaluating, a simple recursive walk should work just fine.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; eval&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; i64&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; expr &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;Literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;value &lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; i64&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;BinaryAdd&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; eval&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; eval&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;rhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;BinarySub&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; eval&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; eval&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;rhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;BinaryMul&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; eval&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; eval&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;rhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The parse tree for &lt;code&gt;1 + (2 * 3)&lt;/code&gt;, we can see that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Parse tree:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;BinaryAdd&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;    lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; Literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;    rhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BinaryMul&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;        lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; Literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;        rhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; Literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Polish notation: &lt;code&gt;(+ 1 (* 2 3))&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Evaluation: &lt;code&gt;7&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;parser-entrypoint&quot;&gt;Parser entrypoint&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#parser-entrypoint&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Our parser needs an entry point, where it receives source code
and produces the parse tree. This is where we implement
the TDOP algorithm.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; parse&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;program&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; mut&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;program&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  todo!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We also add some utility for testing.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mod&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt; test&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  use&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; super&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::*&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; test_parse&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;program&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; expected_display&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; expected_eval&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; i64&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; expr &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; parse&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;program&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;    assert_eq!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;to_string&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(),&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; expected_display&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;    assert_eq!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;eval&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; expected_eval&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // Testcases go here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The boilerplate is done, let’s start implementing our parser.&lt;/p&gt;
&lt;h3 id=&quot;literal-expression&quot;&gt;Literal expression&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#literal-expression&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We begin with the easiest one: literal numbers with no operators.
This is simple, just get the next token from the tokenizer
and wrap it as &lt;code&gt;Expr::Literal&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Some&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;Number&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;Literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;    token &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; panic!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;bad token &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;:?&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We also update &lt;code&gt;expr&lt;/code&gt; and add a testcase.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mod&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt; test&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;// ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;  #&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;    test_parse&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;123&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;123&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt; 123&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;running 1 test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test literal ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;binary-expressions&quot;&gt;Binary expressions&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#binary-expressions&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Next, we handle binary expressions: &lt;code&gt;lhs &amp;lt;op&amp;gt; rhs&lt;/code&gt;.
Below is our template, we need to determine how to get &lt;code&gt;lhs&lt;/code&gt;, &lt;code&gt;&amp;lt;op&amp;gt;&lt;/code&gt;, and &lt;code&gt;rhs&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binary&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; todo!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;how to get lhs&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; op &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; todo!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;how to get op&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; todo!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;how to get rhs&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; op &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Add&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;BinaryAdd&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;rhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Sub&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;BinarySub&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;rhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Mul&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;BinaryMul&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;rhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;    _ &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; panic!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;bad op &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;:?&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; op&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our implementation might be different depending on how many tokens
we have consumed. Let’s look at different options based on
the tokenizer position (represented as &lt;code&gt;|&lt;/code&gt;).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;lhs &amp;lt;op&amp;gt; rhs |&lt;/code&gt;: everything has been consumed, our &lt;code&gt;binary&lt;/code&gt; is
just a no-brainer wrapper around &lt;code&gt;Expr::Binary&lt;/code&gt;. This isn’t a very helpful
option.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binary&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; op&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; rhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; op &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;lhs &amp;lt;op&amp;gt; | rhs&lt;/code&gt;: &lt;code&gt;lhs&lt;/code&gt; and &lt;code&gt;&amp;lt;op&amp;gt;&lt;/code&gt; have been consumed,
we need to parse &lt;code&gt;rhs&lt;/code&gt;, this can be done using &lt;code&gt;expr&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binary&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; op&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; op &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;lhs | &amp;lt;op&amp;gt; rhs&lt;/code&gt;: we need to parse both &lt;code&gt;&amp;lt;op&amp;gt;&lt;/code&gt; and &lt;code&gt;rhs&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binary&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; op &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;unwrap&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; op &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;| lhs &amp;lt;op&amp;gt; rhs&lt;/code&gt;: Nothing has been consumed,
this is similar to &lt;a href=&quot;#literal-expression&quot;&gt;literal expression&lt;/a&gt;, we
have to parse everything. &lt;code&gt;&amp;lt;op&amp;gt;&lt;/code&gt; and &lt;code&gt;rhs&lt;/code&gt; are the easy ones,
the question is how do we parse &lt;code&gt;lhs&lt;/code&gt;?
Using &lt;code&gt;expr&lt;/code&gt; here would lead to an infinite recursion;
using &lt;code&gt;literal&lt;/code&gt; would force &lt;code&gt;lhs&lt;/code&gt; to always be &lt;code&gt;Expr::Literal&lt;/code&gt;,
which might not be true in all case.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The second and third options are viable options for us.
We go with the third one (&lt;code&gt;lhs | &amp;lt;op&amp;gt; rhs&lt;/code&gt;),
this forces &lt;code&gt;binary&lt;/code&gt; to do as much as it can,
abstracting away &lt;code&gt;&amp;lt;op&amp;gt;&lt;/code&gt; parsing from the caller.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binary&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; op &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;expect&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;missing op for binary expression&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; op &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Add&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;BinaryAdd&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;rhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Sub&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;BinarySub&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;rhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Mul&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;BinaryMul&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; rhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;rhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;    _ &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; panic!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;bad op &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;:?&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; op&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We modify &lt;code&gt;expr&lt;/code&gt; to apply new &lt;code&gt;binary&lt;/code&gt; function.
It first parses &lt;code&gt;lhs&lt;/code&gt; with &lt;code&gt;literal&lt;/code&gt;,
then the remaining tokens with &lt;code&gt;binary&lt;/code&gt; if there are any.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;peek&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;is_none&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  binary&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s have some new testcases.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binary_add&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  test_parse&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;1 + 2&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;(+ 1 2)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binary_sub&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  test_parse&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;1 - 2&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;(- 1 2)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binary_mul&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  test_parse&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;2 * 3&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;(* 2 3)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt; 6&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;running 4 tests&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::literal ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_add ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_sub ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_mul ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;operator-precedence&quot;&gt;Operator precedence&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#operator-precedence&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There is an issue with the current implementation:
the parser always produces a right-deep tree, causing
&lt;a href=&quot;#associativity-problem&quot;&gt;the associativity problem&lt;/a&gt;.
For example, it parses &lt;code&gt;1 + 2 * 3 + 4&lt;/code&gt; as &lt;code&gt;(+ 1 (* 2 (+ 3 4)))&lt;/code&gt;,
which is incorrect because &lt;code&gt;3 + 4&lt;/code&gt; is calculated before &lt;code&gt;2 * 3&lt;/code&gt;.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/tdop_20260320132236.Bc-YZL9o_Z18xe2h.png&quot; alt=&quot;The current implementation always parses right-to-left, ignoring associativity&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;607&quot; height=&quot;314&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;The current implementation always parses right-to-left, ignoring associativity&lt;/figcaption&gt; &lt;/figure&gt;
&lt;p&gt;To solve this, the TDOP parser assigns each operator a
binding power, and associates expressions
with operator having higher power.
Take the above example: if we assign &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;*&lt;/code&gt;
binding powers of &lt;code&gt;10&lt;/code&gt; and &lt;code&gt;20&lt;/code&gt;,
then &lt;code&gt;3&lt;/code&gt; must associate with &lt;code&gt;*&lt;/code&gt;.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/tdop_20260320174010.9t0SZYFQ_2jNEEA.png&quot; alt=&quot;3 associates with *, which has higher binding power than +&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;444&quot; height=&quot;87&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;3 associates with *, which has higher binding power than +&lt;/figcaption&gt; &lt;/figure&gt;
&lt;p&gt;The correct tree with binding power assigned to each operator should be:&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/tdop_20260320132928.BjspMJQo_lq1Eo.png&quot; alt=&quot;Parse tree for 1 + 2 * 3 + 4&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;281&quot; height=&quot;406&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;Parse tree for 1 + 2 * 3 + 4&lt;/figcaption&gt; &lt;/figure&gt;
&lt;h4 id=&quot;building-a-correct-tree&quot;&gt;Building a correct tree&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#building-a-correct-tree&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Look at the tree above, we can see that
the child nodes always have higher binding
power than the parent nodes. Why is that?
Because expressions with higher binding powers
must always be computed first. In other words,
they are &lt;em&gt;binded&lt;/em&gt; tightly together to the lower part of the tree.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/tdop_20260320133030.8kumeiK7_1Snhvg.png&quot; alt=&quot;&quot;&gt; 10)&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;281&quot; height=&quot;406&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;Child node has higher binding power than parent node (20 &amp;gt; 10)&lt;/figcaption&gt; &lt;/figure&gt;
&lt;p&gt;Using this observation,
the idea to build a tree is simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If we encounter an operator with a higher binding power than the current node,
attach it as a child.&lt;/li&gt;
&lt;li&gt;Otherwise, find an ancestor with a lower binding power and attach it there.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let’s illustrate this idea by building the parse tree step-by-step.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;At the beginning, there is only one root node with binding power &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/tdop_20260320174403.CcZ-uawY_V4QbT.png&quot; alt=&quot;There is only one root node with bp = 0&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;444&quot; height=&quot;147&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;There is only one root node with bp = 0&lt;/figcaption&gt; &lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Consume the first 2 tokens. Associate &lt;code&gt;1&lt;/code&gt; with &lt;code&gt;+&lt;/code&gt;,
move to &lt;code&gt;+&lt;/code&gt; right subtree.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/tdop_20260228145826.CXrkVtmX_1XHuiy.png&quot; alt=&quot;Associate 1 with +&apos;s left and move to +&apos;s right&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;444&quot; height=&quot;309&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;Associate 1 with +&amp;#39;s left and move to +&amp;#39;s right&lt;/figcaption&gt; &lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Consume the next 2 tokens. Associate &lt;code&gt;2&lt;/code&gt; with &lt;code&gt;*&lt;/code&gt;
(because &lt;code&gt;*&lt;/code&gt; has higher binding power than &lt;code&gt;+&lt;/code&gt;),
move to &lt;code&gt;*&lt;/code&gt; right subtree.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/tdop_20260228150630.DfY9lqx-_Zsjqx7.png&quot; alt=&quot;Associate 2 with *&apos;s left and move to *&apos;s right&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;444&quot; height=&quot;397&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;Associate 2 with *&amp;#39;s left and move to *&amp;#39;s right&lt;/figcaption&gt; &lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Consume the next 2 tokens. Associate &lt;code&gt;3&lt;/code&gt; with &lt;code&gt;*&lt;/code&gt; (because &lt;code&gt;*&lt;/code&gt; has higher binding power than &lt;code&gt;+&lt;/code&gt;).&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/tdop_20260320134733.DFTWw9Na_Z2mW6lJ.png&quot; alt=&quot;Associate 3 with *&apos;s right&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;444&quot; height=&quot;455&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;Associate 3 with *&amp;#39;s right&lt;/figcaption&gt; &lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;What about &lt;code&gt;+&lt;/code&gt;?
We walk back the tree, find the ancestor with lower
binding power - which is the root node, create a new child there, then move to its right.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/tdop_20260320134933.BtCBzk9I_2qR0Ni.png&quot; alt=&quot;Replace root child with +&apos;s left&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;444&quot; height=&quot;495&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;Replace root child with +&amp;#39;s left&lt;/figcaption&gt; &lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Consume the last token, since there is no other operator, associate it
with &lt;code&gt;+&lt;/code&gt;.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/tdop_20260228152211.BLlqDoQA_Z2eFrdp.png&quot; alt=&quot;Associate 4 to +&apos;s right&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;444&quot; height=&quot;496&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;Associate 4 to +&amp;#39;s right&lt;/figcaption&gt; &lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;implement-operator-precedence&quot;&gt;Implement operator precedence&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#implement-operator-precedence&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Okay, now we can apply the binding power idea to our parser.
Let’s assign &lt;code&gt;10&lt;/code&gt; to &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, and &lt;code&gt;20&lt;/code&gt; to &lt;code&gt;*&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;derive&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;PartialEq&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Eq&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; PartialOrd&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Ord&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;pub&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; u8&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binding_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; token &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Add&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Sub&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Mul&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;    _ &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; panic!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;unsupported binding power for &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;:?&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our &lt;code&gt;expr&lt;/code&gt; should accept power, indicating the current node’s binding power.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot; class=&quot;highlighted-word&quot;&gt;min_power&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot; class=&quot;highlighted-word&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot; class=&quot;highlighted-word&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If an operator’s binding power is higher than the current
one, descend to the right subtree, otherwise,
return the current node to the caller.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; min_power&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Some&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;op&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;peek&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; else&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binding_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;op&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; min_power &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  binary&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At the beginning, the binding power should be &lt;code&gt;0&lt;/code&gt;,
representing the root’s binding power. This also means
we parse all operators having binding power higher than &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; parse&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;program&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; mut&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;program&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add new tests, one of them fails unfortunately.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binary_mul_add&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  test_parse&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;2 * 3 + 4&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;(+ (* 2 3) 4)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt; 10&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binary_add_mul&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  test_parse&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;2 + 3 * 4&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;(+ 2 (* 3 4))&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt; 14&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;thread &amp;#39;test::binary_mul_add&amp;#39; (42) panicked at src/main.rs:112:5:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;assertion `left == right` failed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span&gt;  left: &amp;quot;(* 2 3)&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span&gt; right: &amp;quot;(+ (* 2 3) 4)&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Look at the error: &lt;code&gt;2 * 3 + 4&lt;/code&gt; is parsed as &lt;code&gt;(* 2 3)&lt;/code&gt;,
this is because we return too early without exploring all
operators with higher binding power.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; min_power&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Some&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;op&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;peek&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; else&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binding_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;op&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; min_power &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  binary&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We solve this by adding a loop, iterating through all possible operators.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; min_power&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; mut&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  loop&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Some&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;op&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;peek&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; else&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;      break&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binding_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;op&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; min_power &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;      break&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;    lhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binary&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;  lhs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because the accepted operator must have higher binding power,
they should take &lt;code&gt;lhs&lt;/code&gt; as their left-hand side and produce
a &lt;code&gt;Expr::Binary&lt;/code&gt; node.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; min_power&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; mut&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  loop&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Some&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;op&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;peek&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; else&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;      break&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binding_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;op&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; min_power &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;      break&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;    lhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binary&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;  lhs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The testcases should pass.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;running 6 tests&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_add ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_add_mul ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_mul_add ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_mul ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_sub ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::literal ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;prefix-and-infix-operators&quot;&gt;Prefix and infix operators&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#prefix-and-infix-operators&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There is one more issue with our parser: &lt;a href=&quot;#prefix-and-infix-operators-problem&quot;&gt;prefix and infix operators problem&lt;/a&gt;,
let’s fix that.&lt;/p&gt;
&lt;h4 id=&quot;apply-prefix-and-infix-terminology&quot;&gt;Apply prefix and infix terminology&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#apply-prefix-and-infix-terminology&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;We have some observations with prefix and infix forms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prefix operators only require the right hand side: &lt;code&gt;&amp;lt;op&amp;gt; rhs&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Infix operators need both: &lt;code&gt;lhs &amp;lt;op&amp;gt; rhs&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But this is exactly what we have done.
&lt;a href=&quot;#literal-expression&quot;&gt;Literal expression&lt;/a&gt; has prefix form (with no prefix operator),
and &lt;a href=&quot;#binary-expressions&quot;&gt;binary expression&lt;/a&gt; has (obviously) infix form.
We can migrate them to use the new terminology.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha has-diff&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; min_power&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff remove&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; mut&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; mut&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; prefix&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff remove&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;    lhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binary&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;    lhs &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; infix&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line diff remove&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; prefix&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line diff remove&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binary&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; min_power&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; infix&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; lhs&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; min_power&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;minus-expression&quot;&gt;Minus expression&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#minus-expression&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;As mentioned earlier, &lt;a href=&quot;#tdop-parser&quot;&gt;TDOP parser treats operators as first class&lt;/a&gt;,
which means we must handle the prefix form and the infix form of a token separately.&lt;/p&gt;
&lt;p&gt;This is what we will do with the &lt;code&gt;-&lt;/code&gt; token. Since its infix form
has already been implemented in &lt;code&gt;Expr::BinarySub&lt;/code&gt;, we only consider
its prefix form. Let’s add a new &lt;code&gt;Expr::Minus&lt;/code&gt; (with the form &lt;code&gt;- &amp;lt;inner&amp;gt;&lt;/code&gt;)
for that.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;enum&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  Minus&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Box&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; fmt&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Display&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; fmt&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#D20F39;--shiki-dark:#F38BA8&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; fmt&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Formatter&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; fmt&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Result&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    match&lt;/span&gt;&lt;span style=&quot;color:#D20F39;--shiki-dark:#F38BA8&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;      // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;      Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;Minus&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; write!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;-&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; eval&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; i64&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; expr &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;Minus&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;eval&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because &lt;code&gt;Expr::Minus&lt;/code&gt; has prefix form, it should be handled
inside &lt;code&gt;prefix&lt;/code&gt;. We call &lt;code&gt;expr&lt;/code&gt; to get the inner expression and wrap
it in &lt;code&gt;Expr::Minus&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; prefix&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Some&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;Number&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;Literal&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Some&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Sub&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;      let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; expr &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binding_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Sub&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;      Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;Minus&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt;Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;    token &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; panic!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;bad token &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;:?&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;New testcases, and one of them fails.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; prefix_minus&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  test_parse&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;-2&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;-2&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; prefix_minus_mul&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  test_parse&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;-2 * 3&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;(* -2 3)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;thread &amp;#39;test::prefix_minus_mul&amp;#39; (46) panicked at src/main.rs:122:5:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;assertion `left == right` failed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span&gt;  left: &amp;quot;-(* 2 3)&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span&gt; right: &amp;quot;(* -2 3)&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The failed test is &lt;code&gt;-2 * 3&lt;/code&gt;. Look at its parse tree, &lt;code&gt;2 * 3&lt;/code&gt; is computed
before &lt;code&gt;-2&lt;/code&gt;, meaning &lt;code&gt;*&lt;/code&gt; operator binds more tightly than minus (&lt;code&gt;-&lt;/code&gt;) operator.&lt;/p&gt;
&lt;figure class=&quot;mx-auto text-center&quot;&gt; &lt;img src=&quot;https://dqkqd.github.io/_astro/tdop_20260320144509.bg2Akrrf_jmAxn.png&quot; alt=&quot;* is computed before minus operator (-)&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;391&quot; height=&quot;236&quot; class=&quot;mx-auto&quot;&gt; &lt;figcaption&gt;* is computed before minus operator (-)&lt;/figcaption&gt; &lt;/figure&gt;
&lt;p&gt;This is because we use the same binding power for both
minus operator and binary sub operator, and all of them
are less than the &lt;code&gt;*&lt;/code&gt; operator’s.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; prefix&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Some&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Sub&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;      let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; expr &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binding_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Sub&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;      Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;Minus&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt;Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We need to separate binding power for prefix and infix operators.
The &lt;code&gt;binding_power&lt;/code&gt; we have been using so far is, in fact,
the binding power for infix operators. Let’s change that.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha has-diff&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line diff remove&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binding_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; infix_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;// ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; min_power&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff remove&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; binding_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;op&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; bp &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; infix_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;op&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And define a new binding power for prefix operators.
The minus operator should have the highest power
for now, let’s set it to &lt;code&gt;30&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; prefix_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; token &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Sub&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;    _ &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; panic!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;unsupported prefix binding power for &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;:?&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;// ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; prefix&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Some&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Sub&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;      let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; expr &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; prefix_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Sub&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;      Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;Minus&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt;Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The tests should pass.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;running 8 tests&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_add_mul ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_add ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_mul ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_mul_add ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_sub ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::literal ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::prefix_minus_mul ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::prefix_minus ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;parentheses-expression&quot;&gt;Parentheses expression&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#parentheses-expression&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Let’s go with the final one: Parentheses expressions having the form
&lt;code&gt;( &amp;lt;inner&amp;gt; )&lt;/code&gt;, i.e. &lt;code&gt;(1 + 2)&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;enum&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  Paren&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Box&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; fmt&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Display&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; fmt&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#D20F39;--shiki-dark:#F38BA8&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; fmt&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Formatter&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color:#04A5E5;--shiki-dark:#89DCEB&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt; fmt&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Result&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;    match&lt;/span&gt;&lt;span style=&quot;color:#D20F39;--shiki-dark:#F38BA8&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;      // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;      Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;Paren&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; write!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;(&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; eval&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; i64&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; expr &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;Paren&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; eval&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we define binding powers for its operators.
There are some observations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;(&lt;/code&gt; is a prefix operator. It should have the lowest
prefix binding power so that the inner expression is always parsed first.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;)&lt;/code&gt; acts as a parsing breaker, it must have
the lowest infix binding power, so that &lt;code&gt;expr&lt;/code&gt;
knows to stop parsing when exiting a parentheses context.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; prefix_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; token &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Sub&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;LParen&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;    _ &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; panic!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;unsupported prefix binding power for &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;:?&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; infix_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; token &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Add&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Sub&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Mul&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;RParen&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; BindingPower&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;    _ &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; panic!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;unsupported infix binding power for &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;:?&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to &lt;a href=&quot;#minus-expression&quot;&gt;the minus expression&lt;/a&gt;, this is defined
inside &lt;code&gt;prefix&lt;/code&gt;. After getting the inner expression using &lt;code&gt;expr&lt;/code&gt;,
we must also consume the &lt;code&gt;)&lt;/code&gt; token.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; prefix&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E64553;--shiki-dark:#EBA0AC&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;  match&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-light-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;    Some&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;LParen&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;      let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; expr &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;tokenizer&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; prefix_power&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;LParen&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;      let&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; expr &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Expr&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;Paren&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-dark:#F9E2AF&quot;&gt;Box&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;expr&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;      let&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt; Some&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;Token&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;RParen&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; tokenizer&lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt; else&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;        panic!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;expect Token::RParen&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;      };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;      expr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt;    token &lt;/span&gt;&lt;span style=&quot;color:#179299;--shiki-dark:#94E2D5&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; panic!&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;bad token &lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;:?&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4C4F69;--shiki-dark:#CDD6F4&quot;&gt; token&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;New testcases, and they all pass.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; paren&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  test_parse&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;(2)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;(2)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; paren_complex&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  test_parse&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;&amp;quot;2 * (3 + 4) - (5 + 6)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt; &amp;quot;(- (* 2 ((+ 3 4))) ((+ 5 6)))&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#DF8E1D;--shiki-light-font-style:italic;--shiki-dark:#F9E2AF;--shiki-dark-font-style:italic&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8839EF;--shiki-dark:#CBA6F7&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt; paren_nested&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic&quot;&gt;  test_parse&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;    &amp;quot;2 * (3 + 4 * ((5 + 6)))&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#40A02B;--shiki-dark:#A6E3A1&quot;&gt;    &amp;quot;(* 2 ((+ 3 (* 4 (((+ 5 6)))))))&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FE640B;--shiki-dark:#FAB387&quot;&gt;    94&lt;/span&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;  )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7C7F93;--shiki-dark:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code astro-code-themes catppuccin-latte catppuccin-mocha&quot; style=&quot;background-color:#eff1f5;--shiki-dark-bg:#1e1e2e;color:#4c4f69;--shiki-dark:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;running 11 tests&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::paren ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::literal ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::paren_complex ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_sub ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_mul_add ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_add_mul ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::prefix_minus ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_add ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::binary_mul ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::prefix_minus_mul ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test test::paren_nested ... ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;a style=&quot;text-decoration:none;color:inherit&quot; href=&quot;#conclusion&quot;&gt;&lt;span class=&quot;anchor-icon&quot; aria-hidden=&quot;true&quot;&gt; #&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We have our TDOP parser implemented. Using the same idea,
we can add more expressions,
i.e. divide expression (&lt;code&gt;8 / 2&lt;/code&gt;), power expression (&lt;code&gt;5 ^ 2&lt;/code&gt;), etc.&lt;/p&gt;
&lt;p&gt;The TDOP parser, at first glance, might seem to be complicated
(I still don’t fully understand &lt;a href=&quot;https://tdop.github.io/&quot;&gt;its original paper&lt;/a&gt;).
However, once we grasp the idea, it is elegant, easy to implement,
and quite &lt;a href=&quot;https://web.archive.org/web/20080722032411/http://effbot.org/zone/simple-top-down-parsing.htm#performance&quot;&gt;performant&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Most of the ideas in this post come from the very well-written
tutorials from &lt;a href=&quot;https://www.oilshell.org/blog/2017/03/31.html&quot;&gt;this index post&lt;/a&gt;.
I had a very fun time playing with this algorithm, all the code can be found
&lt;a href=&quot;https://github.com/dqkqd/codeblogs/tree/main/tdop&quot;&gt;in my repo&lt;/a&gt;.&lt;/p&gt;</content:encoded></item></channel></rss>