Skip to content

Instantly share code, notes, and snippets.

@t-sin
Last active September 4, 2021 14:02
Show Gist options
  • Save t-sin/09f9ab7f0f221b5d2fcd6f3204e560b3 to your computer and use it in GitHub Desktop.
Save t-sin/09f9ab7f0f221b5d2fcd6f3204e560b3 to your computer and use it in GitHub Desktop.
Goで電卓レッツ&ゴー!
package main
import (
"fmt"
"os"
"unicode"
)
type TokenType int
// トークンの種類
const (
TokenInteger TokenType = iota
TokenOperator
TokenParen
)
type Token struct {
Type TokenType
Str string
}
func tokenize(input string) ([]Token, error) {
inputr := []rune(input)
tokens := make([]Token, 0)
i := 0
for ; i < len(inputr); i += 1 {
r := inputr[i]
if r == '+' {
tokens = append(tokens, Token{Type: TokenOperator, Str: "+"})
} else if r == '-' {
tokens = append(tokens, Token{Type: TokenOperator, Str: "-"})
} else if r == '*' {
tokens = append(tokens, Token{Type: TokenOperator, Str: "*"})
} else if r == '/' {
tokens = append(tokens, Token{Type: TokenOperator, Str: "/"})
} else if unicode.IsDigit(r) {
num := fmt.Sprintf("%c", r)
i += 1
for ; i < len(inputr); i += 1 {
r := inputr[i]
if !unicode.IsDigit(inputr[i]) {
i -= 1
break
}
num = fmt.Sprintf("%s%c", num, r)
}
tokens = append(tokens, Token{Type: TokenInteger, Str: num})
} else if r == '(' {
tokens = append(tokens, Token{Type: TokenParen, Str: "("})
} else if r == ')' {
tokens = append(tokens, Token{Type: TokenParen, Str: ")"})
} else if r == ' ' {
// なにもしない
} else {
return nil, fmt.Errorf("なにこの文字: '%c'", r)
}
}
return tokens, nil
}
// 電卓で扱う式は以下の条件を満たすもの:
// 1. 整数は式である -> "1", "-10"
// 2. `式 演算子 式`は式である -> "10 + 2", "(1 + 3) + 4"
// 3. 1, 2を満たすもののみが式
type Integer int
type Operator int
const (
OperatorPlus Operator = iota
OperatorMinus
OperatorMultiply
OperatorDivide
)
type SyntaxType int
const (
SyntaxInteger SyntaxType = iota
SyntaxOperation
)
type Expression struct {
Type SyntaxType
Integer Integer
Operation *Operation
}
type Operation struct {
Operator Operator
Operand1 *Expression
Operand2 *Expression
}
func parse(tokens []Token) (*Expression, error) {
return nil, nil
}
func evaluate(exp *Expression) int {
return 0
}
func main() {
input := "105 ( + 2 ) ) * 3"
tokens, err := tokenize(input)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("tokens = %v\n", tokens)
exp, err := parse(tokens)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
result := evaluate(exp)
fmt.Printf("result = %d\n", result)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment