Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If I understand correctly, your problem isn't left recursion, it's the structure of the parse tree.</p> <p>You've eliminated the left recursion properly, but unfortunately, the only way to get rid of left recursion is by <em>eliminating left recursion in the raw parse tree</em>. Most of the theory for this stuff is just about matching the right set of strings. You are still matching the same set of strings, so the theory is happy, but you wanted a left recursive parse tree. More on that problem <a href="https://en.wikipedia.org/wiki/Left_recursion#Pitfalls" rel="nofollow">on wikipedia</a>.</p> <p>AFAIK, You can't get the raw output of the PEG parser to be left-recursive. You can, however, do whatever you want with the output. So parse it as an array and then postprocess to give it that nice left-structure.</p> <p>Doing it with a simplified (no spaces, no multicharacter identifiers) grammar:</p> <pre><code> start = call id = [a-z] call = arr:id+ { var acc = arr[0] for (i = 1; i &lt; arr.length; i++) { acc = [acc, arr[i]] } return acc; } </code></pre> <p>That parses <code>abcd</code> to <code>[ [ [ 'a', 'b' ], 'c' ], 'd' ]</code>. I just used <code>+</code> instead of recursion, and then ran through the resulting array building the structure we wanted. Wikipedia has some notes on doing <a href="https://en.wikipedia.org/wiki/Parsing_expression_grammar#Indirect_left_recursion" rel="nofollow">left recursion with a PEG</a>.</p> <p>That's assuming you wanted the data structure. If you just want the parens, replace the action with this:</p> <pre><code>var acc = arr[0] for (i = 1; i &lt; arr.length; i++) { acc = acc + '(' + arr[i] + ')' } return acc; </code></pre> <p>Which gives <code>a(b)(c)(d)</code>.</p> <p>To put spaces and multicharacter id's back, you can do this:</p> <pre><code> start = call id = [a-z]+ _ = [ ]+ call = a:id as:arg* { arr = [a].concat(as) var acc = arr[0] for (i = 1; i &lt; arr.length; i++) { acc = acc + '(' + arr[i] + ')' } return acc; } arg = _ a:id {return a} </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload