The example below, pass parsing data to Context type object. Expression object create an AST structure using tuple. We want only data, so we use tuple which can hold other tuple. We have a function (like a static function) Evaluate Ast, which call recursive until all AST structure evaluate.
Class Context {
property str{
Value {
Value=Stack(Value) ' get a copy of stack
}
}=stack
Module addterminal (t$) {
Stack .[str] {Data 1, t$}
}
Module addnonterminal (t$) {
Stack .[str] {Data 2, t$}
}
}
Class Expression {
Private:
inuse=Stack
function plus() {
=(2, .interpret1(), .interpret1())
}
function interpret1() {
stack .inuse {
read t$, what
}
if what=1 then
=(1, val(t$))
else.if t$="+" Then
=.plus()
end if
}
Public:
function interpret(context as *Context) {
.inuse<=context=>str
stack .inuse {
Shift 1, -Stack.Size ' reverse stack items
}
=.interpret1()
}
}
Function EvaluteAst(a as array) {
if a#val(0)=1 then
=a#val(1)
else.if a#val(0)=2 then
=EvaluteAst(a#val(1))+EvaluteAst(a#val(2))
end if
}
context->Context()
for context {
.addterminal "3"
.addterminal "3"
.addterminal "4"
.addnonterminal "+"
.addterminal "8"
.addnonterminal "+"
.addnonterminal "+"
}
expression->Expression()
AST=expression=>interpret(context)
Print EvaluteAst(AST)=18
Example 2
Class Context {
property str{
Value {
Value=Stack(Value) ' get a copy of stack
}
}=stack
Module addterminal (t$) {
Stack .[str] {Data 1, t$}
}
Module addnonterminal (t$) {
Stack .[str] {Data 2, t$}
}
}
Class Expression {
function interpret(context as *Context) {
Flush
s=context=>str
while len(s)>0
stack s {
Read what, t$
}
if what=1 then
Push val(t$)
else.if t$="+" Then
Push number+number
end if
rem stack
End While
=number
}
}
context->Context()
for context {
.addterminal "3"
.addterminal "3"
.addterminal "4"
.addnonterminal "+"
.addterminal "8"
.addnonterminal "+"
.addnonterminal "+"
}
expression->Expression()
Print expression=>interpret(context)=18
the context has this 3 3 4 + 8 + + as an expression type of reverse polish notation. The second example evaluate the expression without AST, without using recursion. We use the current stack to push values, or addition of the top two values. Remove the Rem statement (or just press enter after Rem to split line) to see the stack as grow and shrink.
Example 1
Class Context {
property str{
Value {
Value=Stack(Value) ' get a copy of stack
}
}=stack
Module addterminal (t$) {
Stack .[str] {Data 1, t$}
}
Module addnonterminal (t$) {
Stack .[str] {Data 2, t$}
}
}
Class Expression {
Private:
inuse=Stack
function plus() {
=(2, .interpret1(), .interpret1())
}
function interpret1() {
stack .inuse {
read t$, what
}
if what=1 then
=(1, val(t$))
else.if t$="+" Then
=.plus()
end if
}
Public:
function interpret(context as *Context) {
.inuse<=context=>str
stack .inuse {
Shift 1, -Stack.Size ' reverse stack items
}
=.interpret1()
}
}
Function EvaluteAst(a as array) {
if a#val(0)=1 then
=a#val(1)
else.if a#val(0)=2 then
=EvaluteAst(a#val(1))+EvaluteAst(a#val(2))
end if
}
context->Context()
for context {
.addterminal "3"
.addterminal "3"
.addterminal "4"
.addnonterminal "+"
.addterminal "8"
.addnonterminal "+"
.addnonterminal "+"
}
expression->Expression()
AST=expression=>interpret(context)
Print EvaluteAst(AST)=18
Example 2
Class Context {
property str{
Value {
Value=Stack(Value) ' get a copy of stack
}
}=stack
Module addterminal (t$) {
Stack .[str] {Data 1, t$}
}
Module addnonterminal (t$) {
Stack .[str] {Data 2, t$}
}
}
Class Expression {
function interpret(context as *Context) {
Flush
s=context=>str
while len(s)>0
stack s {
Read what, t$
}
if what=1 then
Push val(t$)
else.if t$="+" Then
Push number+number
end if
rem stack
End While
=number
}
}
context->Context()
for context {
.addterminal "3"
.addterminal "3"
.addterminal "4"
.addnonterminal "+"
.addterminal "8"
.addnonterminal "+"
.addnonterminal "+"
}
expression->Expression()
Print expression=>interpret(context)=18
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου
You can feel free to write any suggestion, or idea on the subject.