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 |
"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 |
"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 |
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 |
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 |
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 > > |
"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 |
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 > > |
Free forum by Nabble | Edit this page |