Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] parser: framework started #28

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions internal/commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ func Commands() []*cmd.Command {
ping,
purge,
uptime,
update,
nitro,
debug,
helpCommands,
help,
lex,
}
}
78 changes: 78 additions & 0 deletions internal/commands/lex.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package commands

import "github.com/the-sanctuary/waddles/pkg/cmd"

/* === top level command === */
var lex *cmd.Command = &cmd.Command{
Name: "lex",
Aliases: []string{""},
Description: "Temporary command to test the lexer and parser (based on topics).",
Usage: "lex (add|list|remove|manage)",
SubCommands: []*cmd.Command{lexAdd, lexList, lexRemove, lexManage},
}

/* === primary subcommands === */
var lexAdd *cmd.Command = &cmd.Command{
Name: "add",
Aliases: []string{""},
Description: "Temporary command to test the lexer and parser (based on topics).",
Usage: "lex add <slug>",
SubCommands: []*cmd.Command{},
}

var lexList *cmd.Command = &cmd.Command{
Name: "list",
Aliases: []string{""},
Description: "Temporary command to test the lexer and parser (based on topics).",
Usage: "lex list",
SubCommands: []*cmd.Command{},
}

var lexRemove *cmd.Command = &cmd.Command{
Name: "remove",
Aliases: []string{""},
Description: "Temporary command to test the lexer and parser (based on topics).",
Usage: "lex remove <slug>",
SubCommands: []*cmd.Command{},
}

var lexManage *cmd.Command = &cmd.Command{
Name: "manage",
Aliases: []string{""},
Description: "Temporary command to test the lexer and parser (based on topics).",
Usage: "lex manage (add|remove|edit|tags)",
SubCommands: []*cmd.Command{lexManageAdd, lexManageRemove},
}

/* === secondary subommands */
var lexManageAdd *cmd.Command = &cmd.Command{
Name: "add",
Aliases: []string{""},
Description: "Temporary command to test the lexer and parser (based on topics).",
Usage: "lex manage add <slug> <name> [<tag>] <description>",
SubCommands: []*cmd.Command{},
}

var lexManageRemove *cmd.Command = &cmd.Command{
Name: "remove",
Aliases: []string{""},
Description: "Temporary command to test the lexer and parser (based on topics).",
Usage: "lex manage <slug>",
SubCommands: []*cmd.Command{},
}

// var lexManageEdit *cmd.Command = &cmd.Command{
// Name: "edit",
// Aliases: []string{""},
// Description: "Temporary command to test the lexer and parser (based on topics).",
// Usage: "lex manage edit",
// SubCommands: []*cmd.Command{},
// }

// var lexManageTags *cmd.Command = &cmd.Command{
// Name: "tags",
// Aliases: []string{""},
// Description: "Temporary command to test the lexer and parser (based on topics).",
// Usage: "lex manage tags",
// SubCommands: []*cmd.Command{},
// }
2 changes: 2 additions & 0 deletions internal/commands/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ var updateGatekeeper *cmd.Command = &cmd.Command{
"You may decline to accept these rules, but you will be not be granted access to the server, and will instead be kicked.\n\n" +
"Please type `accept`, to accept the rules above, or `decline`, to leave the server.")

log.Trace().Msgf("%s", msg)

// Send the message to the channel specified in the gatekeeper config
c.Session.ChannelMessageSend(config.Gatekeeper.ChannelID, msg)
},
Expand Down
1 change: 1 addition & 0 deletions pkg/cmd/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func (ctx *Context) ReplyError(err error) bool {
return false
}

// ReplyTimeDeleteStringf just putting this here to get rid of the warning
func (ctx *Context) ReplyTimeDeleteStringf(delay time.Duration, format string, a ...interface{}) {
errMsg := ctx.ReplyStringf(format, a...)

Expand Down
10 changes: 9 additions & 1 deletion pkg/cmd/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/the-sanctuary/waddles/pkg/cfg"
"github.com/the-sanctuary/waddles/pkg/db"
"github.com/the-sanctuary/waddles/pkg/parser"
"github.com/the-sanctuary/waddles/pkg/permissions"
"github.com/the-sanctuary/waddles/pkg/util"
)
Expand All @@ -21,15 +22,17 @@ type Router struct {
WadlDB *db.WadlDB
PermSystem *permissions.PermissionSystem
Config *cfg.Config
Parser *parser.Parser
}

//BuildRouter returns a fully built router stuct with commands preregistered
func BuildRouter(wdb *db.WadlDB, permSystem *permissions.PermissionSystem, cfg *cfg.Config) Router {
func BuildRouter(wdb *db.WadlDB, permSystem *permissions.PermissionSystem, cfg *cfg.Config, parser *parser.Parser) Router {
r := Router{
Prefix: cfg.Wadl.Prefix,
WadlDB: wdb,
PermSystem: permSystem,
Config: cfg,
Parser: parser,
}

return r
Expand Down Expand Up @@ -85,6 +88,10 @@ func (r *Router) Handler() func(*discordgo.Session, *discordgo.MessageCreate) {
split := strings.Split(message.Content[len(r.Prefix):], " ")
correct, cmd := triggerCheck(split[0], r.Commands)

tree := parser.BuildCmdTree()
r.Parser.Parse(split[0], tree)
tree.LRTraverse()

if correct {
deepestCmd, args, node := findDeepestCommand(cmd, split, cmd.Name)

Expand Down Expand Up @@ -126,6 +133,7 @@ func defaultHandler(ctx *Context) {
ctx.ReplyString(builder.String())
}

// RBuildHelp helps build :P
func RBuildHelp(c *Context, builder *strings.Builder, cmds []*Command, depth int) {
for _, cmd := range cmds {
if cmd.HideInHelp {
Expand Down
16 changes: 16 additions & 0 deletions pkg/parser/lexer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package parser

type Lexer struct {
Lexemes map[string][]string
}

// BuildLexer returns a Lexer with the proper keyowrds and tokens
func BuildLexer() Lexer {
lex := Lexer{}

// Define the lexemes for our lexer
lex.Lexemes = map[string][]string{
"<cmd>": {""},
}
return lex
}
43 changes: 43 additions & 0 deletions pkg/parser/parser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package parser

// Parser object to hold data of the command parser
type Parser struct {
StringDelims []string
LRDelims []string
}

// BuildParser constructor-like factory function for the Parser object
func BuildParser(stringDelims []string) Parser {
p := Parser{}
for _, sd := range stringDelims {
if len(sd) == 1 {
p.StringDelims = append(p.StringDelims, sd)
} else if len(sd) == 2 {
p.LRDelims = append(p.LRDelims, string(sd[0]))
p.LRDelims = append(p.LRDelims, string(sd[1]))
}
}
return p
}

// Parse parses a command string into a command tree
func (p *Parser) Parse(raw string, tree *CmdTree) {
c1 := BuildCmdTreeArg("hello")
c2 := BuildCmdTreeArg("world")
tree.Data = raw
tree.Trees = []*CmdTree{c1, c2}
}

// func isCmdOrSubCmd(cmd string, commands []cmd.Command) bool {
// for _, command := range commands {
// if command.Name == cmd {
// return true
// }
// for _, subCommand := range command.SubCommands {
// if subCommand.Name == cmd {
// return true
// }
// }
// }
// return false
// }
39 changes: 39 additions & 0 deletions pkg/parser/tree.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package parser

import "github.com/rs/zerolog/log"

// CmdTree tree object for holding a parsed command string
type CmdTree struct {
Data string
Trees []*CmdTree
}

// BuildCmdTree constructor-like factory function for the CmdTree object
func BuildCmdTree() *CmdTree {
tree := &CmdTree{
Data: "",
Trees: []*CmdTree{},
}
return tree
}

// BuildCmdTreeArg constructor-like factory function for the CmdTree object and passing in data
func BuildCmdTreeArg(data string) *CmdTree {
tree := &CmdTree{
Data: data,
Trees: []*CmdTree{},
}
return tree
}

// LRTraverse traverses a CmdTree object from bottom up, left to right
func (t *CmdTree) LRTraverse() {
if len(t.Trees) == 0 {
log.Trace().Msgf("LRTraverse> %s", t.Data)
return
}
for _, tree := range t.Trees {
tree.LRTraverse()
}
log.Trace().Msgf("LRTraverse> %s", t.Data)
}
9 changes: 8 additions & 1 deletion pkg/waddles/waddles.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/the-sanctuary/waddles/internal/handlers"
"github.com/the-sanctuary/waddles/pkg/cfg"
"github.com/the-sanctuary/waddles/pkg/cmd"
"github.com/the-sanctuary/waddles/pkg/parser"

"github.com/the-sanctuary/waddles/pkg/db"
"github.com/the-sanctuary/waddles/pkg/handler"
Expand Down Expand Up @@ -45,7 +46,13 @@ func (w *Waddles) Run() {

permSystem := permissions.BuildPermissionSystem(cfg.Cfg().GetConfigFileLocation("permissions.toml"))

r := cmd.BuildRouter(w.Database, &permSystem, cfg.Cfg())
// Build the parser
parser := parser.BuildParser([]string{"\"", "'", "<>", "()"})
log.Trace().Msgf("String Delims: %s", parser.StringDelims)
log.Trace().Msgf("String Delims: %s", parser.LRDelims)

// Build the router
r := cmd.BuildRouter(w.Database, &permSystem, cfg.Cfg(), &parser)

r.RegisterCommands(commands.Commands())

Expand Down