Last active
September 4, 2021 14:02
-
-
Save t-sin/09f9ab7f0f221b5d2fcd6f3204e560b3 to your computer and use it in GitHub Desktop.
Goで電卓レッツ&ゴー!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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