mirror of
https://github.com/SecurityBrewery/catalyst.git
synced 2025-12-06 15:22:47 +01:00
Release catalyst
This commit is contained in:
120
caql/parser.go
Normal file
120
caql/parser.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package caql
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
|
||||
"github.com/SecurityBrewery/catalyst/generated/caql/parser"
|
||||
)
|
||||
|
||||
type Parser struct {
|
||||
Searcher Searcher
|
||||
Prefix string
|
||||
}
|
||||
|
||||
func (p *Parser) Parse(aql string) (t *Tree, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = fmt.Errorf("%s", r)
|
||||
}
|
||||
}()
|
||||
// Setup the input
|
||||
inputStream := antlr.NewInputStream(aql)
|
||||
|
||||
errorListener := &errorListener{}
|
||||
|
||||
// Create the Lexer
|
||||
lexer := parser.NewCAQLLexer(inputStream)
|
||||
lexer.RemoveErrorListeners()
|
||||
lexer.AddErrorListener(errorListener)
|
||||
stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
|
||||
|
||||
// Create the Parser
|
||||
aqlParser := parser.NewCAQLParser(stream)
|
||||
|
||||
aqlParser.RemoveErrorListeners()
|
||||
aqlParser.AddErrorListener(errorListener)
|
||||
aqlParser.SetErrorHandler(antlr.NewBailErrorStrategy())
|
||||
if errorListener.errs != nil {
|
||||
err = errorListener.errs[0]
|
||||
}
|
||||
|
||||
return &Tree{aqlParser: aqlParser, parseContext: aqlParser.Parse(), searcher: p.Searcher, prefix: p.Prefix}, err
|
||||
}
|
||||
|
||||
type Tree struct {
|
||||
parseContext parser.IParseContext
|
||||
aqlParser *parser.CAQLParser
|
||||
searcher Searcher
|
||||
prefix string
|
||||
}
|
||||
|
||||
func (t *Tree) Eval(values map[string]interface{}) (i interface{}, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = fmt.Errorf("%s", r)
|
||||
}
|
||||
}()
|
||||
interpreter := aqlInterpreter{values: values}
|
||||
|
||||
antlr.ParseTreeWalkerDefault.Walk(&interpreter, t.parseContext)
|
||||
|
||||
if interpreter.errs != nil {
|
||||
return nil, interpreter.errs[0]
|
||||
}
|
||||
return interpreter.stack[0], nil
|
||||
}
|
||||
|
||||
func (t *Tree) String() (s string, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = fmt.Errorf("%s", r)
|
||||
}
|
||||
}()
|
||||
builder := aqlBuilder{searcher: t.searcher, prefix: t.prefix}
|
||||
|
||||
antlr.ParseTreeWalkerDefault.Walk(&builder, t.parseContext)
|
||||
|
||||
return builder.stack[0], err
|
||||
}
|
||||
|
||||
func (t *Tree) BleveString() (s string, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = fmt.Errorf("%s", r)
|
||||
}
|
||||
}()
|
||||
builder := bleveBuilder{}
|
||||
|
||||
antlr.ParseTreeWalkerDefault.Walk(&builder, t.parseContext)
|
||||
|
||||
if builder.err != nil {
|
||||
return "", builder.err
|
||||
}
|
||||
|
||||
return builder.stack[0], err
|
||||
}
|
||||
|
||||
type errorListener struct {
|
||||
*antlr.DefaultErrorListener
|
||||
errs []error
|
||||
}
|
||||
|
||||
func (el *errorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) {
|
||||
el.errs = append(el.errs, fmt.Errorf("line "+strconv.Itoa(line)+":"+strconv.Itoa(column)+" "+msg))
|
||||
}
|
||||
|
||||
func (el *errorListener) ReportAmbiguity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, exact bool, ambigAlts *antlr.BitSet, configs antlr.ATNConfigSet) {
|
||||
el.errs = append(el.errs, errors.New("ReportAmbiguity"))
|
||||
}
|
||||
|
||||
func (el *errorListener) ReportAttemptingFullContext(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, conflictingAlts *antlr.BitSet, configs antlr.ATNConfigSet) {
|
||||
el.errs = append(el.errs, errors.New("ReportAttemptingFullContext"))
|
||||
}
|
||||
|
||||
func (el *errorListener) ReportContextSensitivity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex, prediction int, configs antlr.ATNConfigSet) {
|
||||
el.errs = append(el.errs, errors.New("ReportContextSensitivity"))
|
||||
}
|
||||
Reference in New Issue
Block a user