Fix example
This commit is contained in:
parent
d8d462d3f9
commit
9489f783e5
3 changed files with 25 additions and 25 deletions
|
@ -1,5 +1,3 @@
|
||||||
// +build example
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -8,6 +6,13 @@ import (
|
||||||
"github.com/neonxp/unilex"
|
"github.com/neonxp/unilex"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LP unilex.LexType = iota
|
||||||
|
RP
|
||||||
|
NUMBER
|
||||||
|
OPERATOR
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
l := unilex.New("10 * (20.0 + 30.0)")
|
l := unilex.New("10 * (20.0 + 30.0)")
|
||||||
|
@ -29,13 +34,13 @@ func lexExpression(l *unilex.Lexer) unilex.StateFunc {
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case l.Accept("("):
|
case l.Accept("("):
|
||||||
l.Emit("LP")
|
l.Emit(LP)
|
||||||
case l.Accept(")"):
|
case l.Accept(")"):
|
||||||
l.Emit("RP")
|
l.Emit(RP)
|
||||||
case unilex.ScanNumber(l):
|
case unilex.ScanNumber(l):
|
||||||
l.Emit("NUMBER")
|
l.Emit(NUMBER)
|
||||||
case l.Accept("+-*/^!"):
|
case l.Accept("+-*/^!"):
|
||||||
l.Emit("OPERATOR")
|
l.Emit(OPERATOR)
|
||||||
case l.Peek() == unilex.EOF:
|
case l.Peek() == unilex.EOF:
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// +build example
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
// Helper functions to convert infix notation to RPN and calculates expression result.
|
// Helper functions to convert infix notation to RPN and calculates expression result.
|
||||||
|
@ -29,36 +27,36 @@ parseLoop:
|
||||||
fmt.Printf("Lexem: %+v\n", ll)
|
fmt.Printf("Lexem: %+v\n", ll)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case ll.Type == "NUMBER", ll.Type == "OPERATOR" && ll.Value == "!":
|
case ll.Type == NUMBER, ll.Type == OPERATOR && ll.Value == "!":
|
||||||
output = append(output, ll)
|
output = append(output, ll)
|
||||||
case ll.Type == "LP":
|
case ll.Type == LP:
|
||||||
stack.Push(ll)
|
stack.Push(ll)
|
||||||
case ll.Type == "RP":
|
case ll.Type == RP:
|
||||||
for {
|
for {
|
||||||
cl := stack.Pop()
|
cl := stack.Pop()
|
||||||
if cl.Type == "LP" {
|
if cl.Type == LP {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if cl.Type == unilex.LEOF {
|
if cl.Type == unilex.LexEOF {
|
||||||
log.Fatalf("No pair for parenthesis at %d", ll.Start)
|
log.Fatalf("No pair for parenthesis at %d", ll.Start)
|
||||||
}
|
}
|
||||||
output = append(output, cl)
|
output = append(output, cl)
|
||||||
}
|
}
|
||||||
case ll.Type == "OPERATOR":
|
case ll.Type == OPERATOR:
|
||||||
for {
|
for {
|
||||||
if stack.Head().Type == "OPERATOR" && (opPriority[stack.Head().Value] > opPriority[ll.Value]) {
|
if stack.Head().Type == OPERATOR && (opPriority[stack.Head().Value] > opPriority[ll.Value]) {
|
||||||
output = append(output, stack.Pop())
|
output = append(output, stack.Pop())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
stack.Push(ll)
|
stack.Push(ll)
|
||||||
case ll.Type == unilex.LEOF:
|
case ll.Type == unilex.LexEOF:
|
||||||
break parseLoop
|
break parseLoop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for stack.Head().Type != unilex.LEOF {
|
for stack.Head().Type != unilex.LexEOF {
|
||||||
output = append(output, stack.Pop())
|
output = append(output, stack.Pop())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,26 +66,26 @@ parseLoop:
|
||||||
func calculateRPN(rpnLexems []unilex.Lexem) string {
|
func calculateRPN(rpnLexems []unilex.Lexem) string {
|
||||||
stack := lexemStack{}
|
stack := lexemStack{}
|
||||||
for _, op := range rpnLexems {
|
for _, op := range rpnLexems {
|
||||||
if op.Type == "NUMBER" {
|
if op.Type == NUMBER {
|
||||||
stack.Push(op)
|
stack.Push(op)
|
||||||
} else {
|
} else {
|
||||||
switch op.Value {
|
switch op.Value {
|
||||||
case "+":
|
case "+":
|
||||||
a1, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
a1, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
||||||
a2, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
a2, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
||||||
stack.Push(unilex.Lexem{Type: "NUMBER", Value: strconv.FormatFloat(a2+a1, 'f', -1, 64)})
|
stack.Push(unilex.Lexem{Type: NUMBER, Value: strconv.FormatFloat(a2+a1, 'f', -1, 64)})
|
||||||
case "-":
|
case "-":
|
||||||
a1, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
a1, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
||||||
a2, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
a2, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
||||||
stack.Push(unilex.Lexem{Type: "NUMBER", Value: strconv.FormatFloat(a2-a1, 'f', -1, 64)})
|
stack.Push(unilex.Lexem{Type: NUMBER, Value: strconv.FormatFloat(a2-a1, 'f', -1, 64)})
|
||||||
case "*":
|
case "*":
|
||||||
a1, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
a1, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
||||||
a2, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
a2, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
||||||
stack.Push(unilex.Lexem{Type: "NUMBER", Value: strconv.FormatFloat(a2*a1, 'f', -1, 64)})
|
stack.Push(unilex.Lexem{Type: NUMBER, Value: strconv.FormatFloat(a2*a1, 'f', -1, 64)})
|
||||||
case "/":
|
case "/":
|
||||||
a1, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
a1, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
||||||
a2, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
a2, _ := strconv.ParseFloat(stack.Pop().Value, 64)
|
||||||
stack.Push(unilex.Lexem{Type: "NUMBER", Value: strconv.FormatFloat(a2/a1, 'f', -1, 64)})
|
stack.Push(unilex.Lexem{Type: NUMBER, Value: strconv.FormatFloat(a2/a1, 'f', -1, 64)})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
//go:build example
|
|
||||||
// +build example
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
// Simple lexem stack implementation.
|
// Simple lexem stack implementation.
|
||||||
|
|
Loading…
Reference in a new issue