title: Peg.JS: Simple if..then..else implementation
body: <p>I am trying to implement a grammar for a simple if..then..else statement along with simple statements.</p>
  <p>It should be able to parse a statement like:</p>
  <pre><code>if things are going fine
  then
      things are supposed to be this way
      just go with it
  else
      nothing new
  How are you?
  
  </code></pre>
  <p>The document starts with a decision (if.. then.. else) and is followed by a simple statement.</p>
  <p>My grammar so far looks like this:</p>
  <pre><code>document = decision / simple_statement / !.
  
  decision = i:if t:then e:(else)? document { return { if: { cond: i }, then: t, else: e } }
  
  if = 'if' s:statement nl { return s }
  then = 'then' nl actions:indented_statements+ { return actions }
  else = 'else' nl actions:indented_statements+ { return actions }
  indented_statements = ss:(tab statement nl)+ { return ss.reduce(function(st, el) { return st.concat(el) }, []) }
  statement = text:$(char+) { return text.trim() }
  
  simple_statement = s:statement nl document { return { action: s } }
  
  char = [^\n\r]
  ws = [ \t]*
  tab = [\t]+ { return '' }
  nl = [\r\n]+
  </code></pre>
  <p>This returns an output:</p>
  <pre class="lang-json prettyprint-override"><code>{
     &quot;if&quot;: {
        &quot;cond&quot;: &quot;things are going fine&quot;
     },
     &quot;then&quot;: [
        [
           &quot;&quot;,
           &quot;things are supposed to be this way&quot;,
           [
              &quot;
  &quot;
           ],
           &quot;&quot;,
           &quot;just go with it&quot;,
           [
              &quot;
  &quot;
           ]
        ]
     ],
     &quot;else&quot;: [
        [
           &quot;&quot;,
           &quot;nothing new&quot;,
           [
              &quot;
  &quot;
           ]
        ]
     ]
  }
  </code></pre>
  <p><strike>1. Why are there extra empty strings and arrays in the <code>then</code> and <code>else</code> array? What should I do to remove them?</strike></p>
  <ol start="2">
  <li>Why doesn't my grammar read the simple statement(s) after the decision? What should I do to make it read and parse the entire document?</li>
  </ol>
  <hr />
  <p><strong>EDIT</strong>: I think I figured out why I was getting the arrays. I changed the grammar to remove repetitions inside <code>indented_statements</code>.</p>
  <pre><code>document = decision / simple_statement / !.
  
  decision = i:if t:then e:(else)? document { return { if: i, then: t, else: e } }
  
  if = 'if' s:statement nl { return s }
  then = 'then' nl actions:indented_statements+ { return actions }
  else = 'else' nl actions:indented_statements+ { return actions }
  indented_statements = tab s:statement nl { return s }
  statement = text:$(char+) { return text.trim() }
  
  simple_statement = s:statement nl document { return { action: s } }
  
  char = [^\n\r]
  ws = [ \t]*
  tab = [\t]+ { return '' }
  nl = [\r\n]+
  
  </code></pre>