mirror of
https://github.com/daeuniverse/dae.git
synced 2024-12-22 21:44:55 +07:00
95 lines
2.8 KiB
Go
95 lines
2.8 KiB
Go
/*
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
* Copyright (c) 2022-2024, daeuniverse Organization <dae@v2raya.org>
|
|
*/
|
|
|
|
package config_parser
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/antlr/antlr4/runtime/Go/antlr/v4"
|
|
"reflect"
|
|
"strings"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type ErrorType string
|
|
|
|
const (
|
|
ErrorType_Unsupported ErrorType = "is not supported"
|
|
ErrorType_NotSet ErrorType = "is not set"
|
|
)
|
|
|
|
type ConsoleErrorListener struct {
|
|
ErrorBuilder strings.Builder
|
|
}
|
|
|
|
func NewConsoleErrorListener() *ConsoleErrorListener {
|
|
return &ConsoleErrorListener{}
|
|
}
|
|
|
|
func (d *ConsoleErrorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) {
|
|
// Do not accumulate errors.
|
|
if d.ErrorBuilder.Len() > 0 {
|
|
return
|
|
}
|
|
backtrack := column
|
|
if backtrack > 30 {
|
|
backtrack = 30
|
|
}
|
|
starting := fmt.Sprintf("line %v:%v ", line, column)
|
|
offset := len(starting) + backtrack
|
|
var (
|
|
simplyWrite bool
|
|
token antlr.Token
|
|
)
|
|
if offendingSymbol == nil {
|
|
simplyWrite = true
|
|
} else {
|
|
token = offendingSymbol.(antlr.Token)
|
|
simplyWrite = token.GetTokenType() == -1
|
|
}
|
|
if simplyWrite {
|
|
d.ErrorBuilder.WriteString(fmt.Sprintf("%v%v", starting, msg))
|
|
return
|
|
}
|
|
|
|
beginOfLine := token.GetStart() - backtrack
|
|
strPeek := token.GetInputStream().GetText(beginOfLine, token.GetStop()+30)
|
|
wrap := strings.IndexByte(strPeek, '\n')
|
|
if wrap == -1 {
|
|
wrap = token.GetStop() + 30
|
|
} else {
|
|
wrap += beginOfLine - 1
|
|
}
|
|
strLine := token.GetInputStream().GetText(beginOfLine, wrap)
|
|
d.ErrorBuilder.WriteString(fmt.Sprintf("%v%v\n%v%v: %v\n", starting, strLine, strings.Repeat(" ", offset), strings.Repeat("^", token.GetStop()-token.GetStart()+1), msg))
|
|
}
|
|
func (d *ConsoleErrorListener) ReportAmbiguity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, exact bool, ambigAlts *antlr.BitSet, configs antlr.ATNConfigSet) {
|
|
}
|
|
|
|
func (d *ConsoleErrorListener) ReportAttemptingFullContext(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, conflictingAlts *antlr.BitSet, configs antlr.ATNConfigSet) {
|
|
}
|
|
|
|
func (d *ConsoleErrorListener) ReportContextSensitivity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex, prediction int, configs antlr.ATNConfigSet) {
|
|
}
|
|
|
|
func BaseContext(ctx interface{}) (baseCtx *antlr.BaseParserRuleContext) {
|
|
val := reflect.ValueOf(ctx)
|
|
for val.Kind() == reflect.Pointer && val.Type() != reflect.TypeOf(&antlr.BaseParserRuleContext{}) {
|
|
val = val.Elem()
|
|
}
|
|
if val.Type() == reflect.TypeOf(&antlr.BaseParserRuleContext{}) {
|
|
baseCtx = val.Interface().(*antlr.BaseParserRuleContext)
|
|
} else {
|
|
baseCtxVal := val.FieldByName("BaseParserRuleContext")
|
|
if !baseCtxVal.IsValid() {
|
|
logrus.Debugf("%T", ctx)
|
|
panic("has no field BaseParserRuleContext")
|
|
}
|
|
baseCtx = baseCtxVal.Interface().(*antlr.BaseParserRuleContext)
|
|
}
|
|
return baseCtx
|
|
}
|