diff --git a/main.go b/main.go index 33d2dda..c685d41 100644 --- a/main.go +++ b/main.go @@ -7,8 +7,8 @@ import ( ) func main() { - code := "hello" - ast, state, err := parser.Parse(code, parser.TOP) + code := "int x" + ast, state, err := parser.Parse(code, parser.RULE_SET) if err != nil { fmt.Printf("SyntaxErr at %d:%d: %s\n", state.Line, state.Column, err) return diff --git a/parser/ast.go b/parser/ast.go index 4323a2c..a580a02 100644 --- a/parser/ast.go +++ b/parser/ast.go @@ -2,59 +2,34 @@ package parser import ( "fmt" - - "github.com/wyst-lang/wyst/tokenizer" ) -type inner interface { - isInner() -} - type Rule struct { Name string - Inner inner + Inner []Rule } -func (t Rule) String() string { - return fmt.Sprintf("AstRule(%s)", t.Name) -} - -type Rules struct { - Value []Rule -} - -func (v Rules) isInner() {} - -type Token struct { - Value tokenizer.Rule -} - -func (v Token) isInner() {} - -type String struct { - Value string -} - -func (v String) isInner() {} - type AstNode struct { Rule Rule - Value string Inner []AstNode } func (t AstNode) String() string { - return fmt.Sprintf("AstNode(\n rule=%s,\n value=%s,\n inner=%v\n)", t.Rule, t.Value, t.Inner) + return fmt.Sprintf("AstNode(\n rule=%v,\n inner=%v,\n)", t.Rule, t.Inner) +} +func (t Rule) String() string { + return t.Name +} + +func NewRule(name string, inner []Rule) Rule { + return Rule{name, inner} } -// Ported rules from the tokenizer var ( - IDENTIFIER = Rule{"IDENTIFIER", Token{tokenizer.IDENTIFIER}} + IDENTIFIER = NewRule("IDENTIFIER", []Rule{}) + VAR_DEF = NewRule("VAR_DEF", []Rule{IDENTIFIER, IDENTIFIER}) ) var ( - TOP = Rule{"TOP", Rules{ - []Rule{ - IDENTIFIER, - }}} + RULE_SET = []Rule{IDENTIFIER, VAR_DEF} ) diff --git a/parser/parser.go b/parser/parser.go index fce8f93..57d42ab 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -4,14 +4,31 @@ import ( "github.com/wyst-lang/wyst/tokenizer" ) -func Parse(code string, rule Rule) ([]AstNode, tokenizer.State, error) { - tokens, state, _ := tokenizer.Tokenize(code) +func Parse(code string, rule_set []Rule) ([]AstNode, tokenizer.State, error) { var ast = []AstNode{} + tokens, state, err := tokenizer.Tokenize(code) for i := 0; i < len(tokens); i++ { - // token := tokens[i] - if rule.Inner == (String{""}) { - + for r := 0; r < len(rule_set); r++ { + matching := false + var match_nodes = []AstNode{} + for v := 0; v < len(rule_set[r].Inner); v++ { + if len(tokens)-i > v && tokens[i].Rule.Name == rule_set[r].Inner[v].Name { + matching = true + match_nodes = append(match_nodes, AstNode{Rule: rule_set[r].Inner[v]}) + } else { + matching = false + break + } + } + if matching { + ast = append(ast, AstNode{Rule: rule_set[r], Inner: match_nodes}) + i += len(match_nodes) - 1 + break + } } } + if err != nil { + return ast, state, err + } return ast, state, nil }