-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathc.go
124 lines (106 loc) · 2.31 KB
/
c.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
package nocomment
type state interface {
Next(in rune) state
Result() []rune
}
type cState int
const (
normalState cState = iota
normalEscapeState
normalSlashState
normalEscapedSlashState
quoteState
quoteEscapeState
lineCommentState
blockCommentState
blockCommentStarState
)
// StripCStyleComments removes C-Style line- and block comments from the provided string
// C-Style comments have two different variations://
// - line comments start with // and end at the next \n
// - block comments start with /* and end with */
//
// Comments cannot start within double-quoted regions. These regions can span multiple lines if the
// new-line character \n is escaped with a backslash.
// Backslashes can also be escaped with backslashes.
func StripCStyleComments(input string) string {
var s, out string
state := normalState
for _, r := range input {
s, state = parseNextRune(state, r)
out += s
}
if state == normalSlashState {
out += "/"
}
return out
}
func parseNextRune(state cState, r rune) (string, cState) {
rStr := string(r)
switch state {
case normalState:
switch r {
case '\\':
return rStr, normalEscapeState
case '"':
return rStr, quoteState
case '/':
return "", normalSlashState
}
return rStr, state
case normalEscapeState:
if r == '/' {
return "", normalEscapedSlashState
}
return rStr, normalState
case normalEscapedSlashState:
switch r {
case '/':
return "", lineCommentState
case '*':
return "", blockCommentState
case '"':
return "/" + rStr, quoteState
}
return "/" + rStr, normalState
case quoteState:
switch r {
case '\\':
return rStr, quoteEscapeState
case '"':
return rStr, normalState
case '\n':
return rStr, normalState
}
return rStr, state
case quoteEscapeState:
return rStr, quoteState
case normalSlashState:
switch r {
case '/':
return "", lineCommentState
case '*':
return "", blockCommentState
}
return "/" + rStr, normalState
case lineCommentState:
if r == '\n' {
return rStr, normalState
}
return "", state
case blockCommentState:
if r == '*' {
return "", blockCommentStarState
}
return "", state
case blockCommentStarState:
switch r {
case '/':
return "", normalState
case '*':
return "", state
}
return "", blockCommentState
}
return "", state // cannot reach
}