parser
This commit is contained in:
@@ -7,8 +7,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
code := "hello"
|
code := "int x"
|
||||||
ast, state, err := parser.Parse(code, parser.TOP)
|
ast, state, err := parser.Parse(code, parser.RULE_SET)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("SyntaxErr at %d:%d: %s\n", state.Line, state.Column, err)
|
fmt.Printf("SyntaxErr at %d:%d: %s\n", state.Line, state.Column, err)
|
||||||
return
|
return
|
||||||
|
|||||||
+12
-37
@@ -2,59 +2,34 @@ package parser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/wyst-lang/wyst/tokenizer"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type inner interface {
|
|
||||||
isInner()
|
|
||||||
}
|
|
||||||
|
|
||||||
type Rule struct {
|
type Rule struct {
|
||||||
Name string
|
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 {
|
type AstNode struct {
|
||||||
Rule Rule
|
Rule Rule
|
||||||
Value string
|
|
||||||
Inner []AstNode
|
Inner []AstNode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t AstNode) String() string {
|
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 (
|
var (
|
||||||
IDENTIFIER = Rule{"IDENTIFIER", Token{tokenizer.IDENTIFIER}}
|
IDENTIFIER = NewRule("IDENTIFIER", []Rule{})
|
||||||
|
VAR_DEF = NewRule("VAR_DEF", []Rule{IDENTIFIER, IDENTIFIER})
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TOP = Rule{"TOP", Rules{
|
RULE_SET = []Rule{IDENTIFIER, VAR_DEF}
|
||||||
[]Rule{
|
|
||||||
IDENTIFIER,
|
|
||||||
}}}
|
|
||||||
)
|
)
|
||||||
|
|||||||
+22
-5
@@ -4,14 +4,31 @@ import (
|
|||||||
"github.com/wyst-lang/wyst/tokenizer"
|
"github.com/wyst-lang/wyst/tokenizer"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Parse(code string, rule Rule) ([]AstNode, tokenizer.State, error) {
|
func Parse(code string, rule_set []Rule) ([]AstNode, tokenizer.State, error) {
|
||||||
tokens, state, _ := tokenizer.Tokenize(code)
|
|
||||||
var ast = []AstNode{}
|
var ast = []AstNode{}
|
||||||
|
tokens, state, err := tokenizer.Tokenize(code)
|
||||||
for i := 0; i < len(tokens); i++ {
|
for i := 0; i < len(tokens); i++ {
|
||||||
// token := tokens[i]
|
for r := 0; r < len(rule_set); r++ {
|
||||||
if rule.Inner == (String{""}) {
|
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
|
return ast, state, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user