feat(gitconfig): Improve parser

This commit is contained in:
Myzel394 2024-10-12 15:24:54 +02:00
parent 5c4f2d6aff
commit 3860c73403
No known key found for this signature in database
GPG Key ID: ED20A1D1D423AF3F
14 changed files with 717 additions and 198 deletions

View File

@ -1,15 +1,15 @@
grammar Config; grammar Config;
lineStatement lineStatement
: entry EOF : WHITESPACE? entry WHITESPACE? leadingComment? EOF
; ;
entry entry
: WHITESPACE? key? separator? value? leadingComment? : key? WHITESPACE? separator? WHITESPACE? value?
; ;
leadingComment leadingComment
: HASH WHITESPACE? (string WHITESPACE?)+ : commentSymbol WHITESPACE? (string WHITESPACE?)+
; ;
key key
@ -25,7 +25,11 @@ value
; ;
string string
: (QUOTED_STRING | STRING) : (QUOTED_STRING | (WHITESPACE? (STRING WHITESPACE)* STRING))
;
commentSymbol
: HASH | SEMICOLON
; ;
/////////////////////////////////////////////// ///////////////////////////////////////////////
@ -38,12 +42,16 @@ HASH
: '#' : '#'
; ;
SEMICOLON
: ';'
;
WHITESPACE WHITESPACE
: [ \t]+ : [ \t]+
; ;
STRING STRING
: ~('#' | '\r' | '\n' | '"' | ' ' | '\t')+ : ~('\r' | '\n' | '"' | ' ' | '\t')+
; ;
QUOTED_STRING QUOTED_STRING

View File

