diff --git a/example/math_expression/main.go b/example/math_expression/main.go index bfece39..805028e 100644 --- a/example/math_expression/main.go +++ b/example/math_expression/main.go @@ -1,5 +1,3 @@ -// +build example - package main import ( @@ -8,6 +6,13 @@ import ( "github.com/neonxp/unilex" ) +const ( + LP unilex.LexType = iota + RP + NUMBER + OPERATOR +) + func main() { l := unilex.New("10 * (20.0 + 30.0)") @@ -29,13 +34,13 @@ func lexExpression(l *unilex.Lexer) unilex.StateFunc { switch { case l.Accept("("): - l.Emit("LP") + l.Emit(LP) case l.Accept(")"): - l.Emit("RP") + l.Emit(RP) case unilex.ScanNumber(l): - l.Emit("NUMBER") + l.Emit(NUMBER) case l.Accept("+-*/^!"): - l.Emit("OPERATOR") + l.Emit(OPERATOR) case l.Peek() == unilex.EOF: return nil default: diff --git a/example/math_expression/rpn.go b/example/math_expression/rpn.go index 84de59c..a4cacc0 100644 --- a/example/math_expression/rpn.go +++ b/example/math_expression/rpn.go @@ -1,5 +1,3 @@ -// +build example - package main // Helper functions to convert infix notation to RPN and calculates expression result. @@ -29,36 +27,36 @@ parseLoop: fmt.Printf("Lexem: %+v\n", ll) switch { - case ll.Type == "NUMBER", ll.Type == "OPERATOR" && ll.Value == "!": + case ll.Type == NUMBER, ll.Type == OPERATOR && ll.Value == "!": output = append(output, ll) - case ll.Type == "LP": + case ll.Type == LP: stack.Push(ll) - case ll.Type == "RP": + case ll.Type == RP: for { cl := stack.Pop() - if cl.Type == "LP" { + if cl.Type == LP { break } - if cl.Type == unilex.LEOF { + if cl.Type == unilex.LexEOF { log.Fatalf("No pair for parenthesis at %d", ll.Start) } output = append(output, cl) } - case ll.Type == "OPERATOR": + case ll.Type == OPERATOR: 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()) continue } break } stack.Push(ll) - case ll.Type == unilex.LEOF: + case ll.Type == unilex.LexEOF: break parseLoop } } - for stack.Head().Type != unilex.LEOF { + for stack.Head().Type != unilex.LexEOF { output = append(output, stack.Pop()) } @@ -68,26 +66,26 @@ parseLoop: func calculateRPN(rpnLexems []unilex.Lexem) string { stack := lexemStack{} for _, op := range rpnLexems { - if op.Type == "NUMBER" { + if op.Type == NUMBER { stack.Push(op) } else { switch op.Value { case "+": a1, _ := 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 "-": a1, _ := 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 "*": a1, _ := 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 "/": a1, _ := 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)}) } } } diff --git a/example/math_expression/stack.go b/example/math_expression/stack.go index eebd476..5244f7c 100644 --- a/example/math_expression/stack.go +++ b/example/math_expression/stack.go @@ -1,6 +1,3 @@ -//go:build example -// +build example - package main // Simple lexem stack implementation.