-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathMain_Program.go
128 lines (112 loc) · 2.94 KB
/
Main_Program.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package main
import (
"fmt"
"strconv"
"strings"
"unicode"
)
type TokenType int
const (
IF TokenType = iota
ELSE
VAR
IDENTIFIER
INTEGER
OPERATOR
)
type Token struct {
Type TokenType
Value string
}
func lexer(input string) []Token {
var tokens []Token
var currentToken strings.Builder
for _, char := range input {
if unicode.IsSpace(char) {
if currentToken.Len() > 0 {
tokens = append(tokens, identifyToken(currentToken.String()))
currentToken.Reset()
}
continue
}
if char == '=' || char == '+' || char == '-' || char == '*' || char == '/' {
if currentToken.Len() > 0 {
tokens = append(tokens, identifyToken(currentToken.String()))
currentToken.Reset()
}
tokens = append(tokens, Token{Type: OPERATOR, Value: string(char)})
continue
}
currentToken.WriteRune(char)
}
if currentToken.Len() > 0 {
tokens = append(tokens, identifyToken(currentToken.String()))
}
return tokens
}
func identifyToken(token string) Token {
switch token {
case "if":
return Token{Type: IF, Value: token}
case "else":
return Token{Type: ELSE, Value: token}
case "var":
return Token{Type: VAR, Value: token}
default:
if _, err := strconv.Atoi(token); err == nil {
return Token{Type: INTEGER, Value: token}
} else {
return Token{Type: IDENTIFIER, Value: token}
}
}
}
func parser(tokens []Token) string {
var generatedCode strings.Builder
i := 0
for i < len(tokens) {
token := tokens[i]
switch token.Type {
case IF:
generatedCode.WriteString("if ")
i++
for i < len(tokens) && tokens[i].Type != ELSE {
generatedCode.WriteString(tokens[i].Value + " ")
i++
}
generatedCode.WriteString("{\n")
if i < len(tokens) && tokens[i].Type == ELSE {
generatedCode.WriteString("} else {\n")
i++
} else {
generatedCode.WriteString("}\n")
}
case VAR:
generatedCode.WriteString("var ")
i++
for i < len(tokens) && tokens[i].Type != IF && tokens[i].Type != ELSE {
generatedCode.WriteString(tokens[i].Value + " ")
i++
}
generatedCode.WriteString("\n")
default:
generatedCode.WriteString(token.Value + " ")
i++
for i < len(tokens) && tokens[i].Type != IF && tokens[i].Type != ELSE {
generatedCode.WriteString(tokens[i].Value + " ")
i++
}
generatedCode.WriteString("\n")
}
}
return generatedCode.String()
}
func main() {
fmt.Println("*******************************************************************************************************************************************")
input := `var x = 5 if x > 3 { var y = 10 } else { var z = 20 }`
tokens := lexer(input)
fmt.Println("Berikut adalah hasil dari fungsi lexer yang memecah input string menjadi token-token yang dapat diidentifikasi oleh parser.")
fmt.Println(tokens)
fmt.Println("*******************************************************************************************************************************************")
generatedCode := parser(tokens)
fmt.Println(generatedCode)
}