I think shunting yard is a bit more complex since it requires a separate stack, but precedence climbing is definitely better than pure recursive-descent and follows quite straightforwardly if you try to refactor an RD parser by noticing that most of the functions are very similar, of this form:<p><pre><code>    while(token in tokens[level])
        consume token
        result = result operator[level] func[level+1]()
</code></pre>
Then you realise that you don&#x27;t need to climb up each level of precedence with a function call, and instead can go right to the level of the token and consume everything &quot;above&quot; that level... so it&#x27;s really more like &quot;precedence jumping&quot;. This also means the call stack doesn&#x27;t get deeper in proportion to the number of levels, unlike with a pure RD parser. There could be 10 or 1000 levels in the table and the running time will still be the same - linear in the number of tokens in the input. This is especially good for languages with many precedence levels like C, or more complex applications with dynamically defined operators as you mention. A more detailed explanation of this derivation is here:<p><a href="https:&#x2F;&#x2F;www.engr.mun.ca&#x2F;~theo&#x2F;Misc&#x2F;exp_parsing.htm#climbing" rel="nofollow">https:&#x2F;&#x2F;www.engr.mun.ca&#x2F;~theo&#x2F;Misc&#x2F;exp_parsing.htm#climbing</a>