diff options
author | Alexander Kiryukhin <a.kiryukhin@mail.ru> | 2022-06-13 04:31:31 +0300 |
---|---|---|
committer | Alexander Kiryukhin <a.kiryukhin@mail.ru> | 2022-06-13 04:31:31 +0300 |
commit | 05626592208f56d88523887e2b80c0514f8ac210 (patch) | |
tree | b0db34890e7366008754e975a8f28e878c5b28bf /itr.go |
initial
Diffstat (limited to 'itr.go')
-rw-r--r-- | itr.go | 78 |
1 files changed, 78 insertions, 0 deletions
@@ -0,0 +1,78 @@ +package lexpr + +import "context" + +func infixToRpn(ctx context.Context, tokens <-chan Token) <-chan Token { + out := make(chan Token) + stack := TokenStack{} + go func() { + defer func() { + if len(stack) > 0 { + for { + if stack.Head().typ == lp { + out <- Token{ + typ: tokError, + value: "invalid brakets", + } + break + } + out <- stack.Pop() + if len(stack) == 0 { + break + } + } + } + close(out) + }() + for { + select { + case <-ctx.Done(): + return + case tkn, ok := <-tokens: + if !ok { + return + } + switch tkn.typ { + case number, word, str, tokError: + out <- tkn + case funct: + stack.Push(tkn) + case sep: + for stack.Head().typ != lp { + if len(stack) == 0 { + out <- Token{ + typ: tokError, + value: "no arg separator or opening braket", + } + return + } + out <- stack.Pop() + } + case op: + for len(stack) > 0 && (stack.Head().typ != op || (stack.Head().priority >= tkn.priority)) { + out <- stack.Pop() + } + stack.Push(tkn) + case lp: + stack.Push(tkn) + case rp: + for stack.Head().typ != lp { + if len(stack) == 0 { + out <- Token{ + typ: tokError, + value: "no opening braket", + } + return + } + out <- stack.Pop() + } + stack.Pop() + if stack.Head().typ == funct { + out <- stack.Pop() + } + } + } + } + }() + return out +} |