Trying to figure out how to do simple expressions in if statement

47 views
Skip to first unread message

Steve Tuckner

unread,
Dec 2, 2014, 1:26:30 PM12/2/14
to treet...@googlegroups.com
Hello all,

I have a fairly simple grammer where I am trying to parse and expression as part of an if statement. I want it to handle both of the following cases:

   if 1 == 1 do
   end

and

   if 1 + 1 == 2 do
  end

The relevant portions of the grammar are below. If I change the last thing in binary_expression to expression, then it dies when it hits the do. If I leave it as is, it can parse the first but not the second. Any ideas on the right way to do this?

Thanks,

Steve


  rule if
    'if' ws expression ws block <IfNode>
  end

  rule block
    'do' ws (statement ws)* 'end' <BlockNode>
  end

  rule expression
    ( '(' optional_ws expression optional_ws ')' / binary_expression / unary_expression) <ExpressionNode>
  end

  rule binary_expression
    operand optional_ws binary_operator optional_ws operand <BinaryExpressionNode>
  end

  rule binary_operator
    ('+' / '-' / '*' / '/' / '==' / '>' / '>=' / '<' / '<=') <BinaryOperatorNode>
  end

  rule operand
    (numeric_literal / string_literal / identifier) <OperandNode>
  end

  rule numeric_literal
    [\d]+ <NumericLiteralNode>
  end

  rule string_literal
    "'" [^']* "'" <StringLiteralNode>
  end

  rule symbol
    ':' identifier <SymbolNode>
  end

  rule identifier
    identifier_start identifier_rest
  end



Steve Tuckner

unread,
Dec 9, 2014, 10:57:12 AM12/9/14
to treet...@googlegroups.com
So here I am replying to my own post with a much simpler example and any help would be GREATLY appreciated. I am not sure how to parse something like: ( 1 + 2 + 3 + 4 ). My attempt below will only parse ( 1 + 2 ) successfully.

  rule whole_expr
    '(' ws expr ws ')'
  end

  rule expr
    [\d]+ ws '+' ws expr
  end
 
   rule ws
     [ \t\n]+
   end

The question is whether I am doing this in the right way at all. Is there a better way to have recursively defined rules?

Thanks,

Steve

Steve Tuckner

unread,
Dec 9, 2014, 3:30:05 PM12/9/14
to treet...@googlegroups.com
Responding again to myself, It looks like the way to solve this is to offer an alternative path that recurses as the first option. So to fix this,

rule expr
   ( [\d+] ws '+' ws expr / [\d+] ws '+' [\d+] )
end

That seems to work. Still looking for feedback if this is the way to go or not.

Steve

Clifford Heath

unread,
Dec 9, 2014, 4:50:13 PM12/9/14
to treet...@googlegroups.com
I prefer to use repetition to handle such operations, not recursion.
Recursion makes it harder to manage the arithmetic precedence.
Here’s how I do it:

<https://github.com/cjheath/activefacts/blob/master/lib/activefacts/cql/Expressions.treetop>

The adjacent files contain the other rules (Lexical, etc) that you’ll need.

Clifford Heath.
> --
> You received this message because you are subscribed to the Google Groups "Treetop Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to treetop-dev...@googlegroups.com.
> To post to this group, send email to treet...@googlegroups.com.
> Visit this group at http://groups.google.com/group/treetop-dev.
> For more options, visit https://groups.google.com/d/optout.

Steve (Gmail)

unread,
Dec 9, 2014, 4:52:42 PM12/9/14
to treet...@googlegroups.com
Thanks for the tip. I'll try that out.

Steve

"You must be the change you want to see in the world." Mahatma Gandhi

blog: http://steve.stewdle.com/blog
twitter: @boberetezeke

Diman Todorov

unread,
Mar 2, 2015, 9:43:35 AM3/2/15
to treet...@googlegroups.com
I realize the thread is a little old but nevertheless - Steve, there is a sample that does just that (arithmetic expression parsing) in the examples/ subdirectory on the treetop github.
Reply all
Reply to author
Forward
0 new messages