mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-18 23:15:26 +02:00
fix(fstab): Improvements; Use antlr parser now
This commit is contained in:
parent
5a13487db8
commit
3ca0ea8c35
76
server/handlers/fstab/Fstab.g4
Normal file
76
server/handlers/fstab/Fstab.g4
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
grammar Fstab;
|
||||||
|
|
||||||
|
entry
|
||||||
|
:
|
||||||
|
WHITESPACE? spec?
|
||||||
|
WHITESPACE? mountPoint?
|
||||||
|
WHITESPACE? fileSystem?
|
||||||
|
WHITESPACE? mountOptions?
|
||||||
|
WHITESPACE? freq?
|
||||||
|
WHITESPACE? pass? WHITESPACE?
|
||||||
|
EOF
|
||||||
|
;
|
||||||
|
|
||||||
|
spec
|
||||||
|
: QUOTED_STRING | STRING
|
||||||
|
;
|
||||||
|
|
||||||
|
mountPoint
|
||||||
|
: QUOTED_STRING | STRING
|
||||||
|
;
|
||||||
|
|
||||||
|
fileSystem
|
||||||
|
: ADFS | AFFS | BTRFS | EXFAT
|
||||||
|
// Still match unknown file systems
|
||||||
|
| STRING | QUOTED_STRING
|
||||||
|
;
|
||||||
|
|
||||||
|
mountOptions
|
||||||
|
: QUOTED_STRING | STRING
|
||||||
|
;
|
||||||
|
|
||||||
|
freq
|
||||||
|
: DIGITS
|
||||||
|
;
|
||||||
|
|
||||||
|
pass
|
||||||
|
: DIGITS
|
||||||
|
;
|
||||||
|
|
||||||
|
DIGITS
|
||||||
|
: [0-9]+
|
||||||
|
;
|
||||||
|
|
||||||
|
WHITESPACE
|
||||||
|
: [ \t]+
|
||||||
|
;
|
||||||
|
|
||||||
|
HASH
|
||||||
|
: '#'
|
||||||
|
;
|
||||||
|
|
||||||
|
STRING
|
||||||
|
: ~(' ' | '\t' | '#')+
|
||||||
|
;
|
||||||
|
|
||||||
|
QUOTED_STRING
|
||||||
|
: '"' WHITESPACE? (STRING WHITESPACE)* STRING? ('"')?
|
||||||
|
;
|
||||||
|
|
||||||
|
// ///// Supported file systems /////
|
||||||
|
|
||||||
|
ADFS
|
||||||
|
: ('A' | 'a') ('D' | 'd') ('F' | 'f') ('S' | 's')
|
||||||
|
;
|
||||||
|
|
||||||
|
AFFS
|
||||||
|
: ('A' | 'a') ('F' | 'f') ('F' | 'f') ('S' | 's')
|
||||||
|
;
|
||||||
|
|
||||||
|
BTRFS
|
||||||
|
: ('B' | 'b') ('T' | 't') ('R' | 'r') ('F' | 'f') ('S' | 's')
|
||||||
|
;
|
||||||
|
|
||||||
|
EXFAT
|
||||||
|
: ('E' | 'e') ('X' | 'x') ('F' | 'f') ('A' | 'a') ('T' | 't')
|
||||||
|
;
|
45
server/handlers/fstab/ast/error-listener.go
Normal file
45
server/handlers/fstab/ast/error-listener.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package ast
|
||||||
|
|
||||||
|
import (
|
||||||
|
"config-lsp/common"
|
||||||
|
|
||||||
|
"github.com/antlr4-go/antlr/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
type errorListenerContext struct {
|
||||||
|
line uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorListener struct {
|
||||||
|
*antlr.DefaultErrorListener
|
||||||
|
Errors []common.LSPError
|
||||||
|
context errorListenerContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *errorListener) SyntaxError(
|
||||||
|
recognizer antlr.Recognizer,
|
||||||
|
offendingSymbol interface{},
|
||||||
|
_ int,
|
||||||
|
character int,
|
||||||
|
message string,
|
||||||
|
error antlr.RecognitionException,
|
||||||
|
) {
|
||||||
|
line := d.context.line
|
||||||
|
d.Errors = append(d.Errors, common.LSPError{
|
||||||
|
Range: common.CreateSingleCharRange(uint32(line), uint32(character)),
|
||||||
|
Err: common.SyntaxError{
|
||||||
|
Message: message,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func createErrorListener(
|
||||||
|
line uint32,
|
||||||
|
) errorListener {
|
||||||
|
return errorListener{
|
||||||
|
Errors: make([]common.LSPError, 0),
|
||||||
|
context: errorListenerContext{
|
||||||
|
line: line,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -33,7 +33,7 @@ type FstabFields struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type FstabEntry struct {
|
type FstabEntry struct {
|
||||||
Fields FstabFields
|
Fields *FstabFields
|
||||||
}
|
}
|
||||||
|
|
||||||
type FstabConfig struct {
|
type FstabConfig struct {
|
||||||
|
@ -17,30 +17,118 @@ import (
|
|||||||
// return entry.(*FstabEntry)
|
// return entry.(*FstabEntry)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// LABEL=test ext4 defaults 0 0
|
||||||
func (e FstabEntry) GetFieldAtPosition(position common.Position) FstabFieldName {
|
func (e FstabEntry) GetFieldAtPosition(position common.Position) FstabFieldName {
|
||||||
if e.Fields.Spec == nil || (e.Fields.Spec.ContainsPosition(position)) {
|
// No fields defined, empty line
|
||||||
|
if e.Fields.Spec == nil && e.Fields.MountPoint == nil && e.Fields.FilesystemType == nil && e.Fields.Options == nil && e.Fields.Freq == nil && e.Fields.Pass == nil {
|
||||||
return FstabFieldSpec
|
return FstabFieldSpec
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Fields.MountPoint == nil || (e.Fields.MountPoint.ContainsPosition(position)) {
|
// First, try if out of the existing fields the user wants to edit one of them
|
||||||
|
|
||||||
|
if e.Fields.Spec != nil && e.Fields.Spec.ContainsPosition(position) {
|
||||||
|
return FstabFieldSpec
|
||||||
|
}
|
||||||
|
if e.Fields.MountPoint != nil && e.Fields.MountPoint.ContainsPosition(position) {
|
||||||
|
return FstabFieldMountPoint
|
||||||
|
}
|
||||||
|
if e.Fields.FilesystemType != nil && e.Fields.FilesystemType.ContainsPosition(position) {
|
||||||
|
return FstabFieldFileSystemType
|
||||||
|
}
|
||||||
|
if e.Fields.Options != nil && e.Fields.Options.ContainsPosition(position) {
|
||||||
|
return FstabFieldOptions
|
||||||
|
}
|
||||||
|
if e.Fields.Freq != nil && e.Fields.Freq.ContainsPosition(position) {
|
||||||
|
return FstabFieldFreq
|
||||||
|
}
|
||||||
|
if e.Fields.Pass != nil && e.Fields.Pass.ContainsPosition(position) {
|
||||||
|
return FstabFieldPass
|
||||||
|
}
|
||||||
|
|
||||||
|
// Okay let's try to fetch the field by assuming the user is typing from left to right normally
|
||||||
|
|
||||||
|
if e.Fields.Spec != nil && e.Fields.Spec.IsPositionAfterEnd(position) && (e.Fields.MountPoint == nil || e.Fields.MountPoint.IsPositionBeforeEnd(position)) {
|
||||||
return FstabFieldMountPoint
|
return FstabFieldMountPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Fields.FilesystemType == nil || (e.Fields.FilesystemType.ContainsPosition(position)) {
|
if e.Fields.MountPoint != nil && e.Fields.MountPoint.IsPositionAfterEnd(position) && (e.Fields.FilesystemType == nil || e.Fields.FilesystemType.IsPositionBeforeEnd(position)) {
|
||||||
return FstabFieldFileSystemType
|
return FstabFieldFileSystemType
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Fields.Options == nil || (e.Fields.Options.ContainsPosition(position)) {
|
if e.Fields.FilesystemType != nil && e.Fields.FilesystemType.IsPositionAfterEnd(position) && (e.Fields.Options == nil || e.Fields.Options.IsPositionBeforeEnd(position)) {
|
||||||
return FstabFieldOptions
|
return FstabFieldOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Fields.Freq == nil || (e.Fields.Freq.ContainsPosition(position)) {
|
if e.Fields.Options != nil && e.Fields.Options.IsPositionAfterEnd(position) && (e.Fields.Freq == nil || e.Fields.Freq.IsPositionBeforeEnd(position)) {
|
||||||
|
return FstabFieldFreq
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.Fields.Freq != nil && e.Fields.Freq.IsPositionAfterEnd(position) && (e.Fields.Pass == nil || e.Fields.Pass.IsPositionBeforeEnd(position)) {
|
||||||
|
return FstabFieldPass
|
||||||
|
}
|
||||||
|
|
||||||
|
// Okay shit no idea, let's just give whatever is missing
|
||||||
|
|
||||||
|
if e.Fields.Spec == nil {
|
||||||
|
return FstabFieldSpec
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.Fields.MountPoint == nil {
|
||||||
|
return FstabFieldMountPoint
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.Fields.FilesystemType == nil {
|
||||||
|
return FstabFieldFileSystemType
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.Fields.Options == nil {
|
||||||
|
return FstabFieldOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.Fields.Freq == nil {
|
||||||
return FstabFieldFreq
|
return FstabFieldFreq
|
||||||
}
|
}
|
||||||
|
|
||||||
return FstabFieldPass
|
return FstabFieldPass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LABEL=test /mnt/test btrfs subvol=backup,fat=32 [0] [0]
|
||||||
|
func (e FstabEntry) getCursorIndex() uint8 {
|
||||||
|
definedAmount := e.getDefinedFieldsAmount()
|
||||||
|
|
||||||
|
switch definedAmount {
|
||||||
|
case 5:
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e FstabEntry) getDefinedFieldsAmount() uint8 {
|
||||||
|
var definedAmount uint8 = 0
|
||||||
|
|
||||||
|
if e.Fields.Spec != nil {
|
||||||
|
definedAmount++
|
||||||
|
}
|
||||||
|
if e.Fields.MountPoint != nil {
|
||||||
|
definedAmount++
|
||||||
|
}
|
||||||
|
if e.Fields.FilesystemType != nil {
|
||||||
|
definedAmount++
|
||||||
|
}
|
||||||
|
if e.Fields.Options != nil {
|
||||||
|
definedAmount++
|
||||||
|
}
|
||||||
|
if e.Fields.Freq != nil {
|
||||||
|
definedAmount++
|
||||||
|
}
|
||||||
|
if e.Fields.Pass != nil {
|
||||||
|
definedAmount++
|
||||||
|
}
|
||||||
|
|
||||||
|
return definedAmount
|
||||||
|
}
|
||||||
|
|
||||||
// Create a mount options field for the entry
|
// Create a mount options field for the entry
|
||||||
func (e FstabEntry) FetchMountOptionsField(includeDefaults bool) docvalues.DeprecatedValue {
|
func (e FstabEntry) FetchMountOptionsField(includeDefaults bool) docvalues.DeprecatedValue {
|
||||||
if e.Fields.FilesystemType == nil {
|
if e.Fields.FilesystemType == nil {
|
||||||
|
135
server/handlers/fstab/ast/listener.go
Normal file
135
server/handlers/fstab/ast/listener.go
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
package ast
|
||||||
|
|
||||||
|
import (
|
||||||
|
"config-lsp/common"
|
||||||
|
"config-lsp/handlers/fstab/ast/parser"
|
||||||
|
|
||||||
|
commonparser "config-lsp/common/parser"
|
||||||
|
)
|
||||||
|
|
||||||
|
type fstabListenerContext struct {
|
||||||
|
line uint32
|
||||||
|
currentEntry *FstabEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
func createListenerContext() *fstabListenerContext {
|
||||||
|
context := new(fstabListenerContext)
|
||||||
|
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
type fstabParserListener struct {
|
||||||
|
*parser.BaseFstabListener
|
||||||
|
Config *FstabConfig
|
||||||
|
Errors []common.LSPError
|
||||||
|
fstabContext *fstabListenerContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func createListener(
|
||||||
|
config *FstabConfig,
|
||||||
|
context *fstabListenerContext,
|
||||||
|
) fstabParserListener {
|
||||||
|
return fstabParserListener{
|
||||||
|
Config: config,
|
||||||
|
Errors: make([]common.LSPError, 0),
|
||||||
|
fstabContext: context,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fstabParserListener) EnterEntry(ctx *parser.EntryContext) {
|
||||||
|
location := common.CharacterRangeFromCtx(ctx.BaseParserRuleContext)
|
||||||
|
location.ChangeBothLines(s.fstabContext.line)
|
||||||
|
|
||||||
|
s.fstabContext.currentEntry = &FstabEntry{
|
||||||
|
Fields: &FstabFields{
|
||||||
|
LocationRange: location,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Config.Entries.Put(
|
||||||
|
s.fstabContext.line,
|
||||||
|
s.fstabContext.currentEntry,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fstabParserListener) ExitEntry(ctx *parser.EntryContext) {
|
||||||
|
s.fstabContext.currentEntry = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fstabParserListener) EnterSpec(ctx *parser.SpecContext) {
|
||||||
|
location := common.CharacterRangeFromCtx(ctx.BaseParserRuleContext)
|
||||||
|
location.ChangeBothLines(s.fstabContext.line)
|
||||||
|
|
||||||
|
text := ctx.GetText()
|
||||||
|
value := commonparser.ParseRawString(text, commonparser.FullFeatures)
|
||||||
|
|
||||||
|
s.fstabContext.currentEntry.Fields.Spec = &FstabField{
|
||||||
|
Value: value,
|
||||||
|
LocationRange: location,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fstabParserListener) EnterMountPoint(ctx *parser.MountPointContext) {
|
||||||
|
location := common.CharacterRangeFromCtx(ctx.BaseParserRuleContext)
|
||||||
|
location.ChangeBothLines(s.fstabContext.line)
|
||||||
|
|
||||||
|
text := ctx.GetText()
|
||||||
|
value := commonparser.ParseRawString(text, commonparser.FullFeatures)
|
||||||
|
|
||||||
|
s.fstabContext.currentEntry.Fields.MountPoint = &FstabField{
|
||||||
|
LocationRange: location,
|
||||||
|
Value: value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fstabParserListener) EnterFileSystem(ctx *parser.FileSystemContext) {
|
||||||
|
location := common.CharacterRangeFromCtx(ctx.BaseParserRuleContext)
|
||||||
|
location.ChangeBothLines(s.fstabContext.line)
|
||||||
|
|
||||||
|
text := ctx.GetText()
|
||||||
|
value := commonparser.ParseRawString(text, commonparser.FullFeatures)
|
||||||
|
|
||||||
|
s.fstabContext.currentEntry.Fields.FilesystemType = &FstabField{
|
||||||
|
LocationRange: location,
|
||||||
|
Value: value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fstabParserListener) EnterMountOptions(ctx *parser.MountOptionsContext) {
|
||||||
|
location := common.CharacterRangeFromCtx(ctx.BaseParserRuleContext)
|
||||||
|
location.ChangeBothLines(s.fstabContext.line)
|
||||||
|
|
||||||
|
text := ctx.GetText()
|
||||||
|
value := commonparser.ParseRawString(text, commonparser.FullFeatures)
|
||||||
|
|
||||||
|
s.fstabContext.currentEntry.Fields.Options = &FstabField{
|
||||||
|
LocationRange: location,
|
||||||
|
Value: value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fstabParserListener) EnterFreq(ctx *parser.FreqContext) {
|
||||||
|
location := common.CharacterRangeFromCtx(ctx.BaseParserRuleContext)
|
||||||
|
location.ChangeBothLines(s.fstabContext.line)
|
||||||
|
|
||||||
|
text := ctx.GetText()
|
||||||
|
value := commonparser.ParseRawString(text, commonparser.FullFeatures)
|
||||||
|
|
||||||
|
s.fstabContext.currentEntry.Fields.Freq = &FstabField{
|
||||||
|
LocationRange: location,
|
||||||
|
Value: value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fstabParserListener) EnterPass(ctx *parser.PassContext) {
|
||||||
|
location := common.CharacterRangeFromCtx(ctx.BaseParserRuleContext)
|
||||||
|
location.ChangeBothLines(s.fstabContext.line)
|
||||||
|
|
||||||
|
text := ctx.GetText()
|
||||||
|
value := commonparser.ParseRawString(text, commonparser.FullFeatures)
|
||||||
|
|
||||||
|
s.fstabContext.currentEntry.Fields.Pass = &FstabField{
|
||||||
|
LocationRange: location,
|
||||||
|
Value: value,
|
||||||
|
}
|
||||||
|
}
|
@ -3,9 +3,11 @@ package ast
|
|||||||
import (
|
import (
|
||||||
"config-lsp/common"
|
"config-lsp/common"
|
||||||
commonparser "config-lsp/common/parser"
|
commonparser "config-lsp/common/parser"
|
||||||
|
"config-lsp/handlers/fstab/ast/parser"
|
||||||
"config-lsp/utils"
|
"config-lsp/utils"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/antlr4-go/antlr/v4"
|
||||||
"github.com/emirpasic/gods/maps/treemap"
|
"github.com/emirpasic/gods/maps/treemap"
|
||||||
|
|
||||||
gods "github.com/emirpasic/gods/utils"
|
gods "github.com/emirpasic/gods/utils"
|
||||||
@ -25,14 +27,15 @@ func (c *FstabConfig) Clear() {
|
|||||||
|
|
||||||
var commentPattern = regexp.MustCompile(`^\s*#`)
|
var commentPattern = regexp.MustCompile(`^\s*#`)
|
||||||
var emptyPattern = regexp.MustCompile(`^\s*$`)
|
var emptyPattern = regexp.MustCompile(`^\s*$`)
|
||||||
var whitespacePattern = regexp.MustCompile(`\S+`)
|
|
||||||
|
|
||||||
func (c *FstabConfig) Parse(input string) []common.LSPError {
|
func (c *FstabConfig) Parse(input string) []common.LSPError {
|
||||||
errors := make([]common.LSPError, 0)
|
errors := make([]common.LSPError, 0)
|
||||||
lines := utils.SplitIntoLines(input)
|
lines := utils.SplitIntoLines(input)
|
||||||
|
context := createListenerContext()
|
||||||
|
|
||||||
for rawLineNumber, line := range lines {
|
for rawLineNumber, line := range lines {
|
||||||
lineNumber := uint32(rawLineNumber)
|
lineNumber := uint32(rawLineNumber)
|
||||||
|
context.line = lineNumber
|
||||||
|
|
||||||
if emptyPattern.MatchString(line) {
|
if emptyPattern.MatchString(line) {
|
||||||
continue
|
continue
|
||||||
@ -45,89 +48,121 @@ func (c *FstabConfig) Parse(input string) []common.LSPError {
|
|||||||
|
|
||||||
errors = append(
|
errors = append(
|
||||||
errors,
|
errors,
|
||||||
c.parseStatement(lineNumber, line)...,
|
c.parseStatement(context, line)...,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Handle leading comments
|
||||||
func (c *FstabConfig) parseStatement(
|
func (c *FstabConfig) parseStatement(
|
||||||
line uint32,
|
context *fstabListenerContext,
|
||||||
input string,
|
input string,
|
||||||
) []common.LSPError {
|
) []common.LSPError {
|
||||||
fields := whitespacePattern.FindAllStringIndex(input, -1)
|
stream := antlr.NewInputStream(input)
|
||||||
|
|
||||||
if len(fields) == 0 {
|
lexerErrorListener := createErrorListener(context.line)
|
||||||
return []common.LSPError{
|
lexer := parser.NewFstabLexer(stream)
|
||||||
{
|
lexer.RemoveErrorListeners()
|
||||||
Range: common.LocationRange{
|
lexer.AddErrorListener(&lexerErrorListener)
|
||||||
Start: common.Location{
|
|
||||||
Line: line,
|
|
||||||
Character: 0,
|
|
||||||
},
|
|
||||||
End: common.Location{
|
|
||||||
Line: line,
|
|
||||||
Character: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var spec *FstabField
|
tokenStream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
|
||||||
var mountPoint *FstabField
|
|
||||||
var filesystemType *FstabField
|
|
||||||
var options *FstabField
|
|
||||||
var freq *FstabField
|
|
||||||
var pass *FstabField
|
|
||||||
|
|
||||||
switch len(fields) {
|
parserErrorListener := createErrorListener(context.line)
|
||||||
case 6:
|
antlrParser := parser.NewFstabParser(tokenStream)
|
||||||
pass = parseField(line, input, fields[5])
|
antlrParser.RemoveErrorListeners()
|
||||||
fallthrough
|
antlrParser.AddErrorListener(&parserErrorListener)
|
||||||
case 5:
|
|
||||||
freq = parseField(line, input, fields[4])
|
|
||||||
fallthrough
|
|
||||||
case 4:
|
|
||||||
options = parseField(line, input, fields[3])
|
|
||||||
fallthrough
|
|
||||||
case 3:
|
|
||||||
filesystemType = parseField(line, input, fields[2])
|
|
||||||
fallthrough
|
|
||||||
case 2:
|
|
||||||
mountPoint = parseField(line, input, fields[1])
|
|
||||||
fallthrough
|
|
||||||
case 1:
|
|
||||||
spec = parseField(line, input, fields[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
fstabLine := &FstabEntry{
|
listener := createListener(c, context)
|
||||||
Fields: FstabFields{
|
antlr.ParseTreeWalkerDefault.Walk(
|
||||||
LocationRange: common.LocationRange{
|
&listener,
|
||||||
Start: common.Location{
|
antlrParser.Entry(),
|
||||||
Line: line,
|
)
|
||||||
Character: 0,
|
|
||||||
},
|
|
||||||
End: common.Location{
|
|
||||||
Line: line,
|
|
||||||
Character: uint32(len(input)),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Spec: spec,
|
|
||||||
MountPoint: mountPoint,
|
|
||||||
FilesystemType: filesystemType,
|
|
||||||
Options: options,
|
|
||||||
Freq: freq,
|
|
||||||
Pass: pass,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Entries.Put(line, fstabLine)
|
errors := lexerErrorListener.Errors
|
||||||
|
errors = append(errors, parserErrorListener.Errors...)
|
||||||
|
errors = append(errors, listener.Errors...)
|
||||||
|
|
||||||
return nil
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func (c *FstabConfig) parseStatement(
|
||||||
|
// line uint32,
|
||||||
|
// input string,
|
||||||
|
// ) []common.LSPError {
|
||||||
|
// fields := whitespacePattern.FindAllStringIndex(input, -1)
|
||||||
|
//
|
||||||
|
// if len(fields) == 0 {
|
||||||
|
// return []common.LSPError{
|
||||||
|
// {
|
||||||
|
// Range: common.LocationRange{
|
||||||
|
// Start: common.Location{
|
||||||
|
// Line: line,
|
||||||
|
// Character: 0,
|
||||||
|
// },
|
||||||
|
// End: common.Location{
|
||||||
|
// Line: line,
|
||||||
|
// Character: 0,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var spec *FstabField
|
||||||
|
// var mountPoint *FstabField
|
||||||
|
// var filesystemType *FstabField
|
||||||
|
// var options *FstabField
|
||||||
|
// var freq *FstabField
|
||||||
|
// var pass *FstabField
|
||||||
|
//
|
||||||
|
// switch len(fields) {
|
||||||
|
// case 6:
|
||||||
|
// pass = parseField(line, input, fields[5])
|
||||||
|
// fallthrough
|
||||||
|
// case 5:
|
||||||
|
// freq = parseField(line, input, fields[4])
|
||||||
|
// fallthrough
|
||||||
|
// case 4:
|
||||||
|
// options = parseField(line, input, fields[3])
|
||||||
|
// fallthrough
|
||||||
|
// case 3:
|
||||||
|
// filesystemType = parseField(line, input, fields[2])
|
||||||
|
// fallthrough
|
||||||
|
// case 2:
|
||||||
|
// mountPoint = parseField(line, input, fields[1])
|
||||||
|
// fallthrough
|
||||||
|
// case 1:
|
||||||
|
// spec = parseField(line, input, fields[0])
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fstabLine := &FstabEntry{
|
||||||
|
// Fields: FstabFields{
|
||||||
|
// LocationRange: common.LocationRange{
|
||||||
|
// Start: common.Location{
|
||||||
|
// Line: line,
|
||||||
|
// Character: 0,
|
||||||
|
// },
|
||||||
|
// End: common.Location{
|
||||||
|
// Line: line,
|
||||||
|
// Character: uint32(len(input)),
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// Spec: spec,
|
||||||
|
// MountPoint: mountPoint,
|
||||||
|
// FilesystemType: filesystemType,
|
||||||
|
// Options: options,
|
||||||
|
// Freq: freq,
|
||||||
|
// Pass: pass,
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// c.Entries.Put(line, fstabLine)
|
||||||
|
//
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
func parseField(
|
func parseField(
|
||||||
line uint32,
|
line uint32,
|
||||||
input string,
|
input string,
|
||||||
|
36
server/handlers/fstab/ast/parser/Fstab.interp
Normal file
36
server/handlers/fstab/ast/parser/Fstab.interp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
token literal names:
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
'#'
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
|
||||||
|
token symbolic names:
|
||||||
|
null
|
||||||
|
DIGITS
|
||||||
|
WHITESPACE
|
||||||
|
HASH
|
||||||
|
STRING
|
||||||
|
QUOTED_STRING
|
||||||
|
ADFS
|
||||||
|
AFFS
|
||||||
|
BTRFS
|
||||||
|
EXFAT
|
||||||
|
|
||||||
|
rule names:
|
||||||
|
entry
|
||||||
|
spec
|
||||||
|
mountPoint
|
||||||
|
fileSystem
|
||||||
|
mountOptions
|
||||||
|
freq
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
atn:
|
||||||
|
[4, 1, 9, 68, 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, 3, 0, 16, 8, 0, 1, 0, 3, 0, 19, 8, 0, 1, 0, 3, 0, 22, 8, 0, 1, 0, 3, 0, 25, 8, 0, 1, 0, 3, 0, 28, 8, 0, 1, 0, 3, 0, 31, 8, 0, 1, 0, 3, 0, 34, 8, 0, 1, 0, 3, 0, 37, 8, 0, 1, 0, 3, 0, 40, 8, 0, 1, 0, 3, 0, 43, 8, 0, 1, 0, 3, 0, 46, 8, 0, 1, 0, 3, 0, 49, 8, 0, 1, 0, 3, 0, 52, 8, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 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, 2, 1, 0, 4, 5, 1, 0, 4, 9, 73, 0, 15, 1, 0, 0, 0, 2, 55, 1, 0, 0, 0, 4, 57, 1, 0, 0, 0, 6, 59, 1, 0, 0, 0, 8, 61, 1, 0, 0, 0, 10, 63, 1, 0, 0, 0, 12, 65, 1, 0, 0, 0, 14, 16, 5, 2, 0, 0, 15, 14, 1, 0, 0, 0, 15, 16, 1, 0, 0, 0, 16, 18, 1, 0, 0, 0, 17, 19, 3, 2, 1, 0, 18, 17, 1, 0, 0, 0, 18, 19, 1, 0, 0, 0, 19, 21, 1, 0, 0, 0, 20, 22, 5, 2, 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, 27, 1, 0, 0, 0, 26, 28, 5, 2, 0, 0, 27, 26, 1, 0, 0, 0, 27, 28, 1, 0, 0, 0, 28, 30, 1, 0, 0, 0, 29, 31, 3, 6, 3, 0, 30, 29, 1, 0, 0, 0, 30, 31, 1, 0, 0, 0, 31, 33, 1, 0, 0, 0, 32, 34, 5, 2, 0, 0, 33, 32, 1, 0, 0, 0, 33, 34, 1, 0, 0, 0, 34, 36, 1, 0, 0, 0, 35, 37, 3, 8, 4, 0, 36, 35, 1, 0, 0, 0, 36, 37, 1, 0, 0, 0, 37, 39, 1, 0, 0, 0, 38, 40, 5, 2, 0, 0, 39, 38, 1, 0, 0, 0, 39, 40, 1, 0, 0, 0, 40, 42, 1, 0, 0, 0, 41, 43, 3, 10, 5, 0, 42, 41, 1, 0, 0, 0, 42, 43, 1, 0, 0, 0, 43, 45, 1, 0, 0, 0, 44, 46, 5, 2, 0, 0, 45, 44, 1, 0, 0, 0, 45, 46, 1, 0, 0, 0, 46, 48, 1, 0, 0, 0, 47, 49, 3, 12, 6, 0, 48, 47, 1, 0, 0, 0, 48, 49, 1, 0, 0, 0, 49, 51, 1, 0, 0, 0, 50, 52, 5, 2, 0, 0, 51, 50, 1, 0, 0, 0, 51, 52, 1, 0, 0, 0, 52, 53, 1, 0, 0, 0, 53, 54, 5, 0, 0, 1, 54, 1, 1, 0, 0, 0, 55, 56, 7, 0, 0, 0, 56, 3, 1, 0, 0, 0, 57, 58, 7, 0, 0, 0, 58, 5, 1, 0, 0, 0, 59, 60, 7, 1, 0, 0, 60, 7, 1, 0, 0, 0, 61, 62, 7, 0, 0, 0, 62, 9, 1, 0, 0, 0, 63, 64, 5, 1, 0, 0, 64, 11, 1, 0, 0, 0, 65, 66, 5, 1, 0, 0, 66, 13, 1, 0, 0, 0, 13, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51]
|
10
server/handlers/fstab/ast/parser/Fstab.tokens
Normal file
10
server/handlers/fstab/ast/parser/Fstab.tokens
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
DIGITS=1
|
||||||
|
WHITESPACE=2
|
||||||
|
HASH=3
|
||||||
|
STRING=4
|
||||||
|
QUOTED_STRING=5
|
||||||
|
ADFS=6
|
||||||
|
AFFS=7
|
||||||
|
BTRFS=8
|
||||||
|
EXFAT=9
|
||||||
|
'#'=3
|
44
server/handlers/fstab/ast/parser/FstabLexer.interp
Normal file
44
server/handlers/fstab/ast/parser/FstabLexer.interp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
token literal names:
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
'#'
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
null
|
||||||
|
|
||||||
|
token symbolic names:
|
||||||
|
null
|
||||||
|
DIGITS
|
||||||
|
WHITESPACE
|
||||||
|
HASH
|
||||||
|
STRING
|
||||||
|
QUOTED_STRING
|
||||||
|
ADFS
|
||||||
|
AFFS
|
||||||
|
BTRFS
|
||||||
|
EXFAT
|
||||||
|
|
||||||
|
rule names:
|
||||||
|
DIGITS
|
||||||
|
WHITESPACE
|
||||||
|
HASH
|
||||||
|
STRING
|
||||||
|
QUOTED_STRING
|
||||||
|
ADFS
|
||||||
|
AFFS
|
||||||
|
BTRFS
|
||||||
|
EXFAT
|
||||||
|
|
||||||
|
channel names:
|
||||||
|
DEFAULT_TOKEN_CHANNEL
|
||||||
|
HIDDEN
|
||||||
|
|
||||||
|
mode names:
|
||||||
|
DEFAULT_MODE
|
||||||
|
|
||||||
|
atn:
|
||||||
|
[4, 0, 9, 76, 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, 1, 0, 4, 0, 21, 8, 0, 11, 0, 12, 0, 22, 1, 1, 4, 1, 26, 8, 1, 11, 1, 12, 1, 27, 1, 2, 1, 2, 1, 3, 4, 3, 33, 8, 3, 11, 3, 12, 3, 34, 1, 4, 1, 4, 3, 4, 39, 8, 4, 1, 4, 1, 4, 1, 4, 5, 4, 44, 8, 4, 10, 4, 12, 4, 47, 9, 4, 1, 4, 3, 4, 50, 8, 4, 1, 4, 3, 4, 53, 8, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 0, 0, 9, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 1, 0, 12, 1, 0, 48, 57, 2, 0, 9, 9, 32, 32, 3, 0, 9, 9, 32, 32, 35, 35, 2, 0, 65, 65, 97, 97, 2, 0, 68, 68, 100, 100, 2, 0, 70, 70, 102, 102, 2, 0, 83, 83, 115, 115, 2, 0, 66, 66, 98, 98, 2, 0, 84, 84, 116, 116, 2, 0, 82, 82, 114, 114, 2, 0, 69, 69, 101, 101, 2, 0, 88, 88, 120, 120, 82, 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, 17, 1, 0, 0, 0, 1, 20, 1, 0, 0, 0, 3, 25, 1, 0, 0, 0, 5, 29, 1, 0, 0, 0, 7, 32, 1, 0, 0, 0, 9, 36, 1, 0, 0, 0, 11, 54, 1, 0, 0, 0, 13, 59, 1, 0, 0, 0, 15, 64, 1, 0, 0, 0, 17, 70, 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, 2, 1, 0, 0, 0, 24, 26, 7, 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, 4, 1, 0, 0, 0, 29, 30, 5, 35, 0, 0, 30, 6, 1, 0, 0, 0, 31, 33, 8, 2, 0, 0, 32, 31, 1, 0, 0, 0, 33, 34, 1, 0, 0, 0, 34, 32, 1, 0, 0, 0, 34, 35, 1, 0, 0, 0, 35, 8, 1, 0, 0, 0, 36, 38, 5, 34, 0, 0, 37, 39, 3, 3, 1, 0, 38, 37, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 45, 1, 0, 0, 0, 40, 41, 3, 7, 3, 0, 41, 42, 3, 3, 1, 0, 42, 44, 1, 0, 0, 0, 43, 40, 1, 0, 0, 0, 44, 47, 1, 0, 0, 0, 45, 43, 1, 0, 0, 0, 45, 46, 1, 0, 0, 0, 46, 49, 1, 0, 0, 0, 47, 45, 1, 0, 0, 0, 48, 50, 3, 7, 3, 0, 49, 48, 1, 0, 0, 0, 49, 50, 1, 0, 0, 0, 50, 52, 1, 0, 0, 0, 51, 53, 5, 34, 0, 0, 52, 51, 1, 0, 0, 0, 52, 53, 1, 0, 0, 0, 53, 10, 1, 0, 0, 0, 54, 55, 7, 3, 0, 0, 55, 56, 7, 4, 0, 0, 56, 57, 7, 5, 0, 0, 57, 58, 7, 6, 0, 0, 58, 12, 1, 0, 0, 0, 59, 60, 7, 3, 0, 0, 60, 61, 7, 5, 0, 0, 61, 62, 7, 5, 0, 0, 62, 63, 7, 6, 0, 0, 63, 14, 1, 0, 0, 0, 64, 65, 7, 7, 0, 0, 65, 66, 7, 8, 0, 0, 66, 67, 7, 9, 0, 0, 67, 68, 7, 5, 0, 0, 68, 69, 7, 6, 0, 0, 69, 16, 1, 0, 0, 0, 70, 71, 7, 10, 0, 0, 71, 72, 7, 11, 0, 0, 72, 73, 7, 5, 0, 0, 73, 74, 7, 3, 0, 0, 74, 75, 7, 8, 0, 0, 75, 18, 1, 0, 0, 0, 8, 0, 22, 27, 34, 38, 45, 49, 52, 0]
|
10
server/handlers/fstab/ast/parser/FstabLexer.tokens
Normal file
10
server/handlers/fstab/ast/parser/FstabLexer.tokens
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
DIGITS=1
|
||||||
|
WHITESPACE=2
|
||||||
|
HASH=3
|
||||||
|
STRING=4
|
||||||
|
QUOTED_STRING=5
|
||||||
|
ADFS=6
|
||||||
|
AFFS=7
|
||||||
|
BTRFS=8
|
||||||
|
EXFAT=9
|
||||||
|
'#'=3
|
64
server/handlers/fstab/ast/parser/fstab_base_listener.go
Normal file
64
server/handlers/fstab/ast/parser/fstab_base_listener.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Code generated from Fstab.g4 by ANTLR 4.13.0. DO NOT EDIT.
|
||||||
|
|
||||||
|
package parser // Fstab
|
||||||
|
|
||||||
|
import "github.com/antlr4-go/antlr/v4"
|
||||||
|
|
||||||
|
// BaseFstabListener is a complete listener for a parse tree produced by FstabParser.
|
||||||
|
type BaseFstabListener struct{}
|
||||||
|
|
||||||
|
var _ FstabListener = &BaseFstabListener{}
|
||||||
|
|
||||||
|
// VisitTerminal is called when a terminal node is visited.
|
||||||
|
func (s *BaseFstabListener) VisitTerminal(node antlr.TerminalNode) {}
|
||||||
|
|
||||||
|
// VisitErrorNode is called when an error node is visited.
|
||||||
|
func (s *BaseFstabListener) VisitErrorNode(node antlr.ErrorNode) {}
|
||||||
|
|
||||||
|
// EnterEveryRule is called when any rule is entered.
|
||||||
|
func (s *BaseFstabListener) EnterEveryRule(ctx antlr.ParserRuleContext) {}
|
||||||
|
|
||||||
|
// ExitEveryRule is called when any rule is exited.
|
||||||
|
func (s *BaseFstabListener) ExitEveryRule(ctx antlr.ParserRuleContext) {}
|
||||||
|
|
||||||
|
// EnterEntry is called when production entry is entered.
|
||||||
|
func (s *BaseFstabListener) EnterEntry(ctx *EntryContext) {}
|
||||||
|
|
||||||
|
// ExitEntry is called when production entry is exited.
|
||||||
|
func (s *BaseFstabListener) ExitEntry(ctx *EntryContext) {}
|
||||||
|
|
||||||
|
// EnterSpec is called when production spec is entered.
|
||||||
|
func (s *BaseFstabListener) EnterSpec(ctx *SpecContext) {}
|
||||||
|
|
||||||
|
// ExitSpec is called when production spec is exited.
|
||||||
|
func (s *BaseFstabListener) ExitSpec(ctx *SpecContext) {}
|
||||||
|
|
||||||
|
// EnterMountPoint is called when production mountPoint is entered.
|
||||||
|
func (s *BaseFstabListener) EnterMountPoint(ctx *MountPointContext) {}
|
||||||
|
|
||||||
|
// ExitMountPoint is called when production mountPoint is exited.
|
||||||
|
func (s *BaseFstabListener) ExitMountPoint(ctx *MountPointContext) {}
|
||||||
|
|
||||||
|
// EnterFileSystem is called when production fileSystem is entered.
|
||||||
|
func (s *BaseFstabListener) EnterFileSystem(ctx *FileSystemContext) {}
|
||||||
|
|
||||||
|
// ExitFileSystem is called when production fileSystem is exited.
|
||||||
|
func (s *BaseFstabListener) ExitFileSystem(ctx *FileSystemContext) {}
|
||||||
|
|
||||||
|
// EnterMountOptions is called when production mountOptions is entered.
|
||||||
|
func (s *BaseFstabListener) EnterMountOptions(ctx *MountOptionsContext) {}
|
||||||
|
|
||||||
|
// ExitMountOptions is called when production mountOptions is exited.
|
||||||
|
func (s *BaseFstabListener) ExitMountOptions(ctx *MountOptionsContext) {}
|
||||||
|
|
||||||
|
// EnterFreq is called when production freq is entered.
|
||||||
|
func (s *BaseFstabListener) EnterFreq(ctx *FreqContext) {}
|
||||||
|
|
||||||
|
// ExitFreq is called when production freq is exited.
|
||||||
|
func (s *BaseFstabListener) ExitFreq(ctx *FreqContext) {}
|
||||||
|
|
||||||
|
// EnterPass is called when production pass is entered.
|
||||||
|
func (s *BaseFstabListener) EnterPass(ctx *PassContext) {}
|
||||||
|
|
||||||
|
// ExitPass is called when production pass is exited.
|
||||||
|
func (s *BaseFstabListener) ExitPass(ctx *PassContext) {}
|
143
server/handlers/fstab/ast/parser/fstab_lexer.go
Normal file
143
server/handlers/fstab/ast/parser/fstab_lexer.go
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
// Code generated from Fstab.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 FstabLexer struct {
|
||||||
|
*antlr.BaseLexer
|
||||||
|
channelNames []string
|
||||||
|
modeNames []string
|
||||||
|
// TODO: EOF string
|
||||||
|
}
|
||||||
|
|
||||||
|
var FstabLexerLexerStaticData 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 fstablexerLexerInit() {
|
||||||
|
staticData := &FstabLexerLexerStaticData
|
||||||
|
staticData.ChannelNames = []string{
|
||||||
|
"DEFAULT_TOKEN_CHANNEL", "HIDDEN",
|
||||||
|
}
|
||||||
|
staticData.ModeNames = []string{
|
||||||
|
"DEFAULT_MODE",
|
||||||
|
}
|
||||||
|
staticData.LiteralNames = []string{
|
||||||
|
"", "", "", "'#'",
|
||||||
|
}
|
||||||
|
staticData.SymbolicNames = []string{
|
||||||
|
"", "DIGITS", "WHITESPACE", "HASH", "STRING", "QUOTED_STRING", "ADFS",
|
||||||
|
"AFFS", "BTRFS", "EXFAT",
|
||||||
|
}
|
||||||
|
staticData.RuleNames = []string{
|
||||||
|
"DIGITS", "WHITESPACE", "HASH", "STRING", "QUOTED_STRING", "ADFS", "AFFS",
|
||||||
|
"BTRFS", "EXFAT",
|
||||||
|
}
|
||||||
|
staticData.PredictionContextCache = antlr.NewPredictionContextCache()
|
||||||
|
staticData.serializedATN = []int32{
|
||||||
|
4, 0, 9, 76, 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, 1, 0, 4, 0, 21,
|
||||||
|
8, 0, 11, 0, 12, 0, 22, 1, 1, 4, 1, 26, 8, 1, 11, 1, 12, 1, 27, 1, 2, 1,
|
||||||
|
2, 1, 3, 4, 3, 33, 8, 3, 11, 3, 12, 3, 34, 1, 4, 1, 4, 3, 4, 39, 8, 4,
|
||||||
|
1, 4, 1, 4, 1, 4, 5, 4, 44, 8, 4, 10, 4, 12, 4, 47, 9, 4, 1, 4, 3, 4, 50,
|
||||||
|
8, 4, 1, 4, 3, 4, 53, 8, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1,
|
||||||
|
6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1,
|
||||||
|
8, 1, 8, 1, 8, 0, 0, 9, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15,
|
||||||
|
8, 17, 9, 1, 0, 12, 1, 0, 48, 57, 2, 0, 9, 9, 32, 32, 3, 0, 9, 9, 32, 32,
|
||||||
|
35, 35, 2, 0, 65, 65, 97, 97, 2, 0, 68, 68, 100, 100, 2, 0, 70, 70, 102,
|
||||||
|
102, 2, 0, 83, 83, 115, 115, 2, 0, 66, 66, 98, 98, 2, 0, 84, 84, 116, 116,
|
||||||
|
2, 0, 82, 82, 114, 114, 2, 0, 69, 69, 101, 101, 2, 0, 88, 88, 120, 120,
|
||||||
|
82, 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, 17, 1, 0, 0, 0, 1, 20, 1, 0, 0, 0, 3, 25, 1, 0, 0, 0, 5, 29, 1,
|
||||||
|
0, 0, 0, 7, 32, 1, 0, 0, 0, 9, 36, 1, 0, 0, 0, 11, 54, 1, 0, 0, 0, 13,
|
||||||
|
59, 1, 0, 0, 0, 15, 64, 1, 0, 0, 0, 17, 70, 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, 2, 1, 0, 0, 0, 24, 26, 7, 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, 4, 1, 0,
|
||||||
|
0, 0, 29, 30, 5, 35, 0, 0, 30, 6, 1, 0, 0, 0, 31, 33, 8, 2, 0, 0, 32, 31,
|
||||||
|
1, 0, 0, 0, 33, 34, 1, 0, 0, 0, 34, 32, 1, 0, 0, 0, 34, 35, 1, 0, 0, 0,
|
||||||
|
35, 8, 1, 0, 0, 0, 36, 38, 5, 34, 0, 0, 37, 39, 3, 3, 1, 0, 38, 37, 1,
|
||||||
|
0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 45, 1, 0, 0, 0, 40, 41, 3, 7, 3, 0, 41,
|
||||||
|
42, 3, 3, 1, 0, 42, 44, 1, 0, 0, 0, 43, 40, 1, 0, 0, 0, 44, 47, 1, 0, 0,
|
||||||
|
0, 45, 43, 1, 0, 0, 0, 45, 46, 1, 0, 0, 0, 46, 49, 1, 0, 0, 0, 47, 45,
|
||||||
|
1, 0, 0, 0, 48, 50, 3, 7, 3, 0, 49, 48, 1, 0, 0, 0, 49, 50, 1, 0, 0, 0,
|
||||||
|
50, 52, 1, 0, 0, 0, 51, 53, 5, 34, 0, 0, 52, 51, 1, 0, 0, 0, 52, 53, 1,
|
||||||
|
0, 0, 0, 53, 10, 1, 0, 0, 0, 54, 55, 7, 3, 0, 0, 55, 56, 7, 4, 0, 0, 56,
|
||||||
|
57, 7, 5, 0, 0, 57, 58, 7, 6, 0, 0, 58, 12, 1, 0, 0, 0, 59, 60, 7, 3, 0,
|
||||||
|
0, 60, 61, 7, 5, 0, 0, 61, 62, 7, 5, 0, 0, 62, 63, 7, 6, 0, 0, 63, 14,
|
||||||
|
1, 0, 0, 0, 64, 65, 7, 7, 0, 0, 65, 66, 7, 8, 0, 0, 66, 67, 7, 9, 0, 0,
|
||||||
|
67, 68, 7, 5, 0, 0, 68, 69, 7, 6, 0, 0, 69, 16, 1, 0, 0, 0, 70, 71, 7,
|
||||||
|
10, 0, 0, 71, 72, 7, 11, 0, 0, 72, 73, 7, 5, 0, 0, 73, 74, 7, 3, 0, 0,
|
||||||
|
74, 75, 7, 8, 0, 0, 75, 18, 1, 0, 0, 0, 8, 0, 22, 27, 34, 38, 45, 49, 52,
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FstabLexerInit initializes any static state used to implement FstabLexer. By default the
|
||||||
|
// static state used to implement the lexer is lazily initialized during the first call to
|
||||||
|
// NewFstabLexer(). You can call this function if you wish to initialize the static state ahead
|
||||||
|
// of time.
|
||||||
|
func FstabLexerInit() {
|
||||||
|
staticData := &FstabLexerLexerStaticData
|
||||||
|
staticData.once.Do(fstablexerLexerInit)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFstabLexer produces a new lexer instance for the optional input antlr.CharStream.
|
||||||
|
func NewFstabLexer(input antlr.CharStream) *FstabLexer {
|
||||||
|
FstabLexerInit()
|
||||||
|
l := new(FstabLexer)
|
||||||
|
l.BaseLexer = antlr.NewBaseLexer(input)
|
||||||
|
staticData := &FstabLexerLexerStaticData
|
||||||
|
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 = "Fstab.g4"
|
||||||
|
// TODO: l.EOF = antlr.TokenEOF
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// FstabLexer tokens.
|
||||||
|
const (
|
||||||
|
FstabLexerDIGITS = 1
|
||||||
|
FstabLexerWHITESPACE = 2
|
||||||
|
FstabLexerHASH = 3
|
||||||
|
FstabLexerSTRING = 4
|
||||||
|
FstabLexerQUOTED_STRING = 5
|
||||||
|
FstabLexerADFS = 6
|
||||||
|
FstabLexerAFFS = 7
|
||||||
|
FstabLexerBTRFS = 8
|
||||||
|
FstabLexerEXFAT = 9
|
||||||
|
)
|
52
server/handlers/fstab/ast/parser/fstab_listener.go
Normal file
52
server/handlers/fstab/ast/parser/fstab_listener.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Code generated from Fstab.g4 by ANTLR 4.13.0. DO NOT EDIT.
|
||||||
|
|
||||||
|
package parser // Fstab
|
||||||
|
|
||||||
|
import "github.com/antlr4-go/antlr/v4"
|
||||||
|
|
||||||
|
// FstabListener is a complete listener for a parse tree produced by FstabParser.
|
||||||
|
type FstabListener interface {
|
||||||
|
antlr.ParseTreeListener
|
||||||
|
|
||||||
|
// EnterEntry is called when entering the entry production.
|
||||||
|
EnterEntry(c *EntryContext)
|
||||||
|
|
||||||
|
// EnterSpec is called when entering the spec production.
|
||||||
|
EnterSpec(c *SpecContext)
|
||||||
|
|
||||||
|
// EnterMountPoint is called when entering the mountPoint production.
|
||||||
|
EnterMountPoint(c *MountPointContext)
|
||||||
|
|
||||||
|
// EnterFileSystem is called when entering the fileSystem production.
|
||||||
|
EnterFileSystem(c *FileSystemContext)
|
||||||
|
|
||||||
|
// EnterMountOptions is called when entering the mountOptions production.
|
||||||
|
EnterMountOptions(c *MountOptionsContext)
|
||||||
|
|
||||||
|
// EnterFreq is called when entering the freq production.
|
||||||
|
EnterFreq(c *FreqContext)
|
||||||
|
|
||||||
|
// EnterPass is called when entering the pass production.
|
||||||
|
EnterPass(c *PassContext)
|
||||||
|
|
||||||
|
// ExitEntry is called when exiting the entry production.
|
||||||
|
ExitEntry(c *EntryContext)
|
||||||
|
|
||||||
|
// ExitSpec is called when exiting the spec production.
|
||||||
|
ExitSpec(c *SpecContext)
|
||||||
|
|
||||||
|
// ExitMountPoint is called when exiting the mountPoint production.
|
||||||
|
ExitMountPoint(c *MountPointContext)
|
||||||
|
|
||||||
|
// ExitFileSystem is called when exiting the fileSystem production.
|
||||||
|
ExitFileSystem(c *FileSystemContext)
|
||||||
|
|
||||||
|
// ExitMountOptions is called when exiting the mountOptions production.
|
||||||
|
ExitMountOptions(c *MountOptionsContext)
|
||||||
|
|
||||||
|
// ExitFreq is called when exiting the freq production.
|
||||||
|
ExitFreq(c *FreqContext)
|
||||||
|
|
||||||
|
// ExitPass is called when exiting the pass production.
|
||||||
|
ExitPass(c *PassContext)
|
||||||
|
}
|
1171
server/handlers/fstab/ast/parser/fstab_parser.go
Normal file
1171
server/handlers/fstab/ast/parser/fstab_parser.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,7 @@ func TestExample1(
|
|||||||
) {
|
) {
|
||||||
input := utils.Dedent(`
|
input := utils.Dedent(`
|
||||||
LABEL=test /mnt/test ext4 defaults 0 0
|
LABEL=test /mnt/test ext4 defaults 0 0
|
||||||
|
LABEL=example /mnt/example fat32 defaults 0 2
|
||||||
`)
|
`)
|
||||||
c := NewFstabConfig()
|
c := NewFstabConfig()
|
||||||
|
|
||||||
@ -20,8 +21,8 @@ LABEL=test /mnt/test ext4 defaults 0 0
|
|||||||
t.Fatalf("Expected no errors, got %v", errors)
|
t.Fatalf("Expected no errors, got %v", errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Entries.Size() != 1 {
|
if c.Entries.Size() != 2 {
|
||||||
t.Fatalf("Expected 1 entry, got %d", c.Entries.Size())
|
t.Fatalf("Expected 2 entry, got %d", c.Entries.Size())
|
||||||
}
|
}
|
||||||
|
|
||||||
rawFirstEntry, _ := c.Entries.Get(uint32(0))
|
rawFirstEntry, _ := c.Entries.Get(uint32(0))
|
||||||
@ -93,6 +94,12 @@ LABEL=test /mnt/test ext4 defaults 0 0
|
|||||||
if !(field == FstabFieldFreq) {
|
if !(field == FstabFieldFreq) {
|
||||||
t.Errorf("Expected field to be freq, got %v", field)
|
t.Errorf("Expected field to be freq, got %v", field)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rawSecondEntry, _ := c.Entries.Get(uint32(1))
|
||||||
|
secondEntry := rawSecondEntry.(*FstabEntry)
|
||||||
|
if !(secondEntry.Fields.Start.Line == 1) {
|
||||||
|
t.Errorf("Expected start line to be 1, got %d", secondEntry.Fields.Start.Line)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIncompleteExample(
|
func TestIncompleteExample(
|
||||||
|
@ -15,7 +15,7 @@ var LabelField = docvalues.RegexValue{
|
|||||||
var SpecField = docvalues.OrValue{
|
var SpecField = docvalues.OrValue{
|
||||||
Values: []docvalues.DeprecatedValue{
|
Values: []docvalues.DeprecatedValue{
|
||||||
docvalues.PathValue{
|
docvalues.PathValue{
|
||||||
RequiredType: docvalues.PathTypeFile,
|
RequiredType: docvalues.PathTypeExistenceOptional,
|
||||||
},
|
},
|
||||||
docvalues.KeyEnumAssignmentValue{
|
docvalues.KeyEnumAssignmentValue{
|
||||||
Separator: "=",
|
Separator: "=",
|
||||||
|
@ -101,6 +101,36 @@ LABEL=test /mnt/test btrfs subvol=backup,fat=32 0 0
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIncompleteExample(t *testing.T) {
|
||||||
|
input := utils.Dedent(`
|
||||||
|
LABEL=test /mnt/test defaults 0 0
|
||||||
|
`)
|
||||||
|
p := ast.NewFstabConfig()
|
||||||
|
|
||||||
|
errors := p.Parse(input)
|
||||||
|
|
||||||
|
if len(errors) > 0 {
|
||||||
|
t.Fatal("ParseFromContent returned error", errors)
|
||||||
|
}
|
||||||
|
|
||||||
|
rawFirstEntry, _ := p.Entries.Get(uint32(0))
|
||||||
|
firstEntry := rawFirstEntry.(*ast.FstabEntry)
|
||||||
|
name := firstEntry.GetFieldAtPosition(common.CursorPosition(0))
|
||||||
|
if !(name == ast.FstabFieldSpec) {
|
||||||
|
t.Errorf("GetFieldAtPosition failed to return correct field name. Got: %v but expected: %v", name, ast.FstabFieldSpec)
|
||||||
|
}
|
||||||
|
|
||||||
|
name = firstEntry.GetFieldAtPosition(common.CursorPosition(9))
|
||||||
|
if !(name == ast.FstabFieldSpec) {
|
||||||
|
t.Errorf("GetFieldAtPosition failed to return correct field name. Got: %v but expected: %v", name, ast.FstabFieldSpec)
|
||||||
|
}
|
||||||
|
|
||||||
|
name = firstEntry.GetFieldAtPosition(common.CursorPosition(21))
|
||||||
|
if !(name == ast.FstabFieldFileSystemType) {
|
||||||
|
t.Errorf("GetFieldAtPosition failed to return correct field name. Got: %v but expected: %v", name, ast.FstabFieldFileSystemType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// func TestExample1(t *testing.T) {
|
// func TestExample1(t *testing.T) {
|
||||||
// input := utils.Dedent(`
|
// input := utils.Dedent(`
|
||||||
// /dev/disk/by-uuid/19ae4e13-1d6d-4833-965b-a20197aebf27 /mnt/RetroGames auto nosuid,nodev,nofail,x-gvfs-show 0 0
|
// /dev/disk/by-uuid/19ae4e13-1d6d-4833-965b-a20197aebf27 /mnt/RetroGames auto nosuid,nodev,nofail,x-gvfs-show 0 0
|
||||||
|
@ -42,7 +42,6 @@ func GetCompletion(
|
|||||||
fileSystemType := entry.Fields.FilesystemType.Value.Value
|
fileSystemType := entry.Fields.FilesystemType.Value.Value
|
||||||
completions := make([]protocol.CompletionItem, 0, 50)
|
completions := make([]protocol.CompletionItem, 0, 50)
|
||||||
|
|
||||||
println("fetching field options now", line, cursor)
|
|
||||||
for _, completion := range fields.DefaultMountOptionsField.DeprecatedFetchCompletions(line, cursor) {
|
for _, completion := range fields.DefaultMountOptionsField.DeprecatedFetchCompletions(line, cursor) {
|
||||||
var documentation string
|
var documentation string
|
||||||
|
|
||||||
@ -108,5 +107,9 @@ func getFieldSafely(field *ast.FstabField, cursor common.CursorPosition) (string
|
|||||||
return "", 0
|
return "", 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if uint32(cursor) < field.Start.Character {
|
||||||
|
return "", 0
|
||||||
|
}
|
||||||
|
|
||||||
return field.Value.Raw, common.CursorToCharacterIndex(uint32(cursor) - field.Start.Character)
|
return field.Value.Raw, common.CursorToCharacterIndex(uint32(cursor) - field.Start.Character)
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,13 @@ func createListenerContext() *sshListenerContext {
|
|||||||
return context
|
return context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type sshParserListener struct {
|
||||||
|
*parser.BaseConfigListener
|
||||||
|
Config *SSHConfig
|
||||||
|
Errors []common.LSPError
|
||||||
|
sshContext *sshListenerContext
|
||||||
|
}
|
||||||
|
|
||||||
func createListener(
|
func createListener(
|
||||||
config *SSHConfig,
|
config *SSHConfig,
|
||||||
context *sshListenerContext,
|
context *sshListenerContext,
|
||||||
@ -37,13 +44,6 @@ func createListener(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type sshParserListener struct {
|
|
||||||
*parser.BaseConfigListener
|
|
||||||
Config *SSHConfig
|
|
||||||
Errors []common.LSPError
|
|
||||||
sshContext *sshListenerContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *sshParserListener) EnterEntry(ctx *parser.EntryContext) {
|
func (s *sshParserListener) EnterEntry(ctx *parser.EntryContext) {
|
||||||
location := common.CharacterRangeFromCtx(ctx.BaseParserRuleContext)
|
location := common.CharacterRangeFromCtx(ctx.BaseParserRuleContext)
|
||||||
location.ChangeBothLines(s.sshContext.line)
|
location.ChangeBothLines(s.sshContext.line)
|
||||||
|
@ -5,6 +5,9 @@ ROOT=$(git rev-parse --show-toplevel)/server
|
|||||||
# aliases
|
# aliases
|
||||||
cd $ROOT/handlers/aliases && antlr4 -Dlanguage=Go -o ast/parser Aliases.g4
|
cd $ROOT/handlers/aliases && antlr4 -Dlanguage=Go -o ast/parser Aliases.g4
|
||||||
|
|
||||||
|
# fstab
|
||||||
|
cd $ROOT/hanlders/fstab && antlr4 -Dlanguage=Go -o ast/parser Fstab.g4
|
||||||
|
|
||||||
# sshd_config
|
# sshd_config
|
||||||
cd $ROOT/handlers/sshd_config && antlr4 -Dlanguage=Go -o ast/parser Config.g4
|
cd $ROOT/handlers/sshd_config && antlr4 -Dlanguage=Go -o ast/parser Config.g4
|
||||||
cd $ROOT/handlers/sshd_config/match-parser && antlr4 -Dlanguage=Go -o parser Match.g4
|
cd $ROOT/handlers/sshd_config/match-parser && antlr4 -Dlanguage=Go -o parser Match.g4
|
||||||
|
Loading…
x
Reference in New Issue
Block a user