mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-18 23:15:26 +02:00
195 lines
4.2 KiB
Go
195 lines
4.2 KiB
Go
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"
|
|
)
|
|
|
|
func NewFstabConfig() *FstabConfig {
|
|
config := &FstabConfig{}
|
|
config.Clear()
|
|
|
|
return config
|
|
}
|
|
|
|
func (c *FstabConfig) Clear() {
|
|
c.Entries = treemap.NewWith(gods.UInt32Comparator)
|
|
c.CommentLines = map[uint32]struct{}{}
|
|
}
|
|
|
|
var commentPattern = regexp.MustCompile(`^\s*#`)
|
|
var emptyPattern = 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
|
|
}
|
|
|
|
if commentPattern.MatchString(line) {
|
|
c.CommentLines[lineNumber] = struct{}{}
|
|
continue
|
|
}
|
|
|
|
errors = append(
|
|
errors,
|
|
c.parseStatement(context, line)...,
|
|
)
|
|
}
|
|
|
|
return errors
|
|
}
|
|
|
|
// TODO: Handle leading comments
|
|
func (c *FstabConfig) parseStatement(
|
|
context *fstabListenerContext,
|
|
input string,
|
|
) []common.LSPError {
|
|
stream := antlr.NewInputStream(input)
|
|
|
|
lexerErrorListener := createErrorListener(context.line)
|
|
lexer := parser.NewFstabLexer(stream)
|
|
lexer.RemoveErrorListeners()
|
|
lexer.AddErrorListener(&lexerErrorListener)
|
|
|
|
tokenStream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
|
|
|
|
parserErrorListener := createErrorListener(context.line)
|
|
antlrParser := parser.NewFstabParser(tokenStream)
|
|
antlrParser.RemoveErrorListeners()
|
|
antlrParser.AddErrorListener(&parserErrorListener)
|
|
|
|
listener := createListener(c, context)
|
|
antlr.ParseTreeWalkerDefault.Walk(
|
|
&listener,
|
|
antlrParser.Entry(),
|
|
)
|
|
|
|
errors := lexerErrorListener.Errors
|
|
errors = append(errors, parserErrorListener.Errors...)
|
|
errors = append(errors, listener.Errors...)
|
|
|
|
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,
|
|
field []int,
|
|
) *FstabField {
|
|
start := uint32(field[0])
|
|
end := uint32(field[1])
|
|
value := input[start:end]
|
|
|
|
return &FstabField{
|
|
LocationRange: common.LocationRange{
|
|
Start: common.Location{
|
|
Line: line,
|
|
Character: start,
|
|
},
|
|
End: common.Location{
|
|
Line: line,
|
|
Character: end,
|
|
},
|
|
},
|
|
Value: commonparser.ParseRawString(value, commonparser.ParseFeatures{
|
|
ParseEscapedCharacters: true,
|
|
ParseDoubleQuotes: true,
|
|
Replacements: &map[string]string{
|
|
`\\040`: " ",
|
|
},
|
|
}),
|
|
}
|
|
}
|