Fix example

This commit is contained in:
Alexander Kiryukhin 2022-02-02 22:17:30 +03:00
parent d8d462d3f9
commit 9489f783e5
No known key found for this signature in database
GPG key ID: 6DF7A2910D0699E9
3 changed files with 25 additions and 25 deletions

View file

@ -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:

View file

@ -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)})
} }
} }
} }

View file

@ -1,6 +1,3 @@
//go:build example
// +build example
package main package main
// Simple lexem stack implementation. // Simple lexem stack implementation.