github.com/jmigpin/editor@v1.6.0/util/parseutil/lrparser/lrparser.go (about) 1 package lrparser 2 3 import ( 4 "fmt" 5 ) 6 7 //godebug:annotatepackage:github.com/jmigpin/editor/util/parseutil 8 9 type Lrparser struct { 10 fset *FileSet 11 ri *RuleIndex 12 } 13 14 func NewLrparserFromBytes(src []byte) (*Lrparser, error) { 15 fset := NewFileSetFromBytes(src) 16 return NewLrparser(fset) 17 } 18 func NewLrparserFromString(src string) (*Lrparser, error) { 19 return NewLrparserFromBytes([]byte(src)) 20 } 21 func NewLrparser(fset *FileSet) (*Lrparser, error) { 22 lrp := &Lrparser{fset: fset} 23 // rule index (setups predefined rules) 24 lrp.ri = newRuleIndex() 25 if err := setupPredefineds(lrp.ri); err != nil { 26 return nil, err 27 } 28 // parse provided grammar 29 gp := newGrammarParser(lrp.ri) 30 if err := gp.parse(lrp.fset); err != nil { 31 return nil, err 32 } 33 return lrp, nil 34 } 35 36 func (lrp *Lrparser) ContentParser(opt *CpOpt) (*ContentParser, error) { 37 cp, err := newContentParser(opt, lrp.ri) 38 if err != nil { 39 err = lrp.fset.Error(err) // attempt at improving error; these are ruleindex errors 40 return nil, err 41 } 42 return cp, nil 43 } 44 45 //---------- 46 47 func (lrp *Lrparser) SetStringRule(name string, s string) error { 48 if s == "" { 49 return fmt.Errorf("empty string") 50 } 51 r := &StringRule{} 52 r.runes = []rune(s) 53 return lrp.ri.setDefRule(name, r) 54 } 55 func (lrp *Lrparser) SetBoolRule(name string, v bool) error { 56 return lrp.ri.setBoolRule(name, v) 57 } 58 func (lrp *Lrparser) SetFuncRule(name string, parseOrder int, fn PStateParseFn) error { 59 return lrp.ri.setFuncRule(name, parseOrder, fn) 60 } 61 62 //---------- 63 64 func (lrp *Lrparser) MustGetStringRule(name string) string { 65 if s, err := lrp.GetStringRule(name); err != nil { 66 panic(err) 67 } else { 68 return s 69 } 70 } 71 func (lrp *Lrparser) GetStringRule(name string) (string, error) { 72 r, ok := lrp.ri.get(name) 73 if !ok { 74 return "", fmt.Errorf("rule not found: %v", name) 75 } 76 dr, ok := r.(*DefRule) 77 if !ok { 78 return "", fmt.Errorf("not a defrule: %v", r) 79 } 80 sr, ok := dr.onlyChild().(*StringRule) 81 if !ok { 82 return "", fmt.Errorf("expecting stringrule: %v", dr.onlyChild()) 83 } 84 return string(sr.runes), nil 85 }