mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-19 07:25:27 +02:00
feat(hosts): Add hosts parser
This commit is contained in:
parent
a2b5f1ea93
commit
4fe2f46b1b
14
common/errors.go
Normal file
14
common/errors.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
type LSPError struct {
|
||||||
|
Range LocationRange
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
type SyntaxError struct {
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SyntaxError) Error() string {
|
||||||
|
return s.Message
|
||||||
|
}
|
29
common/location.go
Normal file
29
common/location.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
type Location struct {
|
||||||
|
Line uint32
|
||||||
|
Character uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type LocationRange struct {
|
||||||
|
Start Location
|
||||||
|
End Location
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *LocationRange) ChangeBothLines(newLine uint32) {
|
||||||
|
l.Start.Line = newLine
|
||||||
|
l.End.Line = newLine
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateSingleCharRange(line uint32, character uint32) LocationRange {
|
||||||
|
return LocationRange{
|
||||||
|
Start: Location{
|
||||||
|
Line: line,
|
||||||
|
Character: character,
|
||||||
|
},
|
||||||
|
End: Location{
|
||||||
|
Line: line,
|
||||||
|
Character: character,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
1
go.mod
1
go.mod
@ -8,6 +8,7 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||||
github.com/gorilla/websocket v1.5.3 // indirect
|
github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
github.com/iancoleman/strcase v0.3.0 // indirect
|
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -1,3 +1,5 @@
|
|||||||
|
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
|
||||||
|
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
126
handlers/hosts/Hosts.g4
Normal file
126
handlers/hosts/Hosts.g4
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
grammar Hosts;
|
||||||
|
|
||||||
|
lineStatement
|
||||||
|
: SEPARATOR? entry SEPARATOR? leadingComment? EOF
|
||||||
|
;
|
||||||
|
|
||||||
|
entry
|
||||||
|
: ipAddress SEPARATOR hostname (SEPARATOR aliases)?
|
||||||
|
;
|
||||||
|
|
||||||
|
aliases
|
||||||
|
: (alias SEPARATOR?)+
|
||||||
|
;
|
||||||
|
|
||||||
|
alias
|
||||||
|
: DOMAIN
|
||||||
|
;
|
||||||
|
|
||||||
|
hostname
|
||||||
|
: domain
|
||||||
|
;
|
||||||
|
|
||||||
|
domain
|
||||||
|
: DOMAIN
|
||||||
|
;
|
||||||
|
|
||||||
|
ipAddress
|
||||||
|
: (ipv4Address | ipv6Address)
|
||||||
|
;
|
||||||
|
|
||||||
|
ipv4Address
|
||||||
|
: singleIPv4Address
|
||||||
|
// Allow optional range to tell user ranges are not allowed
|
||||||
|
ipRange?
|
||||||
|
;
|
||||||
|
|
||||||
|
singleIPv4Address
|
||||||
|
: ipv4Digit DOT ipv4Digit DOT ipv4Digit DOT ipv4Digit
|
||||||
|
;
|
||||||
|
|
||||||
|
// This is not correct but fits for now
|
||||||
|
ipv6Address
|
||||||
|
: singleIPv6Address
|
||||||
|
// Allow optional range to tell user ranges are not allowed
|
||||||
|
ipRange?
|
||||||
|
;
|
||||||
|
|
||||||
|
singleIPv6Address
|
||||||
|
: (ipv6Octet COLON)+ ipv6Octet
|
||||||
|
;
|
||||||
|
|
||||||
|
ipv4Digit
|
||||||
|
: DIGITS
|
||||||
|
;
|
||||||
|
|
||||||
|
ipv6Octet
|
||||||
|
: OCTETS
|
||||||
|
;
|
||||||
|
|
||||||
|
ipRange
|
||||||
|
: SLASH ipRangeBits
|
||||||
|
;
|
||||||
|
|
||||||
|
ipRangeBits
|
||||||
|
: DIGITS
|
||||||
|
;
|
||||||
|
|
||||||
|
comment
|
||||||
|
: COMMENTLINE
|
||||||
|
;
|
||||||
|
|
||||||
|
leadingComment
|
||||||
|
: COMMENTLINE
|
||||||
|
;
|
||||||
|
|
||||||
|
COMMENTLINE
|
||||||
|
: HASHTAG ~[\r\n]+
|
||||||
|
;
|
||||||
|
|
||||||
|
SLASH
|
||||||
|
: '/'
|
||||||
|
;
|
||||||
|
|
||||||
|
DOT
|
||||||
|
: '.'
|
||||||
|
;
|
||||||
|
|
||||||
|
COLON
|
||||||
|
: ':'
|
||||||
|
;
|
||||||
|
|
||||||
|
HASHTAG
|
||||||
|
: '#'
|
||||||
|
;
|
||||||
|
|
||||||
|
SEPARATOR
|
||||||
|
: [ \t]+
|
||||||
|
;
|
||||||
|
|
||||||
|
NEWLINE
|
||||||
|
: [\r]? [\n]
|
||||||
|
;
|
||||||
|
|
||||||
|
DIGITS
|
||||||
|
: DIGIT+
|
||||||
|
;
|
||||||
|
|
||||||
|
fragment DIGIT
|
||||||
|
: [0-9]
|
||||||
|
;
|
||||||
|
|
||||||
|
OCTETS
|
||||||
|
: OCTET+
|
||||||
|
;
|
||||||
|
|
||||||
|
fragment OCTET
|
||||||
|
: [0-9a-fA-F]
|
||||||
|
;
|
||||||
|
|
||||||
|
DOMAIN
|
||||||
|
: ((STRING)+ (DOT [a-zA-Z]+)*)
|
||||||
|
;
|
||||||
|
|
||||||
|
fragment STRING
|
||||||
|
: ~(' ' | '\t' | '\n' | '\r' | '#' | '.')
|
||||||
|
;
|
48
handlers/hosts/parser/Hosts.interp
Normal file
48
handlers/hosts/parser/Hosts.interp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
token literal names:
|
||||||
|
null
|
||||||
|
null
|
||||||
|
'/'
|
||||||
|
'.'
|
||||||
|
':'
|
||||||
|
'#'
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
|
||||||
|
token symbolic names:
|
||||||
|
null
|
||||||
|
COMMENTLINE
|
||||||
|
SLASH
|
||||||
|
DOT
|
||||||
|
COLON
|
||||||
|
HASHTAG
|
||||||
|
SEPARATOR
|
||||||
|
NEWLINE
|
||||||
|
DIGITS
|
||||||
|
OCTETS
|
||||||
|
DOMAIN
|
||||||
|
|
||||||
|
rule names:
|
||||||
|
lineStatement
|
||||||
|
entry
|
||||||
|
aliases
|
||||||
|
alias
|
||||||
|
hostname
|
||||||
|
domain
|
||||||
|
ipAddress
|
||||||
|
ipv4Address
|
||||||
|
singleIPv4Address
|
||||||
|
ipv6Address
|
||||||
|
singleIPv6Address
|
||||||
|
ipv4Digit
|
||||||
|
ipv6Octet
|
||||||
|
ipRange
|
||||||
|
ipRangeBits
|
||||||
|
comment
|
||||||
|
leadingComment
|
||||||
|
|
||||||
|
|
||||||
|
atn:
|
||||||
|
[4, 1, 10, 110, 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, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 1, 0, 3, 0, 36, 8, 0, 1, 0, 1, 0, 3, 0, 40, 8, 0, 1, 0, 3, 0, 43, 8, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 52, 8, 1, 1, 2, 1, 2, 3, 2, 56, 8, 2, 4, 2, 58, 8, 2, 11, 2, 12, 2, 59, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 3, 6, 70, 8, 6, 1, 7, 1, 7, 3, 7, 74, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 3, 9, 86, 8, 9, 1, 10, 1, 10, 1, 10, 4, 10, 91, 8, 10, 11, 10, 12, 10, 92, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 0, 0, 17, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 0, 0, 102, 0, 35, 1, 0, 0, 0, 2, 46, 1, 0, 0, 0, 4, 57, 1, 0, 0, 0, 6, 61, 1, 0, 0, 0, 8, 63, 1, 0, 0, 0, 10, 65, 1, 0, 0, 0, 12, 69, 1, 0, 0, 0, 14, 71, 1, 0, 0, 0, 16, 75, 1, 0, 0, 0, 18, 83, 1, 0, 0, 0, 20, 90, 1, 0, 0, 0, 22, 96, 1, 0, 0, 0, 24, 98, 1, 0, 0, 0, 26, 100, 1, 0, 0, 0, 28, 103, 1, 0, 0, 0, 30, 105, 1, 0, 0, 0, 32, 107, 1, 0, 0, 0, 34, 36, 5, 6, 0, 0, 35, 34, 1, 0, 0, 0, 35, 36, 1, 0, 0, 0, 36, 37, 1, 0, 0, 0, 37, 39, 3, 2, 1, 0, 38, 40, 5, 6, 0, 0, 39, 38, 1, 0, 0, 0, 39, 40, 1, 0, 0, 0, 40, 42, 1, 0, 0, 0, 41, 43, 3, 32, 16, 0, 42, 41, 1, 0, 0, 0, 42, 43, 1, 0, 0, 0, 43, 44, 1, 0, 0, 0, 44, 45, 5, 0, 0, 1, 45, 1, 1, 0, 0, 0, 46, 47, 3, 12, 6, 0, 47, 48, 5, 6, 0, 0, 48, 51, 3, 8, 4, 0, 49, 50, 5, 6, 0, 0, 50, 52, 3, 4, 2, 0, 51, 49, 1, 0, 0, 0, 51, 52, 1, 0, 0, 0, 52, 3, 1, 0, 0, 0, 53, 55, 3, 6, 3, 0, 54, 56, 5, 6, 0, 0, 55, 54, 1, 0, 0, 0, 55, 56, 1, 0, 0, 0, 56, 58, 1, 0, 0, 0, 57, 53, 1, 0, 0, 0, 58, 59, 1, 0, 0, 0, 59, 57, 1, 0, 0, 0, 59, 60, 1, 0, 0, 0, 60, 5, 1, 0, 0, 0, 61, 62, 5, 10, 0, 0, 62, 7, 1, 0, 0, 0, 63, 64, 3, 10, 5, 0, 64, 9, 1, 0, 0, 0, 65, 66, 5, 10, 0, 0, 66, 11, 1, 0, 0, 0, 67, 70, 3, 14, 7, 0, 68, 70, 3, 18, 9, 0, 69, 67, 1, 0, 0, 0, 69, 68, 1, 0, 0, 0, 70, 13, 1, 0, 0, 0, 71, 73, 3, 16, 8, 0, 72, 74, 3, 26, 13, 0, 73, 72, 1, 0, 0, 0, 73, 74, 1, 0, 0, 0, 74, 15, 1, 0, 0, 0, 75, 76, 3, 22, 11, 0, 76, 77, 5, 3, 0, 0, 77, 78, 3, 22, 11, 0, 78, 79, 5, 3, 0, 0, 79, 80, 3, 22, 11, 0, 80, 81, 5, 3, 0, 0, 81, 82, 3, 22, 11, 0, 82, 17, 1, 0, 0, 0, 83, 85, 3, 20, 10, 0, 84, 86, 3, 26, 13, 0, 85, 84, 1, 0, 0, 0, 85, 86, 1, 0, 0, 0, 86, 19, 1, 0, 0, 0, 87, 88, 3, 24, 12, 0, 88, 89, 5, 4, 0, 0, 89, 91, 1, 0, 0, 0, 90, 87, 1, 0, 0, 0, 91, 92, 1, 0, 0, 0, 92, 90, 1, 0, 0, 0, 92, 93, 1, 0, 0, 0, 93, 94, 1, 0, 0, 0, 94, 95, 3, 24, 12, 0, 95, 21, 1, 0, 0, 0, 96, 97, 5, 8, 0, 0, 97, 23, 1, 0, 0, 0, 98, 99, 5, 9, 0, 0, 99, 25, 1, 0, 0, 0, 100, 101, 5, 2, 0, 0, 101, 102, 3, 28, 14, 0, 102, 27, 1, 0, 0, 0, 103, 104, 5, 8, 0, 0, 104, 29, 1, 0, 0, 0, 105, 106, 5, 1, 0, 0, 106, 31, 1, 0, 0, 0, 107, 108, 5, 1, 0, 0, 108, 33, 1, 0, 0, 0, 10, 35, 39, 42, 51, 55, 59, 69, 73, 85, 92]
|
14
handlers/hosts/parser/Hosts.tokens
Normal file
14
handlers/hosts/parser/Hosts.tokens
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
COMMENTLINE=1
|
||||||
|
SLASH=2
|
||||||
|
DOT=3
|
||||||
|
COLON=4
|
||||||
|
HASHTAG=5
|
||||||
|
SEPARATOR=6
|
||||||
|
NEWLINE=7
|
||||||
|
DIGITS=8
|
||||||
|
OCTETS=9
|
||||||
|
DOMAIN=10
|
||||||
|
'/'=2
|
||||||
|
'.'=3
|
||||||
|
':'=4
|
||||||
|
'#'=5
|
50
handlers/hosts/parser/HostsLexer.interp
Normal file
50
handlers/hosts/parser/HostsLexer.interp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
token literal names:
|
||||||
|
null
|
||||||
|
null
|
||||||
|
'/'
|
||||||
|
'.'
|
||||||
|
':'
|
||||||
|
'#'
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
|
||||||
|
token symbolic names:
|
||||||
|
null
|
||||||
|
COMMENTLINE
|
||||||
|
SLASH
|
||||||
|
DOT
|
||||||
|
COLON
|
||||||
|
HASHTAG
|
||||||
|
SEPARATOR
|
||||||
|
NEWLINE
|
||||||
|
DIGITS
|
||||||
|
OCTETS
|
||||||
|
DOMAIN
|
||||||
|
|
||||||
|
rule names:
|
||||||
|
COMMENTLINE
|
||||||
|
SLASH
|
||||||
|
DOT
|
||||||
|
COLON
|
||||||
|
HASHTAG
|
||||||
|
SEPARATOR
|
||||||
|
NEWLINE
|
||||||
|
DIGITS
|
||||||
|
DIGIT
|
||||||
|
OCTETS
|
||||||
|
OCTET
|
||||||
|
DOMAIN
|
||||||
|
STRING
|
||||||
|
|
||||||
|
channel names:
|
||||||
|
DEFAULT_TOKEN_CHANNEL
|
||||||
|
HIDDEN
|
||||||
|
|
||||||
|
mode names:
|
||||||
|
DEFAULT_MODE
|
||||||
|
|
||||||
|
atn:
|
||||||
|
[4, 0, 10, 83, 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, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 1, 0, 1, 0, 4, 0, 30, 8, 0, 11, 0, 12, 0, 31, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 4, 5, 43, 8, 5, 11, 5, 12, 5, 44, 1, 6, 3, 6, 48, 8, 6, 1, 6, 1, 6, 1, 7, 4, 7, 53, 8, 7, 11, 7, 12, 7, 54, 1, 8, 1, 8, 1, 9, 4, 9, 60, 8, 9, 11, 9, 12, 9, 61, 1, 10, 1, 10, 1, 11, 4, 11, 67, 8, 11, 11, 11, 12, 11, 68, 1, 11, 1, 11, 4, 11, 73, 8, 11, 11, 11, 12, 11, 74, 5, 11, 77, 8, 11, 10, 11, 12, 11, 80, 9, 11, 1, 12, 1, 12, 0, 0, 13, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 0, 19, 9, 21, 0, 23, 10, 25, 0, 1, 0, 8, 2, 0, 10, 10, 13, 13, 2, 0, 9, 9, 32, 32, 1, 0, 13, 13, 1, 0, 10, 10, 1, 0, 48, 57, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 65, 90, 97, 122, 5, 0, 9, 10, 13, 13, 32, 32, 35, 35, 46, 46, 87, 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, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 1, 27, 1, 0, 0, 0, 3, 33, 1, 0, 0, 0, 5, 35, 1, 0, 0, 0, 7, 37, 1, 0, 0, 0, 9, 39, 1, 0, 0, 0, 11, 42, 1, 0, 0, 0, 13, 47, 1, 0, 0, 0, 15, 52, 1, 0, 0, 0, 17, 56, 1, 0, 0, 0, 19, 59, 1, 0, 0, 0, 21, 63, 1, 0, 0, 0, 23, 66, 1, 0, 0, 0, 25, 81, 1, 0, 0, 0, 27, 29, 3, 9, 4, 0, 28, 30, 8, 0, 0, 0, 29, 28, 1, 0, 0, 0, 30, 31, 1, 0, 0, 0, 31, 29, 1, 0, 0, 0, 31, 32, 1, 0, 0, 0, 32, 2, 1, 0, 0, 0, 33, 34, 5, 47, 0, 0, 34, 4, 1, 0, 0, 0, 35, 36, 5, 46, 0, 0, 36, 6, 1, 0, 0, 0, 37, 38, 5, 58, 0, 0, 38, 8, 1, 0, 0, 0, 39, 40, 5, 35, 0, 0, 40, 10, 1, 0, 0, 0, 41, 43, 7, 1, 0, 0, 42, 41, 1, 0, 0, 0, 43, 44, 1, 0, 0, 0, 44, 42, 1, 0, 0, 0, 44, 45, 1, 0, 0, 0, 45, 12, 1, 0, 0, 0, 46, 48, 7, 2, 0, 0, 47, 46, 1, 0, 0, 0, 47, 48, 1, 0, 0, 0, 48, 49, 1, 0, 0, 0, 49, 50, 7, 3, 0, 0, 50, 14, 1, 0, 0, 0, 51, 53, 3, 17, 8, 0, 52, 51, 1, 0, 0, 0, 53, 54, 1, 0, 0, 0, 54, 52, 1, 0, 0, 0, 54, 55, 1, 0, 0, 0, 55, 16, 1, 0, 0, 0, 56, 57, 7, 4, 0, 0, 57, 18, 1, 0, 0, 0, 58, 60, 3, 21, 10, 0, 59, 58, 1, 0, 0, 0, 60, 61, 1, 0, 0, 0, 61, 59, 1, 0, 0, 0, 61, 62, 1, 0, 0, 0, 62, 20, 1, 0, 0, 0, 63, 64, 7, 5, 0, 0, 64, 22, 1, 0, 0, 0, 65, 67, 3, 25, 12, 0, 66, 65, 1, 0, 0, 0, 67, 68, 1, 0, 0, 0, 68, 66, 1, 0, 0, 0, 68, 69, 1, 0, 0, 0, 69, 78, 1, 0, 0, 0, 70, 72, 3, 5, 2, 0, 71, 73, 7, 6, 0, 0, 72, 71, 1, 0, 0, 0, 73, 74, 1, 0, 0, 0, 74, 72, 1, 0, 0, 0, 74, 75, 1, 0, 0, 0, 75, 77, 1, 0, 0, 0, 76, 70, 1, 0, 0, 0, 77, 80, 1, 0, 0, 0, 78, 76, 1, 0, 0, 0, 78, 79, 1, 0, 0, 0, 79, 24, 1, 0, 0, 0, 80, 78, 1, 0, 0, 0, 81, 82, 8, 7, 0, 0, 82, 26, 1, 0, 0, 0, 9, 0, 31, 44, 47, 54, 61, 68, 74, 78, 0]
|
14
handlers/hosts/parser/HostsLexer.tokens
Normal file
14
handlers/hosts/parser/HostsLexer.tokens
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
COMMENTLINE=1
|
||||||
|
SLASH=2
|
||||||
|
DOT=3
|
||||||
|
COLON=4
|
||||||
|
HASHTAG=5
|
||||||
|
SEPARATOR=6
|
||||||
|
NEWLINE=7
|
||||||
|
DIGITS=8
|
||||||
|
OCTETS=9
|
||||||
|
DOMAIN=10
|
||||||
|
'/'=2
|
||||||
|
'.'=3
|
||||||
|
':'=4
|
||||||
|
'#'=5
|
124
handlers/hosts/parser/hosts_base_listener.go
Normal file
124
handlers/hosts/parser/hosts_base_listener.go
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
// Code generated from Hosts.g4 by ANTLR 4.13.0. DO NOT EDIT.
|
||||||
|
|
||||||
|
package parser // Hosts
|
||||||
|
|
||||||
|
import "github.com/antlr4-go/antlr/v4"
|
||||||
|
|
||||||
|
// BaseHostsListener is a complete listener for a parse tree produced by HostsParser.
|
||||||
|
type BaseHostsListener struct{}
|
||||||
|
|
||||||
|
var _ HostsListener = &BaseHostsListener{}
|
||||||
|
|
||||||
|
// VisitTerminal is called when a terminal node is visited.
|
||||||
|
func (s *BaseHostsListener) VisitTerminal(node antlr.TerminalNode) {}
|
||||||
|
|
||||||
|
// VisitErrorNode is called when an error node is visited.
|
||||||
|
func (s *BaseHostsListener) VisitErrorNode(node antlr.ErrorNode) {}
|
||||||
|
|
||||||
|
// EnterEveryRule is called when any rule is entered.
|
||||||
|
func (s *BaseHostsListener) EnterEveryRule(ctx antlr.ParserRuleContext) {}
|
||||||
|
|
||||||
|
// ExitEveryRule is called when any rule is exited.
|
||||||
|
func (s *BaseHostsListener) ExitEveryRule(ctx antlr.ParserRuleContext) {}
|
||||||
|
|
||||||
|
// EnterLineStatement is called when production lineStatement is entered.
|
||||||
|
func (s *BaseHostsListener) EnterLineStatement(ctx *LineStatementContext) {}
|
||||||
|
|
||||||
|
// ExitLineStatement is called when production lineStatement is exited.
|
||||||
|
func (s *BaseHostsListener) ExitLineStatement(ctx *LineStatementContext) {}
|
||||||
|
|
||||||
|
// EnterEntry is called when production entry is entered.
|
||||||
|
func (s *BaseHostsListener) EnterEntry(ctx *EntryContext) {}
|
||||||
|
|
||||||
|
// ExitEntry is called when production entry is exited.
|
||||||
|
func (s *BaseHostsListener) ExitEntry(ctx *EntryContext) {}
|
||||||
|
|
||||||
|
// EnterAliases is called when production aliases is entered.
|
||||||
|
func (s *BaseHostsListener) EnterAliases(ctx *AliasesContext) {}
|
||||||
|
|
||||||
|
// ExitAliases is called when production aliases is exited.
|
||||||
|
func (s *BaseHostsListener) ExitAliases(ctx *AliasesContext) {}
|
||||||
|
|
||||||
|
// EnterAlias is called when production alias is entered.
|
||||||
|
func (s *BaseHostsListener) EnterAlias(ctx *AliasContext) {}
|
||||||
|
|
||||||
|
// ExitAlias is called when production alias is exited.
|
||||||
|
func (s *BaseHostsListener) ExitAlias(ctx *AliasContext) {}
|
||||||
|
|
||||||
|
// EnterHostname is called when production hostname is entered.
|
||||||
|
func (s *BaseHostsListener) EnterHostname(ctx *HostnameContext) {}
|
||||||
|
|
||||||
|
// ExitHostname is called when production hostname is exited.
|
||||||
|
func (s *BaseHostsListener) ExitHostname(ctx *HostnameContext) {}
|
||||||
|
|
||||||
|
// EnterDomain is called when production domain is entered.
|
||||||
|
func (s *BaseHostsListener) EnterDomain(ctx *DomainContext) {}
|
||||||
|
|
||||||
|
// ExitDomain is called when production domain is exited.
|
||||||
|
func (s *BaseHostsListener) ExitDomain(ctx *DomainContext) {}
|
||||||
|
|
||||||
|
// EnterIpAddress is called when production ipAddress is entered.
|
||||||
|
func (s *BaseHostsListener) EnterIpAddress(ctx *IpAddressContext) {}
|
||||||
|
|
||||||
|
// ExitIpAddress is called when production ipAddress is exited.
|
||||||
|
func (s *BaseHostsListener) ExitIpAddress(ctx *IpAddressContext) {}
|
||||||
|
|
||||||
|
// EnterIpv4Address is called when production ipv4Address is entered.
|
||||||
|
func (s *BaseHostsListener) EnterIpv4Address(ctx *Ipv4AddressContext) {}
|
||||||
|
|
||||||
|
// ExitIpv4Address is called when production ipv4Address is exited.
|
||||||
|
func (s *BaseHostsListener) ExitIpv4Address(ctx *Ipv4AddressContext) {}
|
||||||
|
|
||||||
|
// EnterSingleIPv4Address is called when production singleIPv4Address is entered.
|
||||||
|
func (s *BaseHostsListener) EnterSingleIPv4Address(ctx *SingleIPv4AddressContext) {}
|
||||||
|
|
||||||
|
// ExitSingleIPv4Address is called when production singleIPv4Address is exited.
|
||||||
|
func (s *BaseHostsListener) ExitSingleIPv4Address(ctx *SingleIPv4AddressContext) {}
|
||||||
|
|
||||||
|
// EnterIpv6Address is called when production ipv6Address is entered.
|
||||||
|
func (s *BaseHostsListener) EnterIpv6Address(ctx *Ipv6AddressContext) {}
|
||||||
|
|
||||||
|
// ExitIpv6Address is called when production ipv6Address is exited.
|
||||||
|
func (s *BaseHostsListener) ExitIpv6Address(ctx *Ipv6AddressContext) {}
|
||||||
|
|
||||||
|
// EnterSingleIPv6Address is called when production singleIPv6Address is entered.
|
||||||
|
func (s *BaseHostsListener) EnterSingleIPv6Address(ctx *SingleIPv6AddressContext) {}
|
||||||
|
|
||||||
|
// ExitSingleIPv6Address is called when production singleIPv6Address is exited.
|
||||||
|
func (s *BaseHostsListener) ExitSingleIPv6Address(ctx *SingleIPv6AddressContext) {}
|
||||||
|
|
||||||
|
// EnterIpv4Digit is called when production ipv4Digit is entered.
|
||||||
|
func (s *BaseHostsListener) EnterIpv4Digit(ctx *Ipv4DigitContext) {}
|
||||||
|
|
||||||
|
// ExitIpv4Digit is called when production ipv4Digit is exited.
|
||||||
|
func (s *BaseHostsListener) ExitIpv4Digit(ctx *Ipv4DigitContext) {}
|
||||||
|
|
||||||
|
// EnterIpv6Octet is called when production ipv6Octet is entered.
|
||||||
|
func (s *BaseHostsListener) EnterIpv6Octet(ctx *Ipv6OctetContext) {}
|
||||||
|
|
||||||
|
// ExitIpv6Octet is called when production ipv6Octet is exited.
|
||||||
|
func (s *BaseHostsListener) ExitIpv6Octet(ctx *Ipv6OctetContext) {}
|
||||||
|
|
||||||
|
// EnterIpRange is called when production ipRange is entered.
|
||||||
|
func (s *BaseHostsListener) EnterIpRange(ctx *IpRangeContext) {}
|
||||||
|
|
||||||
|
// ExitIpRange is called when production ipRange is exited.
|
||||||
|
func (s *BaseHostsListener) ExitIpRange(ctx *IpRangeContext) {}
|
||||||
|
|
||||||
|
// EnterIpRangeBits is called when production ipRangeBits is entered.
|
||||||
|
func (s *BaseHostsListener) EnterIpRangeBits(ctx *IpRangeBitsContext) {}
|
||||||
|
|
||||||
|
// ExitIpRangeBits is called when production ipRangeBits is exited.
|
||||||
|
func (s *BaseHostsListener) ExitIpRangeBits(ctx *IpRangeBitsContext) {}
|
||||||
|
|
||||||
|
// EnterComment is called when production comment is entered.
|
||||||
|
func (s *BaseHostsListener) EnterComment(ctx *CommentContext) {}
|
||||||
|
|
||||||
|
// ExitComment is called when production comment is exited.
|
||||||
|
func (s *BaseHostsListener) ExitComment(ctx *CommentContext) {}
|
||||||
|
|
||||||
|
// EnterLeadingComment is called when production leadingComment is entered.
|
||||||
|
func (s *BaseHostsListener) EnterLeadingComment(ctx *LeadingCommentContext) {}
|
||||||
|
|
||||||
|
// ExitLeadingComment is called when production leadingComment is exited.
|
||||||
|
func (s *BaseHostsListener) ExitLeadingComment(ctx *LeadingCommentContext) {}
|
145
handlers/hosts/parser/hosts_lexer.go
Normal file
145
handlers/hosts/parser/hosts_lexer.go
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
// Code generated from Hosts.g4 by ANTLR 4.13.0. DO NOT EDIT.
|
||||||
|
|
||||||
|
package parser
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/antlr4-go/antlr/v4"
|
||||||
|
"sync"
|
||||||
|
"unicode"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Suppress unused import error
|
||||||
|
var _ = fmt.Printf
|
||||||
|
var _ = sync.Once{}
|
||||||
|
var _ = unicode.IsLetter
|
||||||
|
|
||||||
|
type HostsLexer struct {
|
||||||
|
*antlr.BaseLexer
|
||||||
|
channelNames []string
|
||||||
|
modeNames []string
|
||||||
|
// TODO: EOF string
|
||||||
|
}
|
||||||
|
|
||||||
|
var HostsLexerLexerStaticData struct {
|
||||||
|
once sync.Once
|
||||||
|
serializedATN []int32
|
||||||
|
ChannelNames []string
|
||||||
|
ModeNames []string
|
||||||
|
LiteralNames []string
|
||||||
|
SymbolicNames []string
|
||||||
|
RuleNames []string
|
||||||
|
PredictionContextCache *antlr.PredictionContextCache
|
||||||
|
atn *antlr.ATN
|
||||||
|
decisionToDFA []*antlr.DFA
|
||||||
|
}
|
||||||
|
|
||||||
|
func hostslexerLexerInit() {
|
||||||
|
staticData := &HostsLexerLexerStaticData
|
||||||
|
staticData.ChannelNames = []string{
|
||||||
|
"DEFAULT_TOKEN_CHANNEL", "HIDDEN",
|
||||||
|
}
|
||||||
|
staticData.ModeNames = []string{
|
||||||
|
"DEFAULT_MODE",
|
||||||
|
}
|
||||||
|
staticData.LiteralNames = []string{
|
||||||
|
"", "", "'/'", "'.'", "':'", "'#'",
|
||||||
|
}
|
||||||
|
staticData.SymbolicNames = []string{
|
||||||
|
"", "COMMENTLINE", "SLASH", "DOT", "COLON", "HASHTAG", "SEPARATOR",
|
||||||
|
"NEWLINE", "DIGITS", "OCTETS", "DOMAIN",
|
||||||
|
}
|
||||||
|
staticData.RuleNames = []string{
|
||||||
|
"COMMENTLINE", "SLASH", "DOT", "COLON", "HASHTAG", "SEPARATOR", "NEWLINE",
|
||||||
|
"DIGITS", "DIGIT", "OCTETS", "OCTET", "DOMAIN", "STRING",
|
||||||
|
}
|
||||||
|
staticData.PredictionContextCache = antlr.NewPredictionContextCache()
|
||||||
|
staticData.serializedATN = []int32{
|
||||||
|
4, 0, 10, 83, 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, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2,
|
||||||
|
10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 1, 0, 1, 0, 4, 0, 30, 8, 0, 11,
|
||||||
|
0, 12, 0, 31, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 4,
|
||||||
|
5, 43, 8, 5, 11, 5, 12, 5, 44, 1, 6, 3, 6, 48, 8, 6, 1, 6, 1, 6, 1, 7,
|
||||||
|
4, 7, 53, 8, 7, 11, 7, 12, 7, 54, 1, 8, 1, 8, 1, 9, 4, 9, 60, 8, 9, 11,
|
||||||
|
9, 12, 9, 61, 1, 10, 1, 10, 1, 11, 4, 11, 67, 8, 11, 11, 11, 12, 11, 68,
|
||||||
|
1, 11, 1, 11, 4, 11, 73, 8, 11, 11, 11, 12, 11, 74, 5, 11, 77, 8, 11, 10,
|
||||||
|
11, 12, 11, 80, 9, 11, 1, 12, 1, 12, 0, 0, 13, 1, 1, 3, 2, 5, 3, 7, 4,
|
||||||
|
9, 5, 11, 6, 13, 7, 15, 8, 17, 0, 19, 9, 21, 0, 23, 10, 25, 0, 1, 0, 8,
|
||||||
|
2, 0, 10, 10, 13, 13, 2, 0, 9, 9, 32, 32, 1, 0, 13, 13, 1, 0, 10, 10, 1,
|
||||||
|
0, 48, 57, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 65, 90, 97, 122, 5, 0,
|
||||||
|
9, 10, 13, 13, 32, 32, 35, 35, 46, 46, 87, 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, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 23, 1,
|
||||||
|
0, 0, 0, 1, 27, 1, 0, 0, 0, 3, 33, 1, 0, 0, 0, 5, 35, 1, 0, 0, 0, 7, 37,
|
||||||
|
1, 0, 0, 0, 9, 39, 1, 0, 0, 0, 11, 42, 1, 0, 0, 0, 13, 47, 1, 0, 0, 0,
|
||||||
|
15, 52, 1, 0, 0, 0, 17, 56, 1, 0, 0, 0, 19, 59, 1, 0, 0, 0, 21, 63, 1,
|
||||||
|
0, 0, 0, 23, 66, 1, 0, 0, 0, 25, 81, 1, 0, 0, 0, 27, 29, 3, 9, 4, 0, 28,
|
||||||
|
30, 8, 0, 0, 0, 29, 28, 1, 0, 0, 0, 30, 31, 1, 0, 0, 0, 31, 29, 1, 0, 0,
|
||||||
|
0, 31, 32, 1, 0, 0, 0, 32, 2, 1, 0, 0, 0, 33, 34, 5, 47, 0, 0, 34, 4, 1,
|
||||||
|
0, 0, 0, 35, 36, 5, 46, 0, 0, 36, 6, 1, 0, 0, 0, 37, 38, 5, 58, 0, 0, 38,
|
||||||
|
8, 1, 0, 0, 0, 39, 40, 5, 35, 0, 0, 40, 10, 1, 0, 0, 0, 41, 43, 7, 1, 0,
|
||||||
|
0, 42, 41, 1, 0, 0, 0, 43, 44, 1, 0, 0, 0, 44, 42, 1, 0, 0, 0, 44, 45,
|
||||||
|
1, 0, 0, 0, 45, 12, 1, 0, 0, 0, 46, 48, 7, 2, 0, 0, 47, 46, 1, 0, 0, 0,
|
||||||
|
47, 48, 1, 0, 0, 0, 48, 49, 1, 0, 0, 0, 49, 50, 7, 3, 0, 0, 50, 14, 1,
|
||||||
|
0, 0, 0, 51, 53, 3, 17, 8, 0, 52, 51, 1, 0, 0, 0, 53, 54, 1, 0, 0, 0, 54,
|
||||||
|
52, 1, 0, 0, 0, 54, 55, 1, 0, 0, 0, 55, 16, 1, 0, 0, 0, 56, 57, 7, 4, 0,
|
||||||
|
0, 57, 18, 1, 0, 0, 0, 58, 60, 3, 21, 10, 0, 59, 58, 1, 0, 0, 0, 60, 61,
|
||||||
|
1, 0, 0, 0, 61, 59, 1, 0, 0, 0, 61, 62, 1, 0, 0, 0, 62, 20, 1, 0, 0, 0,
|
||||||
|
63, 64, 7, 5, 0, 0, 64, 22, 1, 0, 0, 0, 65, 67, 3, 25, 12, 0, 66, 65, 1,
|
||||||
|
0, 0, 0, 67, 68, 1, 0, 0, 0, 68, 66, 1, 0, 0, 0, 68, 69, 1, 0, 0, 0, 69,
|
||||||
|
78, 1, 0, 0, 0, 70, 72, 3, 5, 2, 0, 71, 73, 7, 6, 0, 0, 72, 71, 1, 0, 0,
|
||||||
|
0, 73, 74, 1, 0, 0, 0, 74, 72, 1, 0, 0, 0, 74, 75, 1, 0, 0, 0, 75, 77,
|
||||||
|
1, 0, 0, 0, 76, 70, 1, 0, 0, 0, 77, 80, 1, 0, 0, 0, 78, 76, 1, 0, 0, 0,
|
||||||
|
78, 79, 1, 0, 0, 0, 79, 24, 1, 0, 0, 0, 80, 78, 1, 0, 0, 0, 81, 82, 8,
|
||||||
|
7, 0, 0, 82, 26, 1, 0, 0, 0, 9, 0, 31, 44, 47, 54, 61, 68, 74, 78, 0,
|
||||||
|
}
|
||||||
|
deserializer := antlr.NewATNDeserializer(nil)
|
||||||
|
staticData.atn = deserializer.Deserialize(staticData.serializedATN)
|
||||||
|
atn := staticData.atn
|
||||||
|
staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState))
|
||||||
|
decisionToDFA := staticData.decisionToDFA
|
||||||
|
for index, state := range atn.DecisionToState {
|
||||||
|
decisionToDFA[index] = antlr.NewDFA(state, index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HostsLexerInit initializes any static state used to implement HostsLexer. By default the
|
||||||
|
// static state used to implement the lexer is lazily initialized during the first call to
|
||||||
|
// NewHostsLexer(). You can call this function if you wish to initialize the static state ahead
|
||||||
|
// of time.
|
||||||
|
func HostsLexerInit() {
|
||||||
|
staticData := &HostsLexerLexerStaticData
|
||||||
|
staticData.once.Do(hostslexerLexerInit)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHostsLexer produces a new lexer instance for the optional input antlr.CharStream.
|
||||||
|
func NewHostsLexer(input antlr.CharStream) *HostsLexer {
|
||||||
|
HostsLexerInit()
|
||||||
|
l := new(HostsLexer)
|
||||||
|
l.BaseLexer = antlr.NewBaseLexer(input)
|
||||||
|
staticData := &HostsLexerLexerStaticData
|
||||||
|
l.Interpreter = antlr.NewLexerATNSimulator(l, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache)
|
||||||
|
l.channelNames = staticData.ChannelNames
|
||||||
|
l.modeNames = staticData.ModeNames
|
||||||
|
l.RuleNames = staticData.RuleNames
|
||||||
|
l.LiteralNames = staticData.LiteralNames
|
||||||
|
l.SymbolicNames = staticData.SymbolicNames
|
||||||
|
l.GrammarFileName = "Hosts.g4"
|
||||||
|
// TODO: l.EOF = antlr.TokenEOF
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// HostsLexer tokens.
|
||||||
|
const (
|
||||||
|
HostsLexerCOMMENTLINE = 1
|
||||||
|
HostsLexerSLASH = 2
|
||||||
|
HostsLexerDOT = 3
|
||||||
|
HostsLexerCOLON = 4
|
||||||
|
HostsLexerHASHTAG = 5
|
||||||
|
HostsLexerSEPARATOR = 6
|
||||||
|
HostsLexerNEWLINE = 7
|
||||||
|
HostsLexerDIGITS = 8
|
||||||
|
HostsLexerOCTETS = 9
|
||||||
|
HostsLexerDOMAIN = 10
|
||||||
|
)
|
112
handlers/hosts/parser/hosts_listener.go
Normal file
112
handlers/hosts/parser/hosts_listener.go
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
// Code generated from Hosts.g4 by ANTLR 4.13.0. DO NOT EDIT.
|
||||||
|
|
||||||
|
package parser // Hosts
|
||||||
|
|
||||||
|
import "github.com/antlr4-go/antlr/v4"
|
||||||
|
|
||||||
|
// HostsListener is a complete listener for a parse tree produced by HostsParser.
|
||||||
|
type HostsListener interface {
|
||||||
|
antlr.ParseTreeListener
|
||||||
|
|
||||||
|
// EnterLineStatement is called when entering the lineStatement production.
|
||||||
|
EnterLineStatement(c *LineStatementContext)
|
||||||
|
|
||||||
|
// EnterEntry is called when entering the entry production.
|
||||||
|
EnterEntry(c *EntryContext)
|
||||||
|
|
||||||
|
// EnterAliases is called when entering the aliases production.
|
||||||
|
EnterAliases(c *AliasesContext)
|
||||||
|
|
||||||
|
// EnterAlias is called when entering the alias production.
|
||||||
|
EnterAlias(c *AliasContext)
|
||||||
|
|
||||||
|
// EnterHostname is called when entering the hostname production.
|
||||||
|
EnterHostname(c *HostnameContext)
|
||||||
|
|
||||||
|
// EnterDomain is called when entering the domain production.
|
||||||
|
EnterDomain(c *DomainContext)
|
||||||
|
|
||||||
|
// EnterIpAddress is called when entering the ipAddress production.
|
||||||
|
EnterIpAddress(c *IpAddressContext)
|
||||||
|
|
||||||
|
// EnterIpv4Address is called when entering the ipv4Address production.
|
||||||
|
EnterIpv4Address(c *Ipv4AddressContext)
|
||||||
|
|
||||||
|
// EnterSingleIPv4Address is called when entering the singleIPv4Address production.
|
||||||
|
EnterSingleIPv4Address(c *SingleIPv4AddressContext)
|
||||||
|
|
||||||
|
// EnterIpv6Address is called when entering the ipv6Address production.
|
||||||
|
EnterIpv6Address(c *Ipv6AddressContext)
|
||||||
|
|
||||||
|
// EnterSingleIPv6Address is called when entering the singleIPv6Address production.
|
||||||
|
EnterSingleIPv6Address(c *SingleIPv6AddressContext)
|
||||||
|
|
||||||
|
// EnterIpv4Digit is called when entering the ipv4Digit production.
|
||||||
|
EnterIpv4Digit(c *Ipv4DigitContext)
|
||||||
|
|
||||||
|
// EnterIpv6Octet is called when entering the ipv6Octet production.
|
||||||
|
EnterIpv6Octet(c *Ipv6OctetContext)
|
||||||
|
|
||||||
|
// EnterIpRange is called when entering the ipRange production.
|
||||||
|
EnterIpRange(c *IpRangeContext)
|
||||||
|
|
||||||
|
// EnterIpRangeBits is called when entering the ipRangeBits production.
|
||||||
|
EnterIpRangeBits(c *IpRangeBitsContext)
|
||||||
|
|
||||||
|
// EnterComment is called when entering the comment production.
|
||||||
|
EnterComment(c *CommentContext)
|
||||||
|
|
||||||
|
// EnterLeadingComment is called when entering the leadingComment production.
|
||||||
|
EnterLeadingComment(c *LeadingCommentContext)
|
||||||
|
|
||||||
|
// ExitLineStatement is called when exiting the lineStatement production.
|
||||||
|
ExitLineStatement(c *LineStatementContext)
|
||||||
|
|
||||||
|
// ExitEntry is called when exiting the entry production.
|
||||||
|
ExitEntry(c *EntryContext)
|
||||||
|
|
||||||
|
// ExitAliases is called when exiting the aliases production.
|
||||||
|
ExitAliases(c *AliasesContext)
|
||||||
|
|
||||||
|
// ExitAlias is called when exiting the alias production.
|
||||||
|
ExitAlias(c *AliasContext)
|
||||||
|
|
||||||
|
// ExitHostname is called when exiting the hostname production.
|
||||||
|
ExitHostname(c *HostnameContext)
|
||||||
|
|
||||||
|
// ExitDomain is called when exiting the domain production.
|
||||||
|
ExitDomain(c *DomainContext)
|
||||||
|
|
||||||
|
// ExitIpAddress is called when exiting the ipAddress production.
|
||||||
|
ExitIpAddress(c *IpAddressContext)
|
||||||
|
|
||||||
|
// ExitIpv4Address is called when exiting the ipv4Address production.
|
||||||
|
ExitIpv4Address(c *Ipv4AddressContext)
|
||||||
|
|
||||||
|
// ExitSingleIPv4Address is called when exiting the singleIPv4Address production.
|
||||||
|
ExitSingleIPv4Address(c *SingleIPv4AddressContext)
|
||||||
|
|
||||||
|
// ExitIpv6Address is called when exiting the ipv6Address production.
|
||||||
|
ExitIpv6Address(c *Ipv6AddressContext)
|
||||||
|
|
||||||
|
// ExitSingleIPv6Address is called when exiting the singleIPv6Address production.
|
||||||
|
ExitSingleIPv6Address(c *SingleIPv6AddressContext)
|
||||||
|
|
||||||
|
// ExitIpv4Digit is called when exiting the ipv4Digit production.
|
||||||
|
ExitIpv4Digit(c *Ipv4DigitContext)
|
||||||
|
|
||||||
|
// ExitIpv6Octet is called when exiting the ipv6Octet production.
|
||||||
|
ExitIpv6Octet(c *Ipv6OctetContext)
|
||||||
|
|
||||||
|
// ExitIpRange is called when exiting the ipRange production.
|
||||||
|
ExitIpRange(c *IpRangeContext)
|
||||||
|
|
||||||
|
// ExitIpRangeBits is called when exiting the ipRangeBits production.
|
||||||
|
ExitIpRangeBits(c *IpRangeBitsContext)
|
||||||
|
|
||||||
|
// ExitComment is called when exiting the comment production.
|
||||||
|
ExitComment(c *CommentContext)
|
||||||
|
|
||||||
|
// ExitLeadingComment is called when exiting the leadingComment production.
|
||||||
|
ExitLeadingComment(c *LeadingCommentContext)
|
||||||
|
}
|
2369
handlers/hosts/parser/hosts_parser.go
Normal file
2369
handlers/hosts/parser/hosts_parser.go
Normal file
File diff suppressed because it is too large
Load Diff
82
handlers/hosts/tree/handler.go
Normal file
82
handlers/hosts/tree/handler.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package tree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"config-lsp/common"
|
||||||
|
"config-lsp/handlers/hosts/parser"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/antlr4-go/antlr/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *HostsParser) Clear() {
|
||||||
|
p.Tree = HostsTree{
|
||||||
|
Entries: make(map[uint32]*HostsEntry),
|
||||||
|
}
|
||||||
|
p.CommentLines = make(map[uint32]struct{})
|
||||||
|
}
|
||||||
|
|
||||||
|
var commentPattern = regexp.MustCompile(`^\s*#.*$`)
|
||||||
|
var emptyPattern = regexp.MustCompile(`^\s*$`)
|
||||||
|
|
||||||
|
func (p *HostsParser) parseStatement(
|
||||||
|
line uint32,
|
||||||
|
input string,
|
||||||
|
) []common.LSPError {
|
||||||
|
stream := antlr.NewInputStream(input)
|
||||||
|
|
||||||
|
errorListener := createErrorListener(line)
|
||||||
|
lexer := parser.NewHostsLexer(stream)
|
||||||
|
lexer.RemoveErrorListeners()
|
||||||
|
lexer.AddErrorListener(&errorListener)
|
||||||
|
|
||||||
|
errors := errorListener.Errors
|
||||||
|
|
||||||
|
errorListener = createErrorListener(line)
|
||||||
|
tokenStream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
|
||||||
|
antlrParser := parser.NewHostsParser(tokenStream)
|
||||||
|
antlrParser.RemoveErrorListeners()
|
||||||
|
antlrParser.AddErrorListener(&errorListener)
|
||||||
|
|
||||||
|
listener := createHostsFileListener(p, line)
|
||||||
|
antlr.ParseTreeWalkerDefault.Walk(
|
||||||
|
&listener,
|
||||||
|
antlrParser.LineStatement(),
|
||||||
|
)
|
||||||
|
|
||||||
|
errors = append(errors, errorListener.Errors...)
|
||||||
|
|
||||||
|
return errors
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *HostsParser) Parse(input string) []common.LSPError {
|
||||||
|
errors := make([]common.LSPError, 0)
|
||||||
|
lines := strings.Split(input, "\n")
|
||||||
|
|
||||||
|
for rawLineNumber, line := range lines {
|
||||||
|
lineNumber := uint32(rawLineNumber + 1)
|
||||||
|
|
||||||
|
if commentPattern.MatchString(line) {
|
||||||
|
p.CommentLines[lineNumber] = struct{}{}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if emptyPattern.MatchString(line) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
errors = append(
|
||||||
|
errors,
|
||||||
|
p.parseStatement(lineNumber, line)...,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateNewHostsParser() HostsParser {
|
||||||
|
p := HostsParser{}
|
||||||
|
p.Clear()
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
143
handlers/hosts/tree/handler_test.go
Normal file
143
handlers/hosts/tree/handler_test.go
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
package tree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"config-lsp/utils"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestValidSimpleExampleWorks(
|
||||||
|
t *testing.T,
|
||||||
|
) {
|
||||||
|
input := utils.Dedent(`
|
||||||
|
1.2.3.4 hello.com
|
||||||
|
`)
|
||||||
|
|
||||||
|
parser := CreateNewHostsParser()
|
||||||
|
errors := parser.Parse(input)
|
||||||
|
|
||||||
|
if len(errors) != 0 {
|
||||||
|
t.Errorf("Expected no errors, but got %v", errors)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(len(parser.Tree.Entries) == 1) {
|
||||||
|
t.Errorf("Expected 1 entry, but got %v", len(parser.Tree.Entries))
|
||||||
|
}
|
||||||
|
|
||||||
|
if parser.Tree.Entries[1].IPAddress == nil {
|
||||||
|
t.Errorf("Expected IP address to be present, but got nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(parser.Tree.Entries[1].IPAddress.Value == "1.2.3.4") {
|
||||||
|
t.Errorf("Expected IP address to be 1.2.3.4, but got %v", parser.Tree.Entries[1].IPAddress.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(parser.Tree.Entries[1].Hostname.Value == "hello.com") {
|
||||||
|
t.Errorf("Expected hostname to be hello.com, but got %v", parser.Tree.Entries[1].Hostname.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(parser.Tree.Entries[1].Aliases == nil) {
|
||||||
|
t.Errorf("Expected no aliases, but got %v", parser.Tree.Entries[1].Aliases)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(parser.Tree.Entries[1].Location.Start.Line == 1) {
|
||||||
|
t.Errorf("Expected line to be 1, but got %v", parser.Tree.Entries[1].Location.Start.Line)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(parser.Tree.Entries[1].Location.Start.Character == 0) {
|
||||||
|
t.Errorf("Expected start to be 0, but got %v", parser.Tree.Entries[1].Location.Start)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(parser.Tree.Entries[1].Location.End.Character == 16) {
|
||||||
|
t.Errorf("Expected end to be 16, but got %v", parser.Tree.Entries[1].Location.End.Character)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(parser.Tree.Entries[1].IPAddress.Location.Start.Line == 1) {
|
||||||
|
t.Errorf("Expected IP address line to be 1, but got %v", parser.Tree.Entries[1].IPAddress.Location.Start.Line)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(parser.Tree.Entries[1].IPAddress.Location.Start.Character == 0) {
|
||||||
|
t.Errorf("Expected IP address start to be 0, but got %v", parser.Tree.Entries[1].IPAddress.Location.Start.Character)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(parser.Tree.Entries[1].IPAddress.Location.End.Character == 6) {
|
||||||
|
t.Errorf("Expected IP address end to be 6, but got %v", parser.Tree.Entries[1].IPAddress.Location.End.Character)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(len(parser.CommentLines) == 0) {
|
||||||
|
t.Errorf("Expected no comment lines, but got %v", len(parser.CommentLines))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidComplexExampleWorks(
|
||||||
|
t *testing.T,
|
||||||
|
) {
|
||||||
|
input := utils.Dedent(`
|
||||||
|
|
||||||
|
# This is a comment
|
||||||
|
1.2.3.4 hello.com test.com # This is another comment
|
||||||
|
5.5.5.5 test.com
|
||||||
|
1.2.3.4 example.com check.com
|
||||||
|
`)
|
||||||
|
|
||||||
|
parser := CreateNewHostsParser()
|
||||||
|
errors := parser.Parse(input)
|
||||||
|
|
||||||
|
if len(errors) != 0 {
|
||||||
|
t.Errorf("Expected no errors, but got %v", errors)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(len(parser.Tree.Entries) == 3) {
|
||||||
|
t.Errorf("Expected 3 entries, but got %v", len(parser.Tree.Entries))
|
||||||
|
}
|
||||||
|
|
||||||
|
if parser.Tree.Entries[3].IPAddress == nil {
|
||||||
|
t.Errorf("Expected IP address to be present, but got nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(parser.Tree.Entries[3].IPAddress.Value == "1.2.3.4") {
|
||||||
|
t.Errorf("Expected IP address to be 1.2.3.4, but got %v", parser.Tree.Entries[2].IPAddress.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(len(parser.CommentLines) == 1) {
|
||||||
|
t.Errorf("Expected 1 comment line, but got %v", len(parser.CommentLines))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(utils.KeyExists(parser.CommentLines, 2)) {
|
||||||
|
t.Errorf("Expected comment line 2 to exist, but it does not")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInvalidExampleWorks(
|
||||||
|
t *testing.T,
|
||||||
|
) {
|
||||||
|
input := utils.Dedent(`
|
||||||
|
1.2.3.4
|
||||||
|
`)
|
||||||
|
|
||||||
|
parser := CreateNewHostsParser()
|
||||||
|
errors := parser.Parse(input)
|
||||||
|
|
||||||
|
if len(errors) == 0 {
|
||||||
|
t.Errorf("Expected errors, but got none")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(len(parser.Tree.Entries) == 1) {
|
||||||
|
t.Errorf("Expected 1 entries, but got %v", len(parser.Tree.Entries))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(len(parser.CommentLines) == 0) {
|
||||||
|
t.Errorf("Expected no comment lines, but got %v", len(parser.CommentLines))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(parser.Tree.Entries[1].IPAddress.Value == "1.2.3.4") {
|
||||||
|
t.Errorf("Expected IP address to be nil, but got %v", parser.Tree.Entries[1].IPAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(parser.Tree.Entries[1].Hostname == nil) {
|
||||||
|
t.Errorf("Expected hostname to be nil, but got %v", parser.Tree.Entries[1].Hostname)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(parser.Tree.Entries[1].Aliases == nil) {
|
||||||
|
t.Errorf("Expected aliases to be nil, but got %v", parser.Tree.Entries[1].Aliases)
|
||||||
|
}
|
||||||
|
}
|
73
handlers/hosts/tree/hosts.go
Normal file
73
handlers/hosts/tree/hosts.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package tree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"config-lsp/common"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/antlr4-go/antlr/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
func characterRangeFromCtx(
|
||||||
|
ctx antlr.BaseParserRuleContext,
|
||||||
|
) common.LocationRange {
|
||||||
|
line := uint32(ctx.GetStart().GetLine())
|
||||||
|
start := uint32(ctx.GetStart().GetStart())
|
||||||
|
end := uint32(ctx.GetStop().GetStop())
|
||||||
|
|
||||||
|
return common.LocationRange{
|
||||||
|
Start: common.Location{
|
||||||
|
Line: line,
|
||||||
|
Character: start,
|
||||||
|
},
|
||||||
|
End: common.Location{
|
||||||
|
Line: line,
|
||||||
|
Character: end,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type HostsParser struct {
|
||||||
|
Tree HostsTree
|
||||||
|
CommentLines map[uint32]struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type HostsTree struct {
|
||||||
|
// [line]entry
|
||||||
|
Entries map[uint32]*HostsEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
type HostsEntry struct {
|
||||||
|
Location common.LocationRange
|
||||||
|
|
||||||
|
IPAddress *HostsIPAddress
|
||||||
|
Hostname *HostsHostname
|
||||||
|
Aliases []*HostsHostname
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p HostsEntry) String() string {
|
||||||
|
str := fmt.Sprintf("HostsEntry(%v)", p.Location)
|
||||||
|
|
||||||
|
if p.IPAddress != nil {
|
||||||
|
str += " " + p.IPAddress.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Hostname != nil {
|
||||||
|
str += " " + p.Hostname.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Aliases != nil {
|
||||||
|
str += " " + fmt.Sprintf("%v", p.Aliases)
|
||||||
|
}
|
||||||
|
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
type HostsIPAddress struct {
|
||||||
|
Location common.LocationRange
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
|
||||||
|
type HostsHostname struct {
|
||||||
|
Location common.LocationRange
|
||||||
|
Value string
|
||||||
|
}
|
129
handlers/hosts/tree/listener.go
Normal file
129
handlers/hosts/tree/listener.go
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
package tree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"config-lsp/common"
|
||||||
|
"config-lsp/handlers/hosts/parser"
|
||||||
|
|
||||||
|
"github.com/antlr4-go/antlr/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
type hostsListenerContext struct {
|
||||||
|
line uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type hostsParserListener struct {
|
||||||
|
*parser.BaseHostsListener
|
||||||
|
Parser *HostsParser
|
||||||
|
hostsContext hostsListenerContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *hostsParserListener) EnterComment(ctx *parser.CommentContext) {
|
||||||
|
line := uint32(s.hostsContext.line)
|
||||||
|
s.Parser.CommentLines[line] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *hostsParserListener) EnterEntry(ctx *parser.EntryContext) {
|
||||||
|
location := characterRangeFromCtx(ctx.BaseParserRuleContext)
|
||||||
|
location.ChangeBothLines(s.hostsContext.line)
|
||||||
|
|
||||||
|
s.Parser.Tree.Entries[location.Start.Line] = &HostsEntry{
|
||||||
|
Location: location,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *hostsParserListener) EnterIpAddress(ctx *parser.IpAddressContext) {
|
||||||
|
location := characterRangeFromCtx(ctx.BaseParserRuleContext)
|
||||||
|
location.ChangeBothLines(s.hostsContext.line)
|
||||||
|
|
||||||
|
entry := s.Parser.Tree.Entries[location.Start.Line]
|
||||||
|
|
||||||
|
entry.IPAddress = &HostsIPAddress{
|
||||||
|
Location: location,
|
||||||
|
Value: ctx.GetText(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *hostsParserListener) EnterHostname(ctx *parser.HostnameContext) {
|
||||||
|
location := characterRangeFromCtx(ctx.BaseParserRuleContext)
|
||||||
|
location.ChangeBothLines(s.hostsContext.line)
|
||||||
|
|
||||||
|
entry := s.Parser.Tree.Entries[location.Start.Line]
|
||||||
|
|
||||||
|
entry.Hostname = &HostsHostname{
|
||||||
|
Location: location,
|
||||||
|
Value: ctx.GetText(),
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Parser.Tree.Entries[location.Start.Line] = entry
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *hostsParserListener) EnterAliases(ctx *parser.AliasesContext) {
|
||||||
|
location := characterRangeFromCtx(ctx.BaseParserRuleContext)
|
||||||
|
location.ChangeBothLines(s.hostsContext.line)
|
||||||
|
|
||||||
|
entry := s.Parser.Tree.Entries[location.Start.Line]
|
||||||
|
|
||||||
|
aliases := make([]*HostsHostname, 0)
|
||||||
|
|
||||||
|
entry.Aliases = aliases
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *hostsParserListener) EnterAlias(ctx *parser.AliasContext) {
|
||||||
|
location := characterRangeFromCtx(ctx.BaseParserRuleContext)
|
||||||
|
location.ChangeBothLines(s.hostsContext.line)
|
||||||
|
|
||||||
|
entry := s.Parser.Tree.Entries[location.Start.Line]
|
||||||
|
|
||||||
|
alias := HostsHostname{
|
||||||
|
Location: location,
|
||||||
|
Value: ctx.GetText(),
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.Aliases = append(entry.Aliases, &alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createHostsFileListener(
|
||||||
|
parser *HostsParser,
|
||||||
|
line uint32,
|
||||||
|
) hostsParserListener {
|
||||||
|
return hostsParserListener{
|
||||||
|
Parser: parser,
|
||||||
|
hostsContext: hostsListenerContext{
|
||||||
|
line: line,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorListener struct {
|
||||||
|
*antlr.DefaultErrorListener
|
||||||
|
Errors []common.LSPError
|
||||||
|
hostsContext hostsListenerContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func createErrorListener(
|
||||||
|
line uint32,
|
||||||
|
) errorListener {
|
||||||
|
return errorListener{
|
||||||
|
Errors: make([]common.LSPError, 0),
|
||||||
|
hostsContext: hostsListenerContext{
|
||||||
|
line: line,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *errorListener) SyntaxError(
|
||||||
|
recognizer antlr.Recognizer,
|
||||||
|
offendingSymbol interface{},
|
||||||
|
_ int,
|
||||||
|
character int,
|
||||||
|
message string,
|
||||||
|
error antlr.RecognitionException,
|
||||||
|
) {
|
||||||
|
line := d.hostsContext.line
|
||||||
|
d.Errors = append(d.Errors, common.LSPError{
|
||||||
|
Range: common.CreateSingleCharRange(uint32(line), uint32(character)),
|
||||||
|
Err: common.SyntaxError{
|
||||||
|
Message: message,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
@ -1,9 +1,7 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
import "strings"
|
|
||||||
|
|
||||||
func Dedent(s string) string {
|
func Dedent(s string) string {
|
||||||
return strings.TrimLeft(s, "\n")
|
return s[len("\n"):]
|
||||||
}
|
}
|
||||||
|
|
||||||
func KeyExists[T comparable, V any](keys map[T]V, key T) bool {
|
func KeyExists[T comparable, V any](keys map[T]V, key T) bool {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user