‹ BackHN Continuity

Thread

Needed 1+1, built a functional programming language

151 points · 80 comments · birdculture

  1. ReDress · · focus · HN ↗
    I'm not sure whether someone else has commented on this. I am yet to read the comments. Maybe I will read them soon enough.

    Anyways and however, speaking in strict mathetical sense, the model of a tree actually breaks the classical mathematical model of operator precedence.

    1 + 1 + 1 evaluates to:

         (+)
         / \
       (+) (1)
       / \
     (1) (1)
    
    The above will be correct, mathematically, but will break once you involve multiple mathematical operators in the statement. Because, mathematically, operators have precedence.

    The operators are essentially ordered based on their depth into the right of the question / statement but unless I am terribly wrong, this is not the case in mathematics and some operators have higher precedence regardless of their position in the statement.

    Any comments on this?

    1. stratos123 · · focus · HN ↗
      Operator precedence needs to get applied at parsing time, before you get a tree. 1 + 2 * 1 needs to get parsed to

           (+)
           / \
         (1) (*)
             / \
           (2) (1)
      
      The tree representation is unambiguous and once you get that there's no need to think about precedence.

      There&#x27;s many ways to do this parsing, e.g. <a href="https:&#x2F;&#x2F;matklad.github.io&#x2F;2020&#x2F;04&#x2F;13&#x2F;simple-but-powerful-pratt-parsing.html" rel="nofollow">https:&#x2F;&#x2F;matklad.github.io&#x2F;2020&#x2F;04&#x2F;13&#x2F;simple-but-powerful-pra...

      1. mrkeen · · focus · HN ↗
        Agree with &#x27;solve it during parsing&#x27;.

        I had a look at the link. The BNF looked good:

          Expr =
            Expr &#x27;+&#x27; Expr
            ...
        
        Then the author fixed the left-recursion and precedence (which also looks good,) but then complains about the fixed version - &quot;the “shape” of expressions feels completely lost in this new formulation.&quot; :

          Expr =
            Factor
          | Expr &#x27;+&#x27; Factor
          ...
        
        Then the author takes us through Pratt parsing and ends up at:

          fn expr_bp(lexer: &amp;mut Lexer, min_bp: u8) -&gt; S { 
            let mut lhs = match lexer.next() {
                Token::Atom(it) =&gt; S::Atom(it),
                t =&gt; panic!(&quot;bad token: {:?}&quot;, t),
            };
        
            loop {
                let op = match lexer.peek() {
                    Token::Eof =&gt; break,
                    Token::Op(op) =&gt; op,
                    t =&gt; panic!(&quot;bad token: {:?}&quot;, t),
                };
            ...
        
        Yikes! I think he criticised the wrong code. I&#x27;ll take the &#x27;{expression} is a {factor} or an {expression plus a factor}&#x27; formulation over the &#x27;mut-loop-peek-panic-lexer-next&#x27; approach any day!
Open on Hacker News to reply ↗

Unofficial Hacker News client; not affiliated with Y Combinator.