@ -17,11 +17,16 @@ type GitSeparator struct {
Value parser.ParsedString Value parser.ParsedString
} }
type GitValue struct { type GitValuePart struct {
common.LocationRange common.LocationRange
Value parser.ParsedString Value parser.ParsedString
} }
type GitValue struct {
Raw common.VirtualLine
Value string
}
type GitEntry struct { type GitEntry struct {
common.LocationRange common.LocationRange
Key *GitKey Key *GitKey
@ -31,7 +36,7 @@ type GitEntry struct {
type GitSectionHeader struct { type GitSectionHeader struct {
common.LocationRange common.LocationRange
Title *parser.ParsedString Title string
} }
type GitSection struct { type GitSection struct {
@ -44,4 +49,3 @@ type GitConfig struct {
Sections []*GitSection Sections []*GitSection
CommentLines map[uint32]struct{} CommentLines map[uint32]struct{}
} }

View File

@ -2,5 +2,5 @@ package ast
func (c *GitConfig) Clear() { func (c *GitConfig) Clear() {
c.Sections = []*GitSection{} c.Sections = []*GitSection{}
c.CommentLines = map[uint32]struct{}{}
} }

View File

@ -10,12 +10,14 @@ type gitconfigListenerContext struct {
line uint32 line uint32
currentSection *GitSection currentSection *GitSection
currentEntry *GitEntry currentEntry *GitEntry
isWaitingForNextSection bool
virtualLine common.VirtualLine
} }
func createListenerContext() *gitconfigListenerContext { func createListenerContext() *gitconfigListenerContext {
context := new(gitconfigListenerContext) return &gitconfigListenerContext{
isWaitingForNextSection: false,
return context }
} }
type gitconfigParserListener struct { type gitconfigParserListener struct {
@ -51,6 +53,10 @@ func (s *gitconfigParserListener) EnterEntry(ctx *parser.EntryContext) {
} }
func (s *gitconfigParserListener) ExitEntry(ctx *parser.EntryContext) { func (s *gitconfigParserListener) ExitEntry(ctx *parser.EntryContext) {
if s.gitconfigContext.currentEntry.Value != nil {
s.gitconfigContext.currentEntry.End = s.gitconfigContext.currentEntry.Value.Raw.End
}
s.gitconfigContext.currentEntry = nil s.gitconfigContext.currentEntry = nil
} }
@ -84,12 +90,18 @@ func (s *gitconfigParserListener) EnterValue(ctx *parser.ValueContext) {
location := common.CharacterRangeFromCtx(ctx.BaseParserRuleContext) location := common.CharacterRangeFromCtx(ctx.BaseParserRuleContext)
location.ChangeBothLines(s.gitconfigContext.line) location.ChangeBothLines(s.gitconfigContext.line)
text := ctx.GetText() virtualLine := s.gitconfigContext.virtualLine.GetSubset(location.Start.Character, location.End.Character).AsTrimmed()
value := commonparser.ParseRawString(text, commonparser.FullFeatures) value := commonparser.ParseRawString(
virtualLine.GetText(),
commonparser.ParseFeatures{
ParseDoubleQuotes: true,
TrimWhitespace: false,
ParseEscapedCharacters: false,
Replacements: &map[string]string{},
},
).Value
s.gitconfigContext.currentEntry.Value = &GitValue{ s.gitconfigContext.currentEntry.Value = &GitValue{
LocationRange: location, Raw: virtualLine,
Value: value, Value: value,
} }
} }

View File

@ -2,11 +2,15 @@ package ast
import ( import (
"config-lsp/common" "config-lsp/common"
"config-lsp/utils" "config-lsp/handlers/gitconfig/ast/parser"
"errors"
"regexp" "regexp"
"strings" "strings"
"github.com/antlr4-go/antlr/v4" "github.com/antlr4-go/antlr/v4"
"github.com/emirpasic/gods/maps/treemap"
gods "github.com/emirpasic/gods/utils"
protocol "github.com/tliron/glsp/protocol_3_16" protocol "github.com/tliron/glsp/protocol_3_16"
) )
@ -17,17 +21,20 @@ func NewGitConfig() *GitConfig {
return config return config
} }
var commentPattern = regexp.MustCompile(`^\s*#`) var commentPattern = regexp.MustCompile(`^\s*[#;]`)
var emptyLinePattern = regexp.MustCompile(`^\s*$`) var emptyLinePattern = regexp.MustCompile(`^\s*$`)
var headerPattern = regexp.MustCompile(`^\s*\[`) var headerPattern = regexp.MustCompile(`^\s*\[`)
func (c *GitConfig) Parse(input string) []common.LSPError { func (c *GitConfig) Parse(input string) []common.LSPError {
errors := make([]common.LSPError, 0) errs := make([]common.LSPError, 0)
lines := utils.SplitIntoLines(input) lines := common.SplitIntoVirtualLines(input)
context := createListenerContext() context := createListenerContext()
for rawLineNumber, line := range lines { for _, virtualLine := range lines {
lineNumber := uint32(rawLineNumber) lineNumber := uint32(virtualLine.Parts[0].Start.Line)
line := virtualLine.GetText()
context.line = lineNumber
context.virtualLine = virtualLine
if emptyLinePattern.MatchString(line) { if emptyLinePattern.MatchString(line) {
continue continue
@ -40,15 +47,41 @@ func (c *GitConfig) Parse(input string) []common.LSPError {
if headerPattern.MatchString(line) { if headerPattern.MatchString(line) {
c.parseHeader(context, line) c.parseHeader(context, line)
continue
} }
errors = append( if context.currentSection == nil {
errors, if !context.isWaitingForNextSection {
context.isWaitingForNextSection = true
errs = append(errs, common.LSPError{
Range: common.LocationRange{
Start: common.Location{
Line: lineNumber,
Character: 0,
},
End: common.Location{
Line: lineNumber,
Character: uint32(len(line)),
},
},
Err: errors.New(`This section is missing a header (e.g. "[section]")`),
})
}
continue
}
context.isWaitingForNextSection = false
errs = append(
errs,
c.parseStatement(context, line)..., c.parseStatement(context, line)...,
) )
} }
return errors return errs
} }
func (c *GitConfig) parseHeader( func (c *GitConfig) parseHeader(
@ -112,6 +145,26 @@ func (c *GitConfig) parseHeader(
} }
} }
location := common.LocationRange{
Start: common.Location{
Line: context.line,
Character: uint32(leftBracketIndex),
},
End: common.Location{
Line: context.line,
Character: uint32(rightBracketIndex + 1),
},
}
context.currentSection = &GitSection{
LocationRange: location,
Title: &GitSectionHeader{
LocationRange: location,
Title: input[leftBracketIndex+1 : rightBracketIndex],
},
Entries: treemap.NewWith(gods.UInt32Comparator),
}
c.Sections = append(c.Sections, context.currentSection)
return nil return nil
} }
@ -145,4 +198,3 @@ func (c *GitConfig) parseStatement(
return errors return errors
} }

View File

@ -2,6 +2,7 @@ token literal names:
null null
'=' '='
'#' '#'
';'
null null
null null
null null
@ -10,6 +11,7 @@ token symbolic names:
null null
EQUAL EQUAL
HASH HASH
SEMICOLON
WHITESPACE WHITESPACE
STRING STRING
QUOTED_STRING QUOTED_STRING
@ -22,7 +24,8 @@ key
separator separator
value value
string string
commentSymbol
atn: atn:
[4, 1, 5, 53, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 1, 0, 1, 0, 1, 0, 1, 1, 3, 1, 19, 8, 1, 1, 1, 3, 1, 22, 8, 1, 1, 1, 3, 1, 25, 8, 1, 1, 1, 3, 1, 28, 8, 1, 1, 1, 3, 1, 31, 8, 1, 1, 2, 1, 2, 3, 2, 35, 8, 2, 1, 2, 1, 2, 3, 2, 39, 8, 2, 4, 2, 41, 8, 2, 11, 2, 12, 2, 42, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 0, 0, 7, 0, 2, 4, 6, 8, 10, 12, 0, 1, 1, 0, 4, 5, 53, 0, 14, 1, 0, 0, 0, 2, 18, 1, 0, 0, 0, 4, 32, 1, 0, 0, 0, 6, 44, 1, 0, 0, 0, 8, 46, 1, 0, 0, 0, 10, 48, 1, 0, 0, 0, 12, 50, 1, 0, 0, 0, 14, 15, 3, 2, 1, 0, 15, 16, 5, 0, 0, 1, 16, 1, 1, 0, 0, 0, 17, 19, 5, 3, 0, 0, 18, 17, 1, 0, 0, 0, 18, 19, 1, 0, 0, 0, 19, 21, 1, 0, 0, 0, 20, 22, 3, 6, 3, 0, 21, 20, 1, 0, 0, 0, 21, 22, 1, 0, 0, 0, 22, 24, 1, 0, 0, 0, 23, 25, 3, 8, 4, 0, 24, 23, 1, 0, 0, 0, 24, 25, 1, 0, 0, 0, 25, 27, 1, 0, 0, 0, 26, 28, 3, 10, 5, 0, 27, 26, 1, 0, 0, 0, 27, 28, 1, 0, 0, 0, 28, 30, 1, 0, 0, 0, 29, 31, 3, 4, 2, 0, 30, 29, 1, 0, 0, 0, 30, 31, 1, 0, 0, 0, 31, 3, 1, 0, 0, 0, 32, 34, 5, 2, 0, 0, 33, 35, 5, 3, 0, 0, 34, 33, 1, 0, 0, 0, 34, 35, 1, 0, 0, 0, 35, 40, 1, 0, 0, 0, 36, 38, 3, 12, 6, 0, 37, 39, 5, 3, 0, 0, 38, 37, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 41, 1, 0, 0, 0, 40, 36, 1, 0, 0, 0, 41, 42, 1, 0, 0, 0, 42, 40, 1, 0, 0, 0, 42, 43, 1, 0, 0, 0, 43, 5, 1, 0, 0, 0, 44, 45, 3, 12, 6, 0, 45, 7, 1, 0, 0, 0, 46, 47, 5, 1, 0, 0, 47, 9, 1, 0, 0, 0, 48, 49, 3, 12, 6, 0, 49, 11, 1, 0, 0, 0, 50, 51, 7, 0, 0, 0, 51, 13, 1, 0, 0, 0, 8, 18, 21, 24, 27, 30, 34, 38, 42] [4, 1, 6, 78, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 1, 0, 3, 0, 18, 8, 0, 1, 0, 1, 0, 3, 0, 22, 8, 0, 1, 0, 3, 0, 25, 8, 0, 1, 0, 1, 0, 1, 1, 3, 1, 30, 8, 1, 1, 1, 3, 1, 33, 8, 1, 1, 1, 3, 1, 36, 8, 1, 1, 1, 3, 1, 39, 8, 1, 1, 1, 3, 1, 42, 8, 1, 1, 2, 1, 2, 3, 2, 46, 8, 2, 1, 2, 1, 2, 3, 2, 50, 8, 2, 4, 2, 52, 8, 2, 11, 2, 12, 2, 53, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 3, 6, 64, 8, 6, 1, 6, 1, 6, 5, 6, 68, 8, 6, 10, 6, 12, 6, 71, 9, 6, 1, 6, 3, 6, 74, 8, 6, 1, 7, 1, 7, 1, 7, 0, 0, 8, 0, 2, 4, 6, 8, 10, 12, 14, 0, 1, 1, 0, 2, 3, 83, 0, 17, 1, 0, 0, 0, 2, 29, 1, 0, 0, 0, 4, 43, 1, 0, 0, 0, 6, 55, 1, 0, 0, 0, 8, 57, 1, 0, 0, 0, 10, 59, 1, 0, 0, 0, 12, 73, 1, 0, 0, 0, 14, 75, 1, 0, 0, 0, 16, 18, 5, 4, 0, 0, 17, 16, 1, 0, 0, 0, 17, 18, 1, 0, 0, 0, 18, 19, 1, 0, 0, 0, 19, 21, 3, 2, 1, 0, 20, 22, 5, 4, 0, 0, 21, 20, 1, 0, 0, 0, 21, 22, 1, 0, 0, 0, 22, 24, 1, 0, 0, 0, 23, 25, 3, 4, 2, 0, 24, 23, 1, 0, 0, 0, 24, 25, 1, 0, 0, 0, 25, 26, 1, 0, 0, 0, 26, 27, 5, 0, 0, 1, 27, 1, 1, 0, 0, 0, 28, 30, 3, 6, 3, 0, 29, 28, 1, 0, 0, 0, 29, 30, 1, 0, 0, 0, 30, 32, 1, 0, 0, 0, 31, 33, 5, 4, 0, 0, 32, 31, 1, 0, 0, 0, 32, 33, 1, 0, 0, 0, 33, 35, 1, 0, 0, 0, 34, 36, 3, 8, 4, 0, 35, 34, 1, 0, 0, 0, 35, 36, 1, 0, 0, 0, 36, 38, 1, 0, 0, 0, 37, 39, 5, 4, 0, 0, 38, 37, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 41, 1, 0, 0, 0, 40, 42, 3, 10, 5, 0, 41, 40, 1, 0, 0, 0, 41, 42, 1, 0, 0, 0, 42, 3, 1, 0, 0, 0, 43, 45, 3, 14, 7, 0, 44, 46, 5, 4, 0, 0, 45, 44, 1, 0, 0, 0, 45, 46, 1, 0, 0, 0, 46, 51, 1, 0, 0, 0, 47, 49, 3, 12, 6, 0, 48, 50, 5, 4, 0, 0, 49, 48, 1, 0, 0, 0, 49, 50, 1, 0, 0, 0, 50, 52, 1, 0, 0, 0, 51, 47, 1, 0, 0, 0, 52, 53, 1, 0, 0, 0, 53, 51, 1, 0, 0, 0, 53, 54, 1, 0, 0, 0, 54, 5, 1, 0, 0, 0, 55, 56, 3, 12, 6, 0, 56, 7, 1, 0, 0, 0, 57, 58, 5, 1, 0, 0, 58, 9, 1, 0, 0, 0, 59, 60, 3, 12, 6, 0, 60, 11, 1, 0, 0, 0, 61, 74, 5, 6, 0, 0, 62, 64, 5, 4, 0, 0, 63, 62, 1, 0, 0, 0, 63, 64, 1, 0, 0, 0, 64, 69, 1, 0, 0, 0, 65, 66, 5, 5, 0, 0, 66, 68, 5, 4, 0, 0, 67, 65, 1, 0, 0, 0, 68, 71, 1, 0, 0, 0, 69, 67, 1, 0, 0, 0, 69, 70, 1, 0, 0, 0, 70, 72, 1, 0, 0, 0, 71, 69, 1, 0, 0, 0, 72, 74, 5, 5, 0, 0, 73, 61, 1, 0, 0, 0, 73, 63, 1, 0, 0, 0, 74, 13, 1, 0, 0, 0, 75, 76, 7, 0, 0, 0, 76, 15, 1, 0, 0, 0, 14, 17, 21, 24, 29, 32, 35, 38, 41, 45, 49, 53, 63, 69, 73]

View File

@ -1,7 +1,9 @@
EQUAL=1 EQUAL=1
HASH=2 HASH=2
WHITESPACE=3 SEMICOLON=3
STRING=4 WHITESPACE=4
QUOTED_STRING=5 STRING=5
QUOTED_STRING=6
'='=1 '='=1
'#'=2 '#'=2
';'=3

View File

@ -2,6 +2,7 @@ token literal names:
null null
'=' '='
'#' '#'
';'
null null
null null
null null
@ -10,6 +11,7 @@ token symbolic names:
null null
EQUAL EQUAL
HASH HASH
SEMICOLON
WHITESPACE WHITESPACE
STRING STRING
QUOTED_STRING QUOTED_STRING
@ -17,6 +19,7 @@ QUOTED_STRING
rule names: rule names:
EQUAL EQUAL
HASH HASH
SEMICOLON
WHITESPACE WHITESPACE
STRING STRING
QUOTED_STRING QUOTED_STRING
@ -29,4 +32,4 @@ mode names:
DEFAULT_MODE DEFAULT_MODE
atn: atn:
[4, 0, 5, 43, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 4, 2, 17, 8, 2, 11, 2, 12, 2, 18, 1, 3, 4, 3, 22, 8, 3, 11, 3, 12, 3, 23, 1, 4, 1, 4, 3, 4, 28, 8, 4, 1, 4, 1, 4, 1, 4, 5, 4, 33, 8, 4, 10, 4, 12, 4, 36, 9, 4, 1, 4, 3, 4, 39, 8, 4, 1, 4, 3, 4, 42, 8, 4, 0, 0, 5, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 1, 0, 2, 2, 0, 9, 9, 32, 32, 4, 0, 9, 10, 13, 13, 32, 32, 34, 35, 48, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 1, 11, 1, 0, 0, 0, 3, 13, 1, 0, 0, 0, 5, 16, 1, 0, 0, 0, 7, 21, 1, 0, 0, 0, 9, 25, 1, 0, 0, 0, 11, 12, 5, 61, 0, 0, 12, 2, 1, 0, 0, 0, 13, 14, 5, 35, 0, 0, 14, 4, 1, 0, 0, 0, 15, 17, 7, 0, 0, 0, 16, 15, 1, 0, 0, 0, 17, 18, 1, 0, 0, 0, 18, 16, 1, 0, 0, 0, 18, 19, 1, 0, 0, 0, 19, 6, 1, 0, 0, 0, 20, 22, 8, 1, 0, 0, 21, 20, 1, 0, 0, 0, 22, 23, 1, 0, 0, 0, 23, 21, 1, 0, 0, 0, 23, 24, 1, 0, 0, 0, 24, 8, 1, 0, 0, 0, 25, 27, 5, 34, 0, 0, 26, 28, 3, 5, 2, 0, 27, 26, 1, 0, 0, 0, 27, 28, 1, 0, 0, 0, 28, 34, 1, 0, 0, 0, 29, 30, 3, 7, 3, 0, 30, 31, 3, 5, 2, 0, 31, 33, 1, 0, 0, 0, 32, 29, 1, 0, 0, 0, 33, 36, 1, 0, 0, 0, 34, 32, 1, 0, 0, 0, 34, 35, 1, 0, 0, 0, 35, 38, 1, 0, 0, 0, 36, 34, 1, 0, 0, 0, 37, 39, 3, 7, 3, 0, 38, 37, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 41, 1, 0, 0, 0, 40, 42, 5, 34, 0, 0, 41, 40, 1, 0, 0, 0, 41, 42, 1, 0, 0, 0, 42, 10, 1, 0, 0, 0, 7, 0, 18, 23, 27, 34, 38, 41, 0] [4, 0, 6, 47, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 4, 3, 21, 8, 3, 11, 3, 12, 3, 22, 1, 4, 4, 4, 26, 8, 4, 11, 4, 12, 4, 27, 1, 5, 1, 5, 3, 5, 32, 8, 5, 1, 5, 1, 5, 1, 5, 5, 5, 37, 8, 5, 10, 5, 12, 5, 40, 9, 5, 1, 5, 3, 5, 43, 8, 5, 1, 5, 3, 5, 46, 8, 5, 0, 0, 6, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 1, 0, 2, 2, 0, 9, 9, 32, 32, 4, 0, 9, 10, 13, 13, 32, 32, 34, 34, 52, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 1, 13, 1, 0, 0, 0, 3, 15, 1, 0, 0, 0, 5, 17, 1, 0, 0, 0, 7, 20, 1, 0, 0, 0, 9, 25, 1, 0, 0, 0, 11, 29, 1, 0, 0, 0, 13, 14, 5, 61, 0, 0, 14, 2, 1, 0, 0, 0, 15, 16, 5, 35, 0, 0, 16, 4, 1, 0, 0, 0, 17, 18, 5, 59, 0, 0, 18, 6, 1, 0, 0, 0, 19, 21, 7, 0, 0, 0, 20, 19, 1, 0, 0, 0, 21, 22, 1, 0, 0, 0, 22, 20, 1, 0, 0, 0, 22, 23, 1, 0, 0, 0, 23, 8, 1, 0, 0, 0, 24, 26, 8, 1, 0, 0, 25, 24, 1, 0, 0, 0, 26, 27, 1, 0, 0, 0, 27, 25, 1, 0, 0, 0, 27, 28, 1, 0, 0, 0, 28, 10, 1, 0, 0, 0, 29, 31, 5, 34, 0, 0, 30, 32, 3, 7, 3, 0, 31, 30, 1, 0, 0, 0, 31, 32, 1, 0, 0, 0, 32, 38, 1, 0, 0, 0, 33, 34, 3, 9, 4, 0, 34, 35, 3, 7, 3, 0, 35, 37, 1, 0, 0, 0, 36, 33, 1, 0, 0, 0, 37, 40, 1, 0, 0, 0, 38, 36, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 42, 1, 0, 0, 0, 40, 38, 1, 0, 0, 0, 41, 43, 3, 9, 4, 0, 42, 41, 1, 0, 0, 0, 42, 43, 1, 0, 0, 0, 43, 45, 1, 0, 0, 0, 44, 46, 5, 34, 0, 0, 45, 44, 1, 0, 0, 0, 45, 46, 1, 0, 0, 0, 46, 12, 1, 0, 0, 0, 7, 0, 22, 27, 31, 38, 42, 45, 0]

View File

@ -1,7 +1,9 @@
EQUAL=1 EQUAL=1
HASH=2 HASH=2
WHITESPACE=3 SEMICOLON=3
STRING=4 WHITESPACE=4
QUOTED_STRING=5 STRING=5
QUOTED_STRING=6
'='=1 '='=1
'#'=2 '#'=2
';'=3

View File

@ -62,3 +62,9 @@ func (s *BaseConfigListener) EnterString(ctx *StringContext) {}
// ExitString is called when production string is exited. // ExitString is called when production string is exited.
func (s *BaseConfigListener) ExitString(ctx *StringContext) {} func (s *BaseConfigListener) ExitString(ctx *StringContext) {}
// EnterCommentSymbol is called when production commentSymbol is entered.
func (s *BaseConfigListener) EnterCommentSymbol(ctx *CommentSymbolContext) {}
// ExitCommentSymbol is called when production commentSymbol is exited.
func (s *BaseConfigListener) ExitCommentSymbol(ctx *CommentSymbolContext) {}

View File

@ -43,36 +43,37 @@ func configlexerLexerInit() {
"DEFAULT_MODE", "DEFAULT_MODE",
} }
staticData.LiteralNames = []string{ staticData.LiteralNames = []string{
"", "'='", "'#'", "", "'='", "'#'", "';'",
} }
staticData.SymbolicNames = []string{ staticData.SymbolicNames = []string{
"", "EQUAL", "HASH", "WHITESPACE", "STRING", "QUOTED_STRING", "", "EQUAL", "HASH", "SEMICOLON", "WHITESPACE", "STRING", "QUOTED_STRING",
} }
staticData.RuleNames = []string{ staticData.RuleNames = []string{
"EQUAL", "HASH", "WHITESPACE", "STRING", "QUOTED_STRING", "EQUAL", "HASH", "SEMICOLON", "WHITESPACE", "STRING", "QUOTED_STRING",
} }
staticData.PredictionContextCache = antlr.NewPredictionContextCache() staticData.PredictionContextCache = antlr.NewPredictionContextCache()
staticData.serializedATN = []int32{ staticData.serializedATN = []int32{
4, 0, 5, 43, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 0, 6, 47, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2,
4, 7, 4, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 4, 2, 17, 8, 2, 11, 2, 12, 2, 18, 4, 7, 4, 2, 5, 7, 5, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 4, 3, 21,
1, 3, 4, 3, 22, 8, 3, 11, 3, 12, 3, 23, 1, 4, 1, 4, 3, 4, 28, 8, 4, 1, 8, 3, 11, 3, 12, 3, 22, 1, 4, 4, 4, 26, 8, 4, 11, 4, 12, 4, 27, 1, 5, 1,
4, 1, 4, 1, 4, 5, 4, 33, 8, 4, 10, 4, 12, 4, 36, 9, 4, 1, 4, 3, 4, 39, 5, 3, 5, 32, 8, 5, 1, 5, 1, 5, 1, 5, 5, 5, 37, 8, 5, 10, 5, 12, 5, 40,
8, 4, 1, 4, 3, 4, 42, 8, 4, 0, 0, 5, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 1, 0, 9, 5, 1, 5, 3, 5, 43, 8, 5, 1, 5, 3, 5, 46, 8, 5, 0, 0, 6, 1, 1, 3, 2,
2, 2, 0, 9, 9, 32, 32, 4, 0, 9, 10, 13, 13, 32, 32, 34, 35, 48, 0, 1, 1, 5, 3, 7, 4, 9, 5, 11, 6, 1, 0, 2, 2, 0, 9, 9, 32, 32, 4, 0, 9, 10, 13,
0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 13, 32, 32, 34, 34, 52, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0,
0, 0, 0, 1, 11, 1, 0, 0, 0, 3, 13, 1, 0, 0, 0, 5, 16, 1, 0, 0, 0, 7, 21, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 1, 13, 1,
1, 0, 0, 0, 9, 25, 1, 0, 0, 0, 11, 12, 5, 61, 0, 0, 12, 2, 1, 0, 0, 0, 0, 0, 0, 3, 15, 1, 0, 0, 0, 5, 17, 1, 0, 0, 0, 7, 20, 1, 0, 0, 0, 9, 25,
13, 14, 5, 35, 0, 0, 14, 4, 1, 0, 0, 0, 15, 17, 7, 0, 0, 0, 16, 15, 1, 1, 0, 0, 0, 11, 29, 1, 0, 0, 0, 13, 14, 5, 61, 0, 0, 14, 2, 1, 0, 0, 0,
0, 0, 0, 17, 18, 1, 0, 0, 0, 18, 16, 1, 0, 0, 0, 18, 19, 1, 0, 0, 0, 19, 15, 16, 5, 35, 0, 0, 16, 4, 1, 0, 0, 0, 17, 18, 5, 59, 0, 0, 18, 6, 1,
6, 1, 0, 0, 0, 20, 22, 8, 1, 0, 0, 21, 20, 1, 0, 0, 0, 22, 23, 1, 0, 0, 0, 0, 0, 19, 21, 7, 0, 0, 0, 20, 19, 1, 0, 0, 0, 21, 22, 1, 0, 0, 0, 22,
0, 23, 21, 1, 0, 0, 0, 23, 24, 1, 0, 0, 0, 24, 8, 1, 0, 0, 0, 25, 27, 5, 20, 1, 0, 0, 0, 22, 23, 1, 0, 0, 0, 23, 8, 1, 0, 0, 0, 24, 26, 8, 1, 0,
34, 0, 0, 26, 28, 3, 5, 2, 0, 27, 26, 1, 0, 0, 0, 27, 28, 1, 0, 0, 0, 28, 0, 25, 24, 1, 0, 0, 0, 26, 27, 1, 0, 0, 0, 27, 25, 1, 0, 0, 0, 27, 28,
34, 1, 0, 0, 0, 29, 30, 3, 7, 3, 0, 30, 31, 3, 5, 2, 0, 31, 33, 1, 0, 0, 1, 0, 0, 0, 28, 10, 1, 0, 0, 0, 29, 31, 5, 34, 0, 0, 30, 32, 3, 7, 3, 0,
0, 32, 29, 1, 0, 0, 0, 33, 36, 1, 0, 0, 0, 34, 32, 1, 0, 0, 0, 34, 35, 31, 30, 1, 0, 0, 0, 31, 32, 1, 0, 0, 0, 32, 38, 1, 0, 0, 0, 33, 34, 3,
1, 0, 0, 0, 35, 38, 1, 0, 0, 0, 36, 34, 1, 0, 0, 0, 37, 39, 3, 7, 3, 0, 9, 4, 0, 34, 35, 3, 7, 3, 0, 35, 37, 1, 0, 0, 0, 36, 33, 1, 0, 0, 0, 37,
38, 37, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 41, 1, 0, 0, 0, 40, 42, 5, 40, 1, 0, 0, 0, 38, 36, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 42, 1, 0, 0,
34, 0, 0, 41, 40, 1, 0, 0, 0, 41, 42, 1, 0, 0, 0, 42, 10, 1, 0, 0, 0, 7, 0, 40, 38, 1, 0, 0, 0, 41, 43, 3, 9, 4, 0, 42, 41, 1, 0, 0, 0, 42, 43,
0, 18, 23, 27, 34, 38, 41, 0, 1, 0, 0, 0, 43, 45, 1, 0, 0, 0, 44, 46, 5, 34, 0, 0, 45, 44, 1, 0, 0, 0,
45, 46, 1, 0, 0, 0, 46, 12, 1, 0, 0, 0, 7, 0, 22, 27, 31, 38, 42, 45, 0,
} }
deserializer := antlr.NewATNDeserializer(nil) deserializer := antlr.NewATNDeserializer(nil)
staticData.atn = deserializer.Deserialize(staticData.serializedATN) staticData.atn = deserializer.Deserialize(staticData.serializedATN)
@ -115,7 +116,8 @@ func NewConfigLexer(input antlr.CharStream) *ConfigLexer {
const ( const (
ConfigLexerEQUAL = 1 ConfigLexerEQUAL = 1
ConfigLexerHASH = 2 ConfigLexerHASH = 2
ConfigLexerWHITESPACE = 3 ConfigLexerSEMICOLON = 3
ConfigLexerSTRING = 4 ConfigLexerWHITESPACE = 4
ConfigLexerQUOTED_STRING = 5 ConfigLexerSTRING = 5
ConfigLexerQUOTED_STRING = 6
) )

View File

@ -29,6 +29,9 @@ type ConfigListener interface {
// EnterString is called when entering the string production. // EnterString is called when entering the string production.
EnterString(c *StringContext) EnterString(c *StringContext)
// EnterCommentSymbol is called when entering the commentSymbol production.
EnterCommentSymbol(c *CommentSymbolContext)
// ExitLineStatement is called when exiting the lineStatement production. // ExitLineStatement is called when exiting the lineStatement production.
ExitLineStatement(c *LineStatementContext) ExitLineStatement(c *LineStatementContext)
@ -49,4 +52,7 @@ type ConfigListener interface {
// ExitString is called when exiting the string production. // ExitString is called when exiting the string production.
ExitString(c *StringContext) ExitString(c *StringContext)
// ExitCommentSymbol is called when exiting the commentSymbol production.
ExitCommentSymbol(c *CommentSymbolContext)
} }

View File

@ -33,38 +33,50 @@ var ConfigParserStaticData struct {
func configParserInit() { func configParserInit() {
staticData := &ConfigParserStaticData staticData := &ConfigParserStaticData
staticData.LiteralNames = []string{ staticData.LiteralNames = []string{
"", "'='", "'#'", "", "'='", "'#'", "';'",
} }
staticData.SymbolicNames = []string{ staticData.SymbolicNames = []string{
"", "EQUAL", "HASH", "WHITESPACE", "STRING", "QUOTED_STRING", "", "EQUAL", "HASH", "SEMICOLON", "WHITESPACE", "STRING", "QUOTED_STRING",
} }
staticData.RuleNames = []string{ staticData.RuleNames = []string{
"lineStatement", "entry", "leadingComment", "key", "separator", "value", "lineStatement", "entry", "leadingComment", "key", "separator", "value",
"string", "string", "commentSymbol",
} }
staticData.PredictionContextCache = antlr.NewPredictionContextCache() staticData.PredictionContextCache = antlr.NewPredictionContextCache()
staticData.serializedATN = []int32{ staticData.serializedATN = []int32{
4, 1, 5, 53, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 4, 1, 6, 78, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4,
2, 5, 7, 5, 2, 6, 7, 6, 1, 0, 1, 0, 1, 0, 1, 1, 3, 1, 19, 8, 1, 1, 1, 3, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 1, 0, 3, 0, 18, 8, 0, 1, 0, 1, 0, 3,
1, 22, 8, 1, 1, 1, 3, 1, 25, 8, 1, 1, 1, 3, 1, 28, 8, 1, 1, 1, 3, 1, 31, 0, 22, 8, 0, 1, 0, 3, 0, 25, 8, 0, 1, 0, 1, 0, 1, 1, 3, 1, 30, 8, 1, 1,
8, 1, 1, 2, 1, 2, 3, 2, 35, 8, 2, 1, 2, 1, 2, 3, 2, 39, 8, 2, 4, 2, 41, 1, 3, 1, 33, 8, 1, 1, 1, 3, 1, 36, 8, 1, 1, 1, 3, 1, 39, 8, 1, 1, 1, 3,
8, 2, 11, 2, 12, 2, 42, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 42, 8, 1, 1, 2, 1, 2, 3, 2, 46, 8, 2, 1, 2, 1, 2, 3, 2, 50, 8, 2, 4,
1, 6, 0, 0, 7, 0, 2, 4, 6, 8, 10, 12, 0, 1, 1, 0, 4, 5, 53, 0, 14, 1, 0, 2, 52, 8, 2, 11, 2, 12, 2, 53, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6,
0, 0, 2, 18, 1, 0, 0, 0, 4, 32, 1, 0, 0, 0, 6, 44, 1, 0, 0, 0, 8, 46, 1, 1, 6, 3, 6, 64, 8, 6, 1, 6, 1, 6, 5, 6, 68, 8, 6, 10, 6, 12, 6, 71, 9,
0, 0, 0, 10, 48, 1, 0, 0, 0, 12, 50, 1, 0, 0, 0, 14, 15, 3, 2, 1, 0, 15, 6, 1, 6, 3, 6, 74, 8, 6, 1, 7, 1, 7, 1, 7, 0, 0, 8, 0, 2, 4, 6, 8, 10,
16, 5, 0, 0, 1, 16, 1, 1, 0, 0, 0, 17, 19, 5, 3, 0, 0, 18, 17, 1, 0, 0, 12, 14, 0, 1, 1, 0, 2, 3, 83, 0, 17, 1, 0, 0, 0, 2, 29, 1, 0, 0, 0, 4,
0, 18, 19, 1, 0, 0, 0, 19, 21, 1, 0, 0, 0, 20, 22, 3, 6, 3, 0, 21, 20, 43, 1, 0, 0, 0, 6, 55, 1, 0, 0, 0, 8, 57, 1, 0, 0, 0, 10, 59, 1, 0, 0,
1, 0, 0, 0, 21, 22, 1, 0, 0, 0, 22, 24, 1, 0, 0, 0, 23, 25, 3, 8, 4, 0, 0, 12, 73, 1, 0, 0, 0, 14, 75, 1, 0, 0, 0, 16, 18, 5, 4, 0, 0, 17, 16,
24, 23, 1, 0, 0, 0, 24, 25, 1, 0, 0, 0, 25, 27, 1, 0, 0, 0, 26, 28, 3, 1, 0, 0, 0, 17, 18, 1, 0, 0, 0, 18, 19, 1, 0, 0, 0, 19, 21, 3, 2, 1, 0,
10, 5, 0, 27, 26, 1, 0, 0, 0, 27, 28, 1, 0, 0, 0, 28, 30, 1, 0, 0, 0, 29, 20, 22, 5, 4, 0, 0, 21, 20, 1, 0, 0, 0, 21, 22, 1, 0, 0, 0, 22, 24, 1,
31, 3, 4, 2, 0, 30, 29, 1, 0, 0, 0, 30, 31, 1, 0, 0, 0, 31, 3, 1, 0, 0, 0, 0, 0, 23, 25, 3, 4, 2, 0, 24, 23, 1, 0, 0, 0, 24, 25, 1, 0, 0, 0, 25,
0, 32, 34, 5, 2, 0, 0, 33, 35, 5, 3, 0, 0, 34, 33, 1, 0, 0, 0, 34, 35, 26, 1, 0, 0, 0, 26, 27, 5, 0, 0, 1, 27, 1, 1, 0, 0, 0, 28, 30, 3, 6, 3,
1, 0, 0, 0, 35, 40, 1, 0, 0, 0, 36, 38, 3, 12, 6, 0, 37, 39, 5, 3, 0, 0, 0, 29, 28, 1, 0, 0, 0, 29, 30, 1, 0, 0, 0, 30, 32, 1, 0, 0, 0, 31, 33,
38, 37, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 41, 1, 0, 0, 0, 40, 36, 1, 5, 4, 0, 0, 32, 31, 1, 0, 0, 0, 32, 33, 1, 0, 0, 0, 33, 35, 1, 0, 0, 0,
0, 0, 0, 41, 42, 1, 0, 0, 0, 42, 40, 1, 0, 0, 0, 42, 43, 1, 0, 0, 0, 43, 34, 36, 3, 8, 4, 0, 35, 34, 1, 0, 0, 0, 35, 36, 1, 0, 0, 0, 36, 38, 1,
5, 1, 0, 0, 0, 44, 45, 3, 12, 6, 0, 45, 7, 1, 0, 0, 0, 46, 47, 5, 1, 0, 0, 0, 0, 37, 39, 5, 4, 0, 0, 38, 37, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39,
0, 47, 9, 1, 0, 0, 0, 48, 49, 3, 12, 6, 0, 49, 11, 1, 0, 0, 0, 50, 51, 41, 1, 0, 0, 0, 40, 42, 3, 10, 5, 0, 41, 40, 1, 0, 0, 0, 41, 42, 1, 0,
7, 0, 0, 0, 51, 13, 1, 0, 0, 0, 8, 18, 21, 24, 27, 30, 34, 38, 42, 0, 0, 42, 3, 1, 0, 0, 0, 43, 45, 3, 14, 7, 0, 44, 46, 5, 4, 0, 0, 45, 44,
1, 0, 0, 0, 45, 46, 1, 0, 0, 0, 46, 51, 1, 0, 0, 0, 47, 49, 3, 12, 6, 0,
48, 50, 5, 4, 0, 0, 49, 48, 1, 0, 0, 0, 49, 50, 1, 0, 0, 0, 50, 52, 1,
0, 0, 0, 51, 47, 1, 0, 0, 0, 52, 53, 1, 0, 0, 0, 53, 51, 1, 0, 0, 0, 53,
54, 1, 0, 0, 0, 54, 5, 1, 0, 0, 0, 55, 56, 3, 12, 6, 0, 56, 7, 1, 0, 0,
0, 57, 58, 5, 1, 0, 0, 58, 9, 1, 0, 0, 0, 59, 60, 3, 12, 6, 0, 60, 11,
1, 0, 0, 0, 61, 74, 5, 6, 0, 0, 62, 64, 5, 4, 0, 0, 63, 62, 1, 0, 0, 0,
63, 64, 1, 0, 0, 0, 64, 69, 1, 0, 0, 0, 65, 66, 5, 5, 0, 0, 66, 68, 5,
4, 0, 0, 67, 65, 1, 0, 0, 0, 68, 71, 1, 0, 0, 0, 69, 67, 1, 0, 0, 0, 69,
70, 1, 0, 0, 0, 70, 72, 1, 0, 0, 0, 71, 69, 1, 0, 0, 0, 72, 74, 5, 5, 0,
0, 73, 61, 1, 0, 0, 0, 73, 63, 1, 0, 0, 0, 74, 13, 1, 0, 0, 0, 75, 76,
7, 0, 0, 0, 76, 15, 1, 0, 0, 0, 14, 17, 21, 24, 29, 32, 35, 38, 41, 45,
49, 53, 63, 69, 73,
} }
deserializer := antlr.NewATNDeserializer(nil) deserializer := antlr.NewATNDeserializer(nil)
staticData.atn = deserializer.Deserialize(staticData.serializedATN) staticData.atn = deserializer.Deserialize(staticData.serializedATN)
@ -105,9 +117,10 @@ const (
ConfigParserEOF = antlr.TokenEOF ConfigParserEOF = antlr.TokenEOF
ConfigParserEQUAL = 1 ConfigParserEQUAL = 1
ConfigParserHASH = 2 ConfigParserHASH = 2
ConfigParserWHITESPACE = 3 ConfigParserSEMICOLON = 3
ConfigParserSTRING = 4 ConfigParserWHITESPACE = 4
ConfigParserQUOTED_STRING = 5 ConfigParserSTRING = 5
ConfigParserQUOTED_STRING = 6
) )
// ConfigParser rules. // ConfigParser rules.
@ -119,6 +132,7 @@ const (
ConfigParserRULE_separator = 4 ConfigParserRULE_separator = 4
ConfigParserRULE_value = 5 ConfigParserRULE_value = 5
ConfigParserRULE_string = 6 ConfigParserRULE_string = 6
ConfigParserRULE_commentSymbol = 7
) )
// ILineStatementContext is an interface to support dynamic dispatch. // ILineStatementContext is an interface to support dynamic dispatch.
@ -131,6 +145,9 @@ type ILineStatementContext interface {
// Getter signatures // Getter signatures
Entry() IEntryContext Entry() IEntryContext
EOF() antlr.TerminalNode EOF() antlr.TerminalNode
AllWHITESPACE() []antlr.TerminalNode
WHITESPACE(i int) antlr.TerminalNode
LeadingComment() ILeadingCommentContext
// IsLineStatementContext differentiates from other interfaces. // IsLineStatementContext differentiates from other interfaces.
IsLineStatementContext() IsLineStatementContext()
@ -188,6 +205,30 @@ func (s *LineStatementContext) EOF() antlr.TerminalNode {
return s.GetToken(ConfigParserEOF, 0) return s.GetToken(ConfigParserEOF, 0)
} }
func (s *LineStatementContext) AllWHITESPACE() []antlr.TerminalNode {
return s.GetTokens(ConfigParserWHITESPACE)
}
func (s *LineStatementContext) WHITESPACE(i int) antlr.TerminalNode {
return s.GetToken(ConfigParserWHITESPACE, i)
}
func (s *LineStatementContext) LeadingComment() ILeadingCommentContext {
var t antlr.RuleContext
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(ILeadingCommentContext); ok {
t = ctx.(antlr.RuleContext)
break
}
}
if t == nil {
return nil
}
return t.(ILeadingCommentContext)
}
func (s *LineStatementContext) GetRuleContext() antlr.RuleContext { func (s *LineStatementContext) GetRuleContext() antlr.RuleContext {
return s return s
} }
@ -211,13 +252,63 @@ func (s *LineStatementContext) ExitRule(listener antlr.ParseTreeListener) {
func (p *ConfigParser) LineStatement() (localctx ILineStatementContext) { func (p *ConfigParser) LineStatement() (localctx ILineStatementContext) {
localctx = NewLineStatementContext(p, p.GetParserRuleContext(), p.GetState()) localctx = NewLineStatementContext(p, p.GetParserRuleContext(), p.GetState())
p.EnterRule(localctx, 0, ConfigParserRULE_lineStatement) p.EnterRule(localctx, 0, ConfigParserRULE_lineStatement)
var _la int
p.EnterOuterAlt(localctx, 1) p.EnterOuterAlt(localctx, 1)
p.SetState(17)
p.GetErrorHandler().Sync(p)
if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 0, p.GetParserRuleContext()) == 1 {
{ {
p.SetState(14) p.SetState(16)
p.Entry() p.Match(ConfigParserWHITESPACE)
if p.HasError() {
// Recognition error - abort rule
goto errorExit
}
}
} else if p.HasError() { // JIM
goto errorExit
} }
{ {
p.SetState(15) p.SetState(19)
p.Entry()
}
p.SetState(21)
p.GetErrorHandler().Sync(p)
if p.HasError() {
goto errorExit
}
_la = p.GetTokenStream().LA(1)
if _la == ConfigParserWHITESPACE {
{
p.SetState(20)
p.Match(ConfigParserWHITESPACE)
if p.HasError() {
// Recognition error - abort rule
goto errorExit
}
}
}
p.SetState(24)
p.GetErrorHandler().Sync(p)
if p.HasError() {
goto errorExit
}
_la = p.GetTokenStream().LA(1)
if _la == ConfigParserHASH || _la == ConfigParserSEMICOLON {
{
p.SetState(23)
p.LeadingComment()
}
}
{
p.SetState(26)
p.Match(ConfigParserEOF) p.Match(ConfigParserEOF)
if p.HasError() { if p.HasError() {
// Recognition error - abort rule // Recognition error - abort rule
@ -246,11 +337,11 @@ type IEntryContext interface {
GetParser() antlr.Parser GetParser() antlr.Parser
// Getter signatures // Getter signatures
WHITESPACE() antlr.TerminalNode
Key() IKeyContext Key() IKeyContext
AllWHITESPACE() []antlr.TerminalNode
WHITESPACE(i int) antlr.TerminalNode
Separator() ISeparatorContext Separator() ISeparatorContext
Value() IValueContext Value() IValueContext
LeadingComment() ILeadingCommentContext
// IsEntryContext differentiates from other interfaces. // IsEntryContext differentiates from other interfaces.
IsEntryContext() IsEntryContext()
@ -288,10 +379,6 @@ func NewEntryContext(parser antlr.Parser, parent antlr.ParserRuleContext, invoki
func (s *EntryContext) GetParser() antlr.Parser { return s.parser } func (s *EntryContext) GetParser() antlr.Parser { return s.parser }
func (s *EntryContext) WHITESPACE() antlr.TerminalNode {
return s.GetToken(ConfigParserWHITESPACE, 0)
}
func (s *EntryContext) Key() IKeyContext { func (s *EntryContext) Key() IKeyContext {
var t antlr.RuleContext var t antlr.RuleContext
for _, ctx := range s.GetChildren() { for _, ctx := range s.GetChildren() {
@ -308,6 +395,14 @@ func (s *EntryContext) Key() IKeyContext {
return t.(IKeyContext) return t.(IKeyContext)
} }
func (s *EntryContext) AllWHITESPACE() []antlr.TerminalNode {
return s.GetTokens(ConfigParserWHITESPACE)
}
func (s *EntryContext) WHITESPACE(i int) antlr.TerminalNode {
return s.GetToken(ConfigParserWHITESPACE, i)
}
func (s *EntryContext) Separator() ISeparatorContext { func (s *EntryContext) Separator() ISeparatorContext {
var t antlr.RuleContext var t antlr.RuleContext
for _, ctx := range s.GetChildren() { for _, ctx := range s.GetChildren() {
@ -340,22 +435,6 @@ func (s *EntryContext) Value() IValueContext {
return t.(IValueContext) return t.(IValueContext)
} }
func (s *EntryContext) LeadingComment() ILeadingCommentContext {
var t antlr.RuleContext
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(ILeadingCommentContext); ok {
t = ctx.(antlr.RuleContext)
break
}
}
if t == nil {
return nil
}
return t.(ILeadingCommentContext)
}
func (s *EntryContext) GetRuleContext() antlr.RuleContext { func (s *EntryContext) GetRuleContext() antlr.RuleContext {
return s return s
} }
@ -382,16 +461,24 @@ func (p *ConfigParser) Entry() (localctx IEntryContext) {
var _la int var _la int
p.EnterOuterAlt(localctx, 1) p.EnterOuterAlt(localctx, 1)
p.SetState(18) p.SetState(29)
p.GetErrorHandler().Sync(p) p.GetErrorHandler().Sync(p)
if p.HasError() {
if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 3, p.GetParserRuleContext()) == 1 {
{
p.SetState(28)
p.Key()
}
} else if p.HasError() { // JIM
goto errorExit goto errorExit
} }
_la = p.GetTokenStream().LA(1) p.SetState(32)
p.GetErrorHandler().Sync(p)
if _la == ConfigParserWHITESPACE { if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 4, p.GetParserRuleContext()) == 1 {
{ {
p.SetState(17) p.SetState(31)
p.Match(ConfigParserWHITESPACE) p.Match(ConfigParserWHITESPACE)
if p.HasError() { if p.HasError() {
// Recognition error - abort rule // Recognition error - abort rule
@ -399,20 +486,10 @@ func (p *ConfigParser) Entry() (localctx IEntryContext) {
} }
} }
}
p.SetState(21)
p.GetErrorHandler().Sync(p)
if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 1, p.GetParserRuleContext()) == 1 {
{
p.SetState(20)
p.Key()
}
} else if p.HasError() { // JIM } else if p.HasError() { // JIM
goto errorExit goto errorExit
} }
p.SetState(24) p.SetState(35)
p.GetErrorHandler().Sync(p) p.GetErrorHandler().Sync(p)
if p.HasError() { if p.HasError() {
goto errorExit goto errorExit
@ -421,39 +498,39 @@ func (p *ConfigParser) Entry() (localctx IEntryContext) {
if _la == ConfigParserEQUAL { if _la == ConfigParserEQUAL {
{ {
p.SetState(23) p.SetState(34)
p.Separator() p.Separator()
} }
} }
p.SetState(27) p.SetState(38)
p.GetErrorHandler().Sync(p) p.GetErrorHandler().Sync(p)
if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 6, p.GetParserRuleContext()) == 1 {
{
p.SetState(37)
p.Match(ConfigParserWHITESPACE)
if p.HasError() { if p.HasError() {
// Recognition error - abort rule
goto errorExit goto errorExit
} }
_la = p.GetTokenStream().LA(1) }
if _la == ConfigParserSTRING || _la == ConfigParserQUOTED_STRING { } else if p.HasError() { // JIM
goto errorExit
}
p.SetState(41)
p.GetErrorHandler().Sync(p)
if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 7, p.GetParserRuleContext()) == 1 {
{ {
p.SetState(26) p.SetState(40)
p.Value() p.Value()
} }
} } else if p.HasError() { // JIM
p.SetState(30)
p.GetErrorHandler().Sync(p)
if p.HasError() {
goto errorExit goto errorExit
} }
_la = p.GetTokenStream().LA(1)
if _la == ConfigParserHASH {
{
p.SetState(29)
p.LeadingComment()
}
}
errorExit: errorExit:
if p.HasError() { if p.HasError() {
@ -476,7 +553,7 @@ type ILeadingCommentContext interface {
GetParser() antlr.Parser GetParser() antlr.Parser
// Getter signatures // Getter signatures
HASH() antlr.TerminalNode CommentSymbol() ICommentSymbolContext
AllWHITESPACE() []antlr.TerminalNode AllWHITESPACE() []antlr.TerminalNode
WHITESPACE(i int) antlr.TerminalNode WHITESPACE(i int) antlr.TerminalNode
AllString_() []IStringContext AllString_() []IStringContext
@ -518,8 +595,20 @@ func NewLeadingCommentContext(parser antlr.Parser, parent antlr.ParserRuleContex
func (s *LeadingCommentContext) GetParser() antlr.Parser { return s.parser } func (s *LeadingCommentContext) GetParser() antlr.Parser { return s.parser }
func (s *LeadingCommentContext) HASH() antlr.TerminalNode { func (s *LeadingCommentContext) CommentSymbol() ICommentSymbolContext {
return s.GetToken(ConfigParserHASH, 0) var t antlr.RuleContext
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(ICommentSymbolContext); ok {
t = ctx.(antlr.RuleContext)
break
}
}
if t == nil {
return nil
}
return t.(ICommentSymbolContext)
} }
func (s *LeadingCommentContext) AllWHITESPACE() []antlr.TerminalNode { func (s *LeadingCommentContext) AllWHITESPACE() []antlr.TerminalNode {
@ -598,23 +687,15 @@ func (p *ConfigParser) LeadingComment() (localctx ILeadingCommentContext) {
p.EnterOuterAlt(localctx, 1) p.EnterOuterAlt(localctx, 1)
{ {
p.SetState(32) p.SetState(43)
p.Match(ConfigParserHASH) p.CommentSymbol()
if p.HasError() {
// Recognition error - abort rule
goto errorExit
} }
} p.SetState(45)
p.SetState(34)
p.GetErrorHandler().Sync(p) p.GetErrorHandler().Sync(p)
if p.HasError() {
goto errorExit
}
_la = p.GetTokenStream().LA(1)
if _la == ConfigParserWHITESPACE { if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 8, p.GetParserRuleContext()) == 1 {
{ {
p.SetState(33) p.SetState(44)
p.Match(ConfigParserWHITESPACE) p.Match(ConfigParserWHITESPACE)
if p.HasError() { if p.HasError() {
// Recognition error - abort rule // Recognition error - abort rule
@ -622,29 +703,27 @@ func (p *ConfigParser) LeadingComment() (localctx ILeadingCommentContext) {
} }
} }
} else if p.HasError() { // JIM
goto errorExit
} }
p.SetState(40) p.SetState(51)
p.GetErrorHandler().Sync(p) p.GetErrorHandler().Sync(p)
if p.HasError() { if p.HasError() {
goto errorExit goto errorExit
} }
_la = p.GetTokenStream().LA(1) _la = p.GetTokenStream().LA(1)
for ok := true; ok; ok = _la == ConfigParserSTRING || _la == ConfigParserQUOTED_STRING { for ok := true; ok; ok = ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&112) != 0) {
{ {
p.SetState(36) p.SetState(47)
p.String_() p.String_()
} }
p.SetState(38) p.SetState(49)
p.GetErrorHandler().Sync(p) p.GetErrorHandler().Sync(p)
if p.HasError() {
goto errorExit
}
_la = p.GetTokenStream().LA(1)
if _la == ConfigParserWHITESPACE { if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 9, p.GetParserRuleContext()) == 1 {
{ {
p.SetState(37) p.SetState(48)
p.Match(ConfigParserWHITESPACE) p.Match(ConfigParserWHITESPACE)
if p.HasError() { if p.HasError() {
// Recognition error - abort rule // Recognition error - abort rule
@ -652,9 +731,11 @@ func (p *ConfigParser) LeadingComment() (localctx ILeadingCommentContext) {
} }
} }
} else if p.HasError() { // JIM
goto errorExit
} }
p.SetState(42) p.SetState(53)
p.GetErrorHandler().Sync(p) p.GetErrorHandler().Sync(p)
if p.HasError() { if p.HasError() {
goto errorExit goto errorExit
@ -762,7 +843,7 @@ func (p *ConfigParser) Key() (localctx IKeyContext) {
p.EnterRule(localctx, 6, ConfigParserRULE_key) p.EnterRule(localctx, 6, ConfigParserRULE_key)
p.EnterOuterAlt(localctx, 1) p.EnterOuterAlt(localctx, 1)
{ {
p.SetState(44) p.SetState(55)
p.String_() p.String_()
} }
@ -854,7 +935,7 @@ func (p *ConfigParser) Separator() (localctx ISeparatorContext) {
p.EnterRule(localctx, 8, ConfigParserRULE_separator) p.EnterRule(localctx, 8, ConfigParserRULE_separator)
p.EnterOuterAlt(localctx, 1) p.EnterOuterAlt(localctx, 1)
{ {
p.SetState(46) p.SetState(57)
p.Match(ConfigParserEQUAL) p.Match(ConfigParserEQUAL)
if p.HasError() { if p.HasError() {
// Recognition error - abort rule // Recognition error - abort rule
@ -962,7 +1043,7 @@ func (p *ConfigParser) Value() (localctx IValueContext) {
p.EnterRule(localctx, 10, ConfigParserRULE_value) p.EnterRule(localctx, 10, ConfigParserRULE_value)
p.EnterOuterAlt(localctx, 1) p.EnterOuterAlt(localctx, 1)
{ {
p.SetState(48) p.SetState(59)
p.String_() p.String_()
} }
@ -988,7 +1069,10 @@ type IStringContext interface {
// Getter signatures // Getter signatures
QUOTED_STRING() antlr.TerminalNode QUOTED_STRING() antlr.TerminalNode
STRING() antlr.TerminalNode AllSTRING() []antlr.TerminalNode
STRING(i int) antlr.TerminalNode
AllWHITESPACE() []antlr.TerminalNode
WHITESPACE(i int) antlr.TerminalNode
// IsStringContext differentiates from other interfaces. // IsStringContext differentiates from other interfaces.
IsStringContext() IsStringContext()
@ -1030,8 +1114,20 @@ func (s *StringContext) QUOTED_STRING() antlr.TerminalNode {
return s.GetToken(ConfigParserQUOTED_STRING, 0) return s.GetToken(ConfigParserQUOTED_STRING, 0)
} }
func (s *StringContext) STRING() antlr.TerminalNode { func (s *StringContext) AllSTRING() []antlr.TerminalNode {
return s.GetToken(ConfigParserSTRING, 0) return s.GetTokens(ConfigParserSTRING)
}
func (s *StringContext) STRING(i int) antlr.TerminalNode {
return s.GetToken(ConfigParserSTRING, i)
}
func (s *StringContext) AllWHITESPACE() []antlr.TerminalNode {
return s.GetTokens(ConfigParserWHITESPACE)
}
func (s *StringContext) WHITESPACE(i int) antlr.TerminalNode {
return s.GetToken(ConfigParserWHITESPACE, i)
} }
func (s *StringContext) GetRuleContext() antlr.RuleContext { func (s *StringContext) GetRuleContext() antlr.RuleContext {
@ -1059,12 +1155,197 @@ func (p *ConfigParser) String_() (localctx IStringContext) {
p.EnterRule(localctx, 12, ConfigParserRULE_string) p.EnterRule(localctx, 12, ConfigParserRULE_string)
var _la int var _la int
var _alt int
p.EnterOuterAlt(localctx, 1) p.EnterOuterAlt(localctx, 1)
p.SetState(73)
p.GetErrorHandler().Sync(p)
if p.HasError() {
goto errorExit
}
switch p.GetTokenStream().LA(1) {
case ConfigParserQUOTED_STRING:
{ {
p.SetState(50) p.SetState(61)
p.Match(ConfigParserQUOTED_STRING)
if p.HasError() {
// Recognition error - abort rule
goto errorExit
}
}
case ConfigParserWHITESPACE, ConfigParserSTRING:
p.SetState(63)
p.GetErrorHandler().Sync(p)
if p.HasError() {
goto errorExit
}
_la = p.GetTokenStream().LA(1) _la = p.GetTokenStream().LA(1)
if !(_la == ConfigParserSTRING || _la == ConfigParserQUOTED_STRING) { if _la == ConfigParserWHITESPACE {
{
p.SetState(62)
p.Match(ConfigParserWHITESPACE)
if p.HasError() {
// Recognition error - abort rule
goto errorExit
}
}
}
p.SetState(69)
p.GetErrorHandler().Sync(p)
if p.HasError() {
goto errorExit
}
_alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 12, p.GetParserRuleContext())
if p.HasError() {
goto errorExit
}
for _alt != 2 && _alt != antlr.ATNInvalidAltNumber {
if _alt == 1 {
{
p.SetState(65)
p.Match(ConfigParserSTRING)
if p.HasError() {
// Recognition error - abort rule
goto errorExit
}
}
{
p.SetState(66)
p.Match(ConfigParserWHITESPACE)
if p.HasError() {
// Recognition error - abort rule
goto errorExit
}
}
}
p.SetState(71)
p.GetErrorHandler().Sync(p)
if p.HasError() {
goto errorExit
}
_alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 12, p.GetParserRuleContext())
if p.HasError() {
goto errorExit
}
}
{
p.SetState(72)
p.Match(ConfigParserSTRING)
if p.HasError() {
// Recognition error - abort rule
goto errorExit
}
}
default:
p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
goto errorExit
}
errorExit:
if p.HasError() {
v := p.GetError()
localctx.SetException(v)
p.GetErrorHandler().ReportError(p, v)
p.GetErrorHandler().Recover(p, v)
p.SetError(nil)
}
p.ExitRule()
return localctx
goto errorExit // Trick to prevent compiler error if the label is not used
}
// ICommentSymbolContext is an interface to support dynamic dispatch.
type ICommentSymbolContext interface {
antlr.ParserRuleContext
// GetParser returns the parser.
GetParser() antlr.Parser
// Getter signatures
HASH() antlr.TerminalNode
SEMICOLON() antlr.TerminalNode
// IsCommentSymbolContext differentiates from other interfaces.
IsCommentSymbolContext()
}
type CommentSymbolContext struct {
antlr.BaseParserRuleContext
parser antlr.Parser
}
func NewEmptyCommentSymbolContext() *CommentSymbolContext {
var p = new(CommentSymbolContext)
antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
p.RuleIndex = ConfigParserRULE_commentSymbol
return p
}
func InitEmptyCommentSymbolContext(p *CommentSymbolContext) {
antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
p.RuleIndex = ConfigParserRULE_commentSymbol
}
func (*CommentSymbolContext) IsCommentSymbolContext() {}
func NewCommentSymbolContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CommentSymbolContext {
var p = new(CommentSymbolContext)
antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
p.parser = parser
p.RuleIndex = ConfigParserRULE_commentSymbol
return p
}
func (s *CommentSymbolContext) GetParser() antlr.Parser { return s.parser }
func (s *CommentSymbolContext) HASH() antlr.TerminalNode {
return s.GetToken(ConfigParserHASH, 0)
}
func (s *CommentSymbolContext) SEMICOLON() antlr.TerminalNode {
return s.GetToken(ConfigParserSEMICOLON, 0)
}
func (s *CommentSymbolContext) GetRuleContext() antlr.RuleContext {
return s
}
func (s *CommentSymbolContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
return antlr.TreesStringTree(s, ruleNames, recog)
}
func (s *CommentSymbolContext) EnterRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(ConfigListener); ok {
listenerT.EnterCommentSymbol(s)
}
}
func (s *CommentSymbolContext) ExitRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(ConfigListener); ok {
listenerT.ExitCommentSymbol(s)
}
}
func (p *ConfigParser) CommentSymbol() (localctx ICommentSymbolContext) {
localctx = NewCommentSymbolContext(p, p.GetParserRuleContext(), p.GetState())
p.EnterRule(localctx, 14, ConfigParserRULE_commentSymbol)
var _la int
p.EnterOuterAlt(localctx, 1)
{
p.SetState(75)
_la = p.GetTokenStream().LA(1)
if !(_la == ConfigParserHASH || _la == ConfigParserSEMICOLON) {
p.GetErrorHandler().RecoverInline(p) p.GetErrorHandler().RecoverInline(p)
} else { } else {
p.GetErrorHandler().ReportMatch(p) p.GetErrorHandler().ReportMatch(p)

View File

@ -0,0 +1,138 @@
package ast
import (
"config-lsp/utils"
"testing"
)
func TestValidOneSectionExample(t *testing.T) {
input := utils.Dedent(`
[core]
repositoryformatversion = 0
filemode = true
bare = false
`)
config := NewGitConfig()
errors := config.Parse(input)
if len(errors) > 0 {
t.Fatalf("Expected no errors, got %v", errors)
}
if len(config.Sections) != 1 {
t.Fatalf("Expected 1 section, got %d", len(config.Sections))
}
section := config.Sections[0]
rawFirstOption, _ := section.Entries.Get(uint32(1))
firstOption := rawFirstOption.(*GitEntry)
if !(firstOption.Key.Value.Value == "repositoryformatversion" && firstOption.Value.Value == "0") {
t.Errorf("Expected repositoryformatversion, got %s", firstOption.Key.Value.Value)
}
rawSecondOption, _ := section.Entries.Get(uint32(2))
secondOption := rawSecondOption.(*GitEntry)
if !(secondOption.Key.Value.Value == "filemode" && secondOption.Value.Value == "true") {
t.Errorf("Expected filemode, got %s", secondOption.Key.Value.Value)
}
rawThirdOption, _ := section.Entries.Get(uint32(3))
thirdOption := rawThirdOption.(*GitEntry)
if !(thirdOption.Key.Value.Value == "bare" && thirdOption.Value.Value == "false") {
t.Errorf("Expected bare, got %s", thirdOption.Key.Value.Value)
}
}
func TestComplexExample(t *testing.T) {
input := utils.Dedent(`
[core]
repositoryformatversion = 0 # This contains 4 spaces instead of a tab at the beginning
filemode = true # Hello World
# Hello World
bare = false ; Trailing comment
# Test
[remote "origin"]
url = https://github.com/github/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
[alias]
ours = "!f() { git checkout --ours $@ && git add $@; }; f" ; This is a comment
; Hello
`)
config := NewGitConfig()
errors := config.Parse(input)
if len(errors) > 0 {
t.Fatalf("Expected no errors, got %v", errors)
}
if len(config.Sections) != 3 {
t.Fatalf("Expected 3 sections, got %d", len(config.Sections))
}
section := config.Sections[0]
if !(section.Title.Title == "core") {
t.Errorf("Expected core, got %s", section.Title.Title)
}
if !(section.Entries.Size() == 3) {
t.Errorf("Expected 3 entries, got %d", section.Entries.Size())
}
rawFirstOption, _ := section.Entries.Get(uint32(1))
firstOption := rawFirstOption.(*GitEntry)
if !(firstOption.Key.Value.Value == "repositoryformatversion" && firstOption.Value.Value == "0" && firstOption.Start.Line == 1 && firstOption.End.Line == 1 && firstOption.Start.Character == 4 && firstOption.End.Character == 31) {
t.Errorf("Expected 0, got %s", firstOption)
}
_, found := section.Entries.Get(uint32(3))
if found {
t.Errorf("Expected no entry at line 3")
}
section = config.Sections[1]
if !(section.Title.Title == `remote "origin"`) {
t.Errorf("Expected remote \"origin\", got %s", section.Title.Title)
}
if !(section.Entries.Size() == 2) {
t.Errorf("Expected 2 entries, got %d", section.Entries.Size())
}
section = config.Sections[2]
if !(section.Title.Title == "alias") {
t.Errorf("Expected alias, got %s", section.Title.Title)
}
rawSecondOption, _ := section.Entries.Get(uint32(13))
secondOption := rawSecondOption.(*GitEntry)
if !(secondOption.Key.Value.Value == "ours" && secondOption.Value.Value == "!f() { git checkout --ours $@ && git add $@; }; f" && secondOption.Start.Character == 1 && secondOption.End.Character == 59) {
t.Errorf("Expected ours, got %s", secondOption.Key.Value.Value)
}
}
func TestMissingSectionHeader(t *testing.T) {
input := utils.Dedent(`
repositoryformatversion = 0
filemode = true
bare = false
[core]
bare = false
`)
config := NewGitConfig()
errors := config.Parse(input)
if len(errors) != 1 {
t.Fatalf("Expected 1 error, got %d", len(errors))
}
}