diff --git a/.gitignore b/.gitignore index c4fba4e..a6c612e 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,6 @@ go.work # End of https://www.toptal.com/developers/gitignore/api/go -parser/ \ No newline at end of file +parser/ + +go.sum \ No newline at end of file diff --git a/Wyst.g4 b/Wyst.g4 index 8d2d2a9..ab6f50b 100644 --- a/Wyst.g4 +++ b/Wyst.g4 @@ -2,10 +2,8 @@ grammar Wyst; WS : [ \t\r\n]+ -> skip; -expr: expr ('*'|'/') expr - | expr ('+'|'-') expr - | INT - | '(' expr ')' +expr: IDENTIFIER ; -INT: [0-9]+; \ No newline at end of file +INT: [0-9]+; +IDENTIFIER: [a-zA-Z_] ([a-zA-Z0-9] | '::')*; \ No newline at end of file diff --git a/go.mod b/go.mod index af7a2e8..57bf7eb 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,4 @@ toolchain go1.22.6 require github.com/antlr4-go/antlr/v4 v4.13.1 // direct -require ( - // github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect - golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect -) +require golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect diff --git a/go.sum b/go.sum index d57d439..a4312cd 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,3 @@ -github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves= -github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= -github.com/antlr4-go/antlr v0.0.0-20230518091524-98b52378c522 h1:o+W7GDFUwWtVkN28CW/nhh/aCmHn6OJddUs3+8vMMjs= -github.com/antlr4-go/antlr v0.0.0-20230518091524-98b52378c522/go.mod h1:srLVvW4JLxy+tCG9Nn2l8al77mUIMCwAOLQocfLDU2w= github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= diff --git a/main.go b/main.go index f8dc3fd..60721e5 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,8 @@ package main -import ( -) +import "fmt" func main() { - tree, parser := Parse("") - iterateTree(tree, parser, 0) + ast := Parse("abc123::hello") + fmt.Printf("%v", ast) } diff --git a/parser.go b/parser.go new file mode 100644 index 0000000..e4cd0c4 --- /dev/null +++ b/parser.go @@ -0,0 +1,53 @@ +package main + +import ( + "github.com/antlr4-go/antlr/v4" + "github.com/wyst-lang/wyst/parser" +) + +type ASTNode struct { + Rule string + Text string + Inner []ASTNode +} + +func getTokenName(tokenType int, lexer *parser.WystLexer) string { + if tokenType >= 0 && tokenType < len(lexer.SymbolicNames) { + if lexer.SymbolicNames[tokenType] != "" { + return lexer.SymbolicNames[tokenType] + } + return lexer.LiteralNames[tokenType] + } + return "UNKNOWN" +} + +func ConvertAST(node antlr.Tree, wparser *parser.WystParser, lexer *parser.WystLexer) ASTNode { + var ast = ASTNode{} + switch node := node.(type) { + case antlr.TerminalNode: + token := node.GetSymbol() + ast.Text = token.GetText() + ast.Rule = getTokenName(token.GetTokenType(), lexer) + default: + if ruleContext, ok := node.(antlr.RuleContext); ok { + ast.Rule = wparser.RuleNames[ruleContext.GetRuleIndex()] + } + if parseTree, ok := node.(antlr.ParseTree); ok { + ast.Text = parseTree.GetText() + } + for i := 0; i < node.GetChildCount(); i++ { + ast.Inner = append(ast.Inner, ConvertAST(node.GetChild(i), wparser, lexer)) + } + } + return ast +} + +func Parse(code string) ASTNode { + chars := antlr.NewInputStream(code) + lexer := parser.NewWystLexer(chars) + stream := antlr.NewCommonTokenStream(lexer, 0) + p := parser.NewWystParser(stream) + // p.AddErrorListener(antlr.NewDiagnosticErrorListener(true).WithContext(p)) + tree := p.Expr() + return ConvertAST(tree, p, lexer) +} diff --git a/utils.go b/utils.go index 83afb7f..a348b13 100644 --- a/utils.go +++ b/utils.go @@ -3,22 +3,10 @@ package main import ( "fmt" - "github.com/antlr4-go/antlr/v4" + "github.com/antlr4-go/antlr" "github.com/wyst-lang/wyst/parser" ) -func Parse(code string) (antlr.ParseTree, *parser.WystParser) { - chars := antlr.NewInputStream(code) - lexer := parser.NewWystLexer(chars) - stream := antlr.NewCommonTokenStream(lexer, 0) - - p := parser.NewWystParser(stream) - // p.AddErrorListener(antlr.NewDiagnosticErrorListener(true).WithContext(p)) - - tree := p.Expr() - return tree, p -} - func iterateTree(node antlr.Tree, wparser *parser.WystParser, depth int) { if ruleContext, ok := node.(antlr.RuleContext); ok { ruleIndex := ruleContext.GetRuleIndex()