1

I'm trying to understand how left and right associative grammars work and I need a little help. So I decided to come up an example and ask for some clarification. Basically, I want to create a grammar for two logical operations: and + implication. I want to make it so and is left associative and implication is right associative. This is what I got so far. Is this correct? I feel like it might be ambiguous. (I also kept in mind that and has higher precedence than implication)

<exp> := <and>
<and> := <impl> | <and> ^ <impl>
<impl> := <term> | <term> -> <impl>
<term> := (<exp>) | <bool>
<bool> := true | false
Sreten Jocić
  • 165
  • 1
  • 14
  • 1
    Yes, it's ambiguous, but more importantly it doesn't match all valid inputs (unless I've misunderstood what your input language is). As I've understood you, you want to parse, say, `a ^ b ^ c` and have it produce a parse tree that grows to the left (like `(a ^ b) ^ c`) and `a -> b -> c` producing a right-leaning parse tree (like `a -> (b -> c)`). But your grammar doesn't match either - it always requires one operator to be parenthesized (and does not allow the other to be). – sepp2k May 16 '18 at 11:31
  • @sepp2k yes, you understood what I want, can you please help me thank you!! – Sreten Jocić May 16 '18 at 11:35
  • There is a sample grammar in [this answer](https://stackoverflow.com/a/39501548) which includes both left- and right-associative operators. The names of the operators are different but the principle is the same so you should have no trouble adapting it for your problem. – rici May 16 '18 at 17:01
  • @rici Yes, I found that answer and used it to come up with my solution. But still can you please have a look to see if I made a mistake somewhere, it would really help me a lot. Thanks! – Sreten Jocić May 17 '18 at 12:42
  • It looks ok, except for the missing close angle bracket. But, for future reference, "check my homework assignment" (or even "check my program") is not generally considered to be within the scope of StackOverflow and downvotes/close votes are likely. – rici May 17 '18 at 15:24

1 Answers1

6

From my limited knowledge, it seems to me that you got the precedences inverted.

At the grammar level, a left associative operator has the following format:

exp = exp op other | other

...and a right associative operator would have the following format:

exp = other op exp | other

As you can see, it depends on your use of recursion: left associativity would use a left recursive rule while right associativity would use a right recursive one.

As for precedence, the later a rule is in the grammar, the higher its precedence. In the grammar bellow, where opL represents a left-associative operator and opR represents a right associative one, exp0 has lower precedence than exp1, which has lower precendence than other:

exp0 = exp0 opL exp1 | exp1
exp1 = other opR exp1 | other
other = ...

As an example, if opL is "+" and opR is "**" and other is a letter, see how the parse tree for a few expressions would be built:

  • Left associativity:

    a + b + c -> (a + b) + c
    exp0 -+-> exp0 +-> exp0 --> exp1 --> other --> a
          |        |
          |        +-> opL --> "+"
          |        |
          |        \-> exp1 --> other --> b
          |
          +-> opL --> "+"
          |
          \-> exp1 --> c        
    
  • Right Associativity:

      a ** b ** c -> a ** (b ** c)
      exp0 --> exp1 +-> other --> a
                    |
                    +-> opR --> "**"
                    |
                    \-> exp1 +-> other --> b
                             |
                             +-> opR --> "**"
                             |
                             \-> exp1 --> other --> c
    
  • Precedence:

    a + b ** c -> a + (b ** c)
    exp0 +-> exp0 +-> exp1 --> other --> a
         |
         +-> opL --> "+"
         | 
         \-> exp1 +-> other --> b
                  |
                  +-> opR --> "**"
                  |
                  \-> exp1 --> other --> c
    
Branco Medeiros
  • 729
  • 4
  • 10
  • You might want to read up on Markdown. TL;DR: if you want to nest one construct within another one (eg. code within a bullet) you need an extra four-space indent. After a bullet point, four spaces means the paragraph is still in the sane bullet; *eight* spaces means that it is also a code block. We don't use the three-backtick notation here; code blocks are just indented. – rici May 17 '18 at 15:27
  • I eventually indented all the "code" removing the back-ticks it had initially, but didnt' know about the 8 spaces trick. thanks for the heads up. – Branco Medeiros May 17 '18 at 15:46
  • This link might be useful reading: https://stackoverflow.com/editing-help. It's surprisingly hard to find. – rici May 17 '18 at 15:51