Equation evaluator

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Equation evaluator

Tom Ayerst
Hi all,

Anybody have any pointers towards a equation evaluator in smalltalk.  I
am working through writing my own scanner, parser, evaluator etc but its
slow going as I am learning it all as I go.

Thanks

Tom


Reply | Threaded
Open this post in threaded view
|

Re: Equation evaluator

John Brant
"Tom Ayerst" <[hidden email]> wrote in message news:3d70940a$1@tobjects....

> Anybody have any pointers towards a equation evaluator in smalltalk.  I
> am working through writing my own scanner, parser, evaluator etc but its
> slow going as I am learning it all as I go.

You can use a parser generator. For example, T-Gen should be able to handle
this. We have a T-Gen replacement named SmaCC, but it requires an updated
compiler to run in Dolphin 5. I believe the updated compiler is scheduled to
be shipped with patch level 2, but I'm not in charge of those decisions :).

Without the updated compiler, Dolphin doesn't compile literal byte arrays
inside of literal arrays (e.g., "#(#[])"). It is possible to get around this
bug by using compile time constants (e.g., "#(##(#[]))"), but I didn't want
to change SmaCC's code that much. You can change the code if you want. You
need to change all of the #transitionTable methods to use compile time
constants (search/replace "#[" -> "##(#[" and "]" -> "])"). You also need to
change the SmaCCGrammarCompiler>>compileTransitionTable method to output
'##(#[' and '])' instead of '#[' and ']' respectively.

Anyway, if you wish to download SmaCC, you can get it from
        http://www.refactory.com/Software/SmaCC/
There is also a tutorial page that has a simple calculator as an example. It
is probably a good starting point for writing your equation evaluator in
SmaCC.


John Brant


Reply | Threaded
Open this post in threaded view
|

Re: Equation evaluator

rush
"John Brant" <[hidden email]> wrote in message
news:jgOd9.1346$Jo.226@rwcrnsc53...
> "Tom Ayerst" <[hidden email]> wrote in message news:3d70940a$1@tobjects....

> Without the updated compiler, Dolphin doesn't compile literal byte arrays
> inside of literal arrays (e.g., "#(#[])"). It is possible to get around
this
> bug by using compile time constants (e.g., "#(##(#[]))"), but I didn't
want
> to change SmaCC's code that much. You can change the code if you want. You
> need to change all of the #transitionTable methods to use compile time
> constants (search/replace "#[" -> "##(#[" and "]" -> "])"). You also need
to
> change the SmaCCGrammarCompiler>>compileTransitionTable method to output
> '##(#[' and '])' instead of '#[' and ']' respectively.

is it only in the code of SmallCC or also in the generated code? Can SmallCC
code be used in commercial programs?


rush


Reply | Threaded
Open this post in threaded view
|

Re: Equation evaluator

Blair McGlashan
In reply to this post by John Brant
"John Brant" <[hidden email]> wrote in message
news:jgOd9.1346$Jo.226@rwcrnsc53...
> "Tom Ayerst" <[hidden email]> wrote in message news:3d70940a$1@tobjects....
>
> > Anybody have any pointers towards a equation evaluator in smalltalk.  I
> > am working through writing my own scanner, parser, evaluator etc but its
> > slow going as I am learning it all as I go.
>
> You can use a parser generator. For example, T-Gen should be able to
handle
> this. We have a T-Gen replacement named SmaCC, but it requires an updated
> compiler to run in Dolphin 5. I believe the updated compiler is scheduled
to
> be shipped with patch level 2, but I'm not in charge of those decisions
:).
>

In the interim the updated compiler is available here:

http://www.object-arts.com/wiki/html/Dolphin/ByteArraysInLiteralArrays.htm

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Equation evaluator

