wrong argument type Class (expected Module) (TypeError)

461 views
Skip to first unread message

amir teshome

unread,
Jun 26, 2014, 9:29:06 AM6/26/14
to treet...@googlegroups.com
I was trying to parse mathematical expression below is my treetop rules, 

rule expr 
    (term / (expr '+' term) )      <XBody>
end 

rule term     
   (factor / (term '*' factor))    <XBody>
end

rule factor
  (numd / groupd)    <XBody>
end

rule groupd
 '(' expr ')'    <XBody>
end

rule numd
 [1-9] [0-9]*  <XBody>
end


when I try to parse 2+3 i'm  getting this error 

(eval):158:in `extend': wrong argument type Class (expected Module) (TypeError)
from (eval):158:in `_nt_factor'
from (eval):97:in `_nt_term'
from (eval):30:in `_nt_expr'
from /var/lib/gems/1.9.1/gems/treetop-1.5.3/lib/treetop/runtime/compiled_parser.rb:18:in `parse'

Can any one help me out on this (I'm somehow new for treetop) thank you in advance.    

Paul Madden

unread,
Jun 26, 2014, 11:12:17 AM6/26/14
to treet...@googlegroups.com
Hi Amir,

Try this:

grammar G

  rule expr 
    term '+' expr <X> / term "" <X>
  end 

  rule term     
    factor '*' term <X> / factor "" <X>
  end

  rule factor
    numd "" <X> / groupd "" <X>
  end

  rule groupd
    '(' expr ')' <X>
  end

  rule numd
    [1-9] [0-9]* <X>
  end

end

The problem you asked about was due to the fact that Treetop only lets you associate compound rules (not single-terminal rules) with classes. But you can add an empty string terminal to a rule to make it compound, and it will not affect the parse.

Also, in rules 'expr' and 'factor': You want to try to match the longer rule first -- otherwise the short one will always match because it is a prefix of the longer rule. Also, PEGs do not support left recursion, so you want e.g. "term '+' expr" rather than "expr '+' term".

paul

Clifford Heath

unread,
Jun 26, 2014, 8:02:20 PM6/26/14
to treet...@googlegroups.com
Amir,

On 27 Jun 2014, at 1:12 am, Paul Madden <pma...@gmail.com> wrote:
> The problem you asked about was due to the fact that Treetop only lets you associate compound rules (not single-terminal rules) with classes.

Not quite. You can only associate new nodes with classes.
When an alternate in a rule calls only one other rule, no new
sequence-node is created (that would have only one element).
Instead, the same node is returned, so you cannot use a class.

> But you can add an empty string terminal to a rule to make it compound, and it will not affect the parse.

This forces a sequence node. It’s better to rewrite your class
as a module and use that instead.

Clifford Heath.
signature.asc

amir teshome

unread,
Jun 30, 2014, 5:01:05 AM6/30/14
to treet...@googlegroups.com
Hi Paul,

Sorry for late respond I have been some how busy, and thank you very much for your explanation, I have done what you suggested and it works now I'm trying to write other ruby class to execute the parsed result, 

I hope if I got some problem you will help me thank you       

amir teshome

unread,
Jun 30, 2014, 5:07:13 AM6/30/14
to treet...@googlegroups.com
thank you also Calliford, 

But I have seen the suggestion to change the class into module then I tried to change but it was some how messy since I have other previous code which is related to other parser, which was contained in one module with a lots of classes. So I have to change those all classes to module       


On Thursday, June 26, 2014 3:29:06 PM UTC+2, amir teshome wrote:
Reply all
Reply to author
Forward
0 new messages