Skip to content

Commit 565d1f1

Browse files
authored
Merge pull request #51 from yoheimuta/fix-empty-field-within-option
Fix empty field within option
2 parents d1b02ac + 7282b37 commit 565d1f1

File tree

4 files changed

+55
-4
lines changed

4 files changed

+55
-4
lines changed

internal/lexer/lexer.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ func (lex *Lexer) Next() {
9191
}
9292
}
9393

94+
// NextN scans the read buffer nth times.
95+
func (lex *Lexer) NextN(n int) {
96+
for 0 < n {
97+
lex.Next()
98+
n--
99+
}
100+
}
101+
94102
// NextKeywordOrStrLit scans the read buffer with ScanKeyword or ScanStrLit modes.
95103
func (lex *Lexer) NextKeywordOrStrLit() {
96104
lex.nextWithSpecificMode(scanner.ScanKeyword | scanner.ScanStrLit)
@@ -148,6 +156,21 @@ func (lex *Lexer) Peek() scanner.Token {
148156
return lex.Token
149157
}
150158

159+
// PeekN returns the nth next token with keeping the read buffer unchanged.
160+
func (lex *Lexer) PeekN(n int) scanner.Token {
161+
var lasts [][]rune
162+
for 0 < n {
163+
lex.Next()
164+
lasts = append(lasts, lex.RawText)
165+
n--
166+
}
167+
token := lex.Token
168+
for i := len(lasts) - 1; 0 <= i; i-- {
169+
lex.UnNextTo(lasts[i])
170+
}
171+
return token
172+
}
173+
151174
// UnNext put the latest text back to the read buffer.
152175
func (lex *Lexer) UnNext() {
153176
lex.scanner.UnScan()

internal/lexer/scanner/position.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ func (pos Position) String() string {
3333

3434
// Advance advances the position value.
3535
func (pos *Position) Advance(r rune) {
36-
len := utf8.RuneLen(r)
37-
pos.Offset += len
36+
length := utf8.RuneLen(r)
37+
pos.Offset += length
3838

3939
if r == '\n' {
4040
pos.columns[pos.Line] = pos.Column
@@ -48,8 +48,8 @@ func (pos *Position) Advance(r rune) {
4848

4949
// Revert reverts the position value.
5050
func (pos *Position) Revert(r rune) {
51-
len := utf8.RuneLen(r)
52-
pos.Offset -= len
51+
length := utf8.RuneLen(r)
52+
pos.Offset -= length
5353

5454
if r == '\n' {
5555
pos.Line--

parser/option.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,12 @@ func (p *Parser) parseOptionConstant() (constant string, err error) {
194194
return "", p.unexpected("constant or permissive mode")
195195
}
196196

197+
// parses empty fields within an option
198+
if p.lex.PeekN(2) == scanner.TRIGHTCURLY {
199+
p.lex.NextN(2)
200+
return "{}", nil
201+
}
202+
197203
constant, err = p.parseCloudEndpointsOptionConstant()
198204
if err != nil {
199205
return "", err

parser/option_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,28 @@ option (google.api.http) = {
188188
},
189189
},
190190
},
191+
{
192+
name: "parses empty fields within an option",
193+
input: `
194+
option (opt) = {
195+
empty : {},
196+
inner_empty : {
197+
empty : {},
198+
},
199+
};`,
200+
permissive: true,
201+
wantOption: &parser.Option{
202+
OptionName: "(opt)",
203+
Constant: `{empty:{},inner_empty:{empty:{},},}`,
204+
Meta: meta.Meta{
205+
Pos: meta.Position{
206+
Offset: 1,
207+
Line: 2,
208+
Column: 1,
209+
},
210+
},
211+
},
212+
},
191213
}
192214

193215
for _, test := range tests {

0 commit comments

Comments
 (0)