John Brant
In reply to this post by rush
"rush" <[hidden email]> wrote in message
news:al9mn2$1oq6$[hidden email]...
>
> "John Brant" <[hidden email]> wrote in message
> news:jgOd9.1346$Jo.226@rwcrnsc53...
>
> > Without the updated compiler, Dolphin doesn't compile literal byte
arrays
> > inside of literal arrays (e.g., "#(#[])"). It is possible to get around
> this
> > bug by using compile time constants (e.g., "#(##(#[]))"), but I didn't
> want
> > to change SmaCC's code that much. You can change the code if you want.
You
> > need to change all of the #transitionTable methods to use compile time
> > constants (search/replace "#[" -> "##(#[" and "]" -> "])"). You also
need
> to
> > change the SmaCCGrammarCompiler>>compileTransitionTable method to output
> > '##(#[' and '])' instead of '#[' and ']' respectively.
>
> is it only in the code of SmallCC or also in the generated code?

The #transitionTable methods are all generated methods. However, if you also
change the #compileTransitionTable method, then it would generate the code
that used the compile time constants. Of course, with the updated compiler
that Blair posted, you shouldn't need to change anything.

>Can SmallCC
> code be used in commercial programs?

Yes, we only request that if you make some grammar that could be useful for
others, you post it. A little acknowledgement never hurts either :).

BTW, if anyone has any problems, please report them. The development is done
under VW and ported to VA and Dolphin using a script that apply several
rewrite rules. We could be missing some necessary transformations in our
script.


John Brant


Reply | Threaded
Open this post in threaded view
|

Re: Equation evaluator

Tom Ayerst
John,

Sorry for taking such a long time to get back to you.  Thank you very
much for smallcc.  It is, I think, just what I need, and very easy to use.

I say, "I think", because I am now stuck at the next hurdle.  Part of
the app I am attempting wull let the user enter an arbitrary (but
simple, at least at first) equation such as "(inputA + inputB) / inputC
= output".  My knowledge of parsing and evaluating is woefully
inadequate.

I think I need to generate some kind of tree into which I can substitute
values and evaluate it.  Does anyone know of some good resources on this
sort of thing?  (I suspect if I had done a computing degree it would
have been covered in some depth :-( )

Thanks agian for the Parser.

Tom Ayerst

John Brant wrote:

> "rush" <[hidden email]> wrote in message
> news:al9mn2$1oq6$[hidden email]...
>
>>"John Brant" <[hidden email]> wrote in message
>>news:jgOd9.1346$Jo.226@rwcrnsc53...
>>
>>
>>>Without the updated compiler, Dolphin doesn't compile literal byte
>>
> arrays
>
>>>inside of literal arrays (e.g., "#(#[])"). It is possible to get around
>>
>>this
>>
>>>bug by using compile time constants (e.g., "#(##(#[]))"), but I didn't
>>
>>want
>>
>>>to change SmaCC's code that much. You can change the code if you want.
>>
> You
>
>>>need to change all of the #transitionTable methods to use compile time
>>>constants (search/replace "#[" -> "##(#[" and "]" -> "])"). You also
>>
> need
>
>>to
>>
>>>change the SmaCCGrammarCompiler>>compileTransitionTable method to output
>>>'##(#[' and '])' instead of '#[' and ']' respectively.
>>
>>is it only in the code of SmallCC or also in the generated code?
>
>
> The #transitionTable methods are all generated methods. However, if you also
> change the #compileTransitionTable method, then it would generate the code
> that used the compile time constants. Of course, with the updated compiler
> that Blair posted, you shouldn't need to change anything.
>
>
>>Can SmallCC
>>code be used in commercial programs?
>
>
> Yes, we only request that if you make some grammar that could be useful for
> others, you post it. A little acknowledgement never hurts either :).
>
> BTW, if anyone has any problems, please report them. The development is done
> under VW and ported to VA and Dolphin using a script that apply several
> rewrite rules. We could be missing some necessary transformations in our
> script.
>
>
> John Brant
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Equation evaluator

John Brant
"Tom Ayerst" <[hidden email]> wrote in message
news:[hidden email]...

> I say, "I think", because I am now stuck at the next hurdle.  Part of
> the app I am attempting wull let the user enter an arbitrary (but
> simple, at least at first) equation such as "(inputA + inputB) / inputC
> = output".  My knowledge of parsing and evaluating is woefully
> inadequate.
>
> I think I need to generate some kind of tree into which I can substitute
> values and evaluate it.  Does anyone know of some good resources on this
> sort of thing?  (I suspect if I had done a computing degree it would
> have been covered in some depth :-( )

You don't have to create a parse tree, but it may be better. Will the same
expression be evaluated multiple times? If so, then it is probably better to
create a parse tree that can be interpreted. You should look at the
Interpreter pattern from the Design Patterns book (or the Design Patterns
Smalltalk Companion book).

If you are only executing the expression once (e.g., an initialization
expression), then you can get by without needing a tree to interpret. For
example, we can add variables to our simple calculator example
(http://www.refactory.com/Software/SmaCC/Tutorial.html) by doing the
following:

1) Add an instance "values" to the CalculatorParser class
2) Add a setter method for the "values" variable:
    CalculatorParser>>values: aDictionary
        values := aDictionary
3) Add a new method that parses an expression with some variables:
    CalculatorParser class>>parse: aString withValues: aDictionary
        | parser |
        parser := self on: (ReadStream on: aString).
        parser values: aDictionary.
        ^parser parse
4) Add "<variable> : [a-zA-Z_] \w* ;" to the calculator scanner's definition
5) Add a new rule for the Number production in the parser's definition:
    | <variable> 'variable'
        {values
            at: variable value
            ifAbsent:
                [self reportErrorMessage: variable value, ' is undeclared']}
6) Now compile the parser and run a test like:
    | variables |
    variables := Dictionary new.
    variables
        at: 'one' put: 1;
        at: 'var' put: 214.
    CalculatorParser parse: 'var / 2 + one' withValues: variables
You should get 108. Also, if you use a name that isn't in your dictionary,
you should get an error.


John Brant


Reply | Threaded
Open this post in threaded view
|

Re: Equation evaluator

Tom Ayerst
Brilliant!  I'll have to build a parse tree but this will get me up and
running.

Thanks.

Tom

John Brant wrote:

> "Tom Ayerst" <[hidden email]> wrote in message
> news:[hidden email]...
>
>
>>I say, "I think", because I am now stuck at the next hurdle.  Part of
>>the app I am attempting wull let the user enter an arbitrary (but
>>simple, at least at first) equation such as "(inputA + inputB) / inputC
>>= output".  My knowledge of parsing and evaluating is woefully
>>inadequate.
>>
>>I think I need to generate some kind of tree into which I can substitute
>>values and evaluate it.  Does anyone know of some good resources on this
>>sort of thing?  (I suspect if I had done a computing degree it would
>>have been covered in some depth :-( )
>
>
> You don't have to create a parse tree, but it may be better. Will the same
> expression be evaluated multiple times? If so, then it is probably better to
> create a parse tree that can be interpreted. You should look at the
> Interpreter pattern from the Design Patterns book (or the Design Patterns
> Smalltalk Companion book).
>
> If you are only executing the expression once (e.g., an initialization
> expression), then you can get by without needing a tree to interpret. For
> example, we can add variables to our simple calculator example
> (http://www.refactory.com/Software/SmaCC/Tutorial.html) by doing the
> following:
>
> 1) Add an instance "values" to the CalculatorParser class
> 2) Add a setter method for the "values" variable:
>     CalculatorParser>>values: aDictionary
>         values := aDictionary
> 3) Add a new method that parses an expression with some variables:
>     CalculatorParser class>>parse: aString withValues: aDictionary
>         | parser |
>         parser := self on: (ReadStream on: aString).
>         parser values: aDictionary.
>         ^parser parse
> 4) Add "<variable> : [a-zA-Z_] \w* ;" to the calculator scanner's definition
> 5) Add a new rule for the Number production in the parser's definition:
>     | <variable> 'variable'
>         {values
>             at: variable value
>             ifAbsent:
>                 [self reportErrorMessage: variable value, ' is undeclared']}
> 6) Now compile the parser and run a test like:
>     | variables |
>     variables := Dictionary new.
>     variables
>         at: 'one' put: 1;
>         at: 'var' put: 214.
>     CalculatorParser parse: 'var / 2 + one' withValues: variables
> You should get 108. Also, if you use a name that isn't in your dictionary,
> you should get an error.
>
>
> John Brant
>
>