Τρίτη 14 Ιουλίου 2020

Interpreter Pattern (OOP)

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.

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.