mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-18 15:05:28 +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 {
|
||||
Fields FstabFields
|
||||
Fields *FstabFields
|
||||
}
|
||||
|
||||
type FstabConfig struct {
|
||||
|
@ -17,30 +17,118 @@ import (
|
||||
// return entry.(*FstabEntry)
|
||||
// }
|
||||
|
||||
// LABEL=test ext4 defaults 0 0
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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 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
|
||||
func (e FstabEntry) FetchMountOptionsField(includeDefaults bool) docvalues.DeprecatedValue {
|
||||
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 (
|
||||
"config-lsp/common"
|
||||
commonparser "config-lsp/common/parser"
|
||||
"config-lsp/handlers/fstab/ast/parser"
|
||||
"config-lsp/utils"
|
||||
"regexp"
|
||||
|
||||
"github.com/antlr4-go/antlr/v4"
|
||||
"github.com/emirpasic/gods/maps/treemap"
|
||||
|
||||
gods "github.com/emirpasic/gods/utils"
|
||||
@ -25,14 +27,15 @@ func (c *FstabConfig) Clear() {
|
||||
|
||||
var commentPattern = regexp.MustCompile(`^\s*#`)
|
||||
var emptyPattern = regexp.MustCompile(`^\s*$`)
|
||||
var whitespacePattern = regexp.MustCompile(`\S+`)
|
||||
|
||||
func (c *FstabConfig) Parse(input string) []common.LSPError {
|
||||
errors := make([]common.LSPError, 0)
|
||||
lines := utils.SplitIntoLines(input)
|
||||
context := createListenerContext()
|
||||
|
||||
for rawLineNumber, line := range lines {
|
||||
lineNumber := uint32(rawLineNumber)
|
||||
context.line = lineNumber
|
||||
|
||||
if emptyPattern.MatchString(line) {
|
||||
continue
|
||||
@ -45,89 +48,121 @@ func (c *FstabConfig) Parse(input string) []common.LSPError {
|
||||
|
||||
errors = append(
|
||||
errors,
|
||||
c.parseStatement(lineNumber, line)...,
|
||||
c.parseStatement(context, line)...,
|
||||
)
|
||||
}
|
||||
|
||||
return errors
|
||||
}
|
||||
|
||||
// TODO: Handle leading comments
|
||||
func (c *FstabConfig) parseStatement(
|
||||
line uint32,
|
||||
context *fstabListenerContext,
|
||||
input string,
|
||||
) []common.LSPError {
|
||||
fields := whitespacePattern.FindAllStringIndex(input, -1)
|
||||
stream := antlr.NewInputStream(input)
|
||||
|
||||
if len(fields) == 0 {
|
||||
return []common.LSPError{
|
||||
{
|
||||
Range: common.LocationRange{
|
||||
Start: common.Location{
|
||||
Line: line,
|
||||
Character: 0,
|
||||
},
|
||||
End: common.Location{
|
||||
Line: line,
|
||||
Character: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
lexerErrorListener := createErrorListener(context.line)
|
||||
lexer := parser.NewFstabLexer(stream)
|
||||
lexer.RemoveErrorListeners()
|
||||
lexer.AddErrorListener(&lexerErrorListener)
|
||||
|
||||
var spec *FstabField
|
||||
var mountPoint *FstabField
|
||||
var filesystemType *FstabField
|
||||
var options *FstabField
|
||||
var freq *FstabField
|
||||
var pass *FstabField
|
||||
tokenStream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
|
||||
|
||||
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])
|
||||
}
|
||||
parserErrorListener := createErrorListener(context.line)
|
||||
antlrParser := parser.NewFstabParser(tokenStream)
|
||||
antlrParser.RemoveErrorListeners()
|
||||
antlrParser.AddErrorListener(&parserErrorListener)
|
||||
|
||||
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,
|
||||
},
|
||||
}
|
||||
listener := createListener(c, context)
|
||||
antlr.ParseTreeWalkerDefault.Walk(
|
||||
&listener,
|
||||
antlrParser.Entry(),
|
||||
)
|
||||
|
||||
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(
|
||||
line uint32,
|
||||
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(`
|
||||
LABEL=test /mnt/test ext4 defaults 0 0
|
||||
LABEL=example /mnt/example fat32 defaults 0 2
|
||||
`)
|
||||
c := NewFstabConfig()
|
||||
|
||||
@ -20,8 +21,8 @@ LABEL=test /mnt/test ext4 defaults 0 0
|
||||
t.Fatalf("Expected no errors, got %v", errors)
|
||||
}
|
||||
|
||||
if c.Entries.Size() != 1 {
|
||||
t.Fatalf("Expected 1 entry, got %d", c.Entries.Size())
|
||||
if c.Entries.Size() != 2 {
|
||||
t.Fatalf("Expected 2 entry, got %d", c.Entries.Size())
|
||||
}
|
||||
|
||||
rawFirstEntry, _ := c.Entries.Get(uint32(0))
|
||||
@ -93,6 +94,12 @@ LABEL=test /mnt/test ext4 defaults 0 0
|
||||
if !(field == FstabFieldFreq) {
|
||||
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(
|
||||
|
@ -15,7 +15,7 @@ var LabelField = docvalues.RegexValue{
|
||||
var SpecField = docvalues.OrValue{
|
||||
Values: []docvalues.DeprecatedValue{
|
||||
docvalues.PathValue{
|
||||
RequiredType: docvalues.PathTypeFile,
|
||||
RequiredType: docvalues.PathTypeExistenceOptional,
|
||||
},
|
||||
docvalues.KeyEnumAssignmentValue{
|
||||
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) {
|
||||
// input := utils.Dedent(`
|
||||
// /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
|
||||
completions := make([]protocol.CompletionItem, 0, 50)
|
||||
|
||||
println("fetching field options now", line, cursor)
|
||||
for _, completion := range fields.DefaultMountOptionsField.DeprecatedFetchCompletions(line, cursor) {
|
||||
var documentation string
|
||||
|
||||
@ -108,5 +107,9 @@ func getFieldSafely(field *ast.FstabField, cursor common.CursorPosition) (string
|
||||
return "", 0
|
||||
}
|
||||
|
||||
if uint32(cursor) < field.Start.Character {
|
||||
return "", 0
|
||||
}
|
||||
|
||||
return field.Value.Raw, common.CursorToCharacterIndex(uint32(cursor) - field.Start.Character)
|
||||
}
|
||||
|
@ -26,6 +26,13 @@ func createListenerContext() *sshListenerContext {
|
||||
return context
|
||||
}
|
||||
|
||||
type sshParserListener struct {
|
||||
*parser.BaseConfigListener
|
||||
Config *SSHConfig
|
||||
Errors []common.LSPError
|
||||
sshContext *sshListenerContext
|
||||
}
|
||||
|
||||
func createListener(
|
||||
config *SSHConfig,
|
||||
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) {
|
||||
location := common.CharacterRangeFromCtx(ctx.BaseParserRuleContext)
|
||||
location.ChangeBothLines(s.sshContext.line)
|
||||
|
@ -5,6 +5,9 @@ ROOT=$(git rev-parse --show-toplevel)/server
|
||||
# aliases
|
||||
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
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user