func (p *Pattern) CreateNode(data string, pos int, d parser.DataSource, mo MatchObject) *parser.Node { ret := parser.Node{Name: p.Name, Range: parser.Range{mo[0], mo[1]}, P: d} if p.Match.re != nil { p.CreateCaptureNodes(data, pos, d, mo, &ret, p.Captures) } else if p.Begin.re != nil { if len(p.BeginCaptures) > 0 { p.CreateCaptureNodes(data, pos, d, mo, &ret, p.BeginCaptures) } else { p.CreateCaptureNodes(data, pos, d, mo, &ret, p.Captures) } if p.End.re != nil { var ( found = false i, end int ) for i, end = ret.Range.End, len(data); i < len(data); { endmatch := p.End.Find(data, i) if endmatch != nil { end = endmatch[1] } else { if !found { // oops.. no end found at all, set it to the next line if e2 := strings.IndexRune(data[i:], '\n'); e2 != -1 { end = i + e2 } else { end = len(data) } break } else { end = i break } } if /*(endmatch == nil || (endmatch != nil && endmatch[0] != i)) && */ len(p.cachedPatterns) > 0 { // Might be more recursive patterns to apply BEFORE the end is reached pattern2, match2 := p.FirstMatch(data, i) if match2 != nil && ((endmatch == nil && match2[0] < end) || (endmatch != nil && (match2[0] < endmatch[0] || match2[0] == endmatch[0] && ret.Range.Start == ret.Range.End))) { found = true r := pattern2.CreateNode(data, i, d, match2) ret.Append(r) i = r.Range.End continue } } if endmatch != nil { if len(p.EndCaptures) > 0 { p.CreateCaptureNodes(data, i, d, endmatch, &ret, p.EndCaptures) } else { p.CreateCaptureNodes(data, i, d, endmatch, &ret, p.Captures) } } break } ret.Range.End = end } } ret.UpdateRange() return &ret }
func (lp *LanguageParser) Parse() (*parser.Node, error) { sdata := string(lp.data) rn := parser.Node{P: lp, Name: lp.l.ScopeName} defer func() { if r := recover(); r != nil { log4go.Error("Panic during parse: %v\n", r) log4go.Debug("%v", rn) } }() iter := maxiter for i := 0; i < len(sdata) && iter > 0; iter-- { pat, ret := lp.l.RootPattern.Cache(sdata, i) nl := strings.IndexAny(sdata[i:], "\n\r") if nl != -1 { nl += i } if ret == nil { break } else if nl > 0 && nl <= ret[0] { i = nl for i < len(sdata) && (sdata[i] == '\n' || sdata[i] == '\r') { i++ } } else { n := pat.CreateNode(sdata, i, lp, ret) rn.Append(n) i = n.Range.End } } rn.UpdateRange() if len(sdata) != 0 { lut := make([]int, len(sdata)+1) j := 0 for i := range sdata { lut[i] = j j++ } lut[len(sdata)] = len(lp.data) lp.patch(lut, &rn) } if iter == 0 { panic("reached maximum number of iterations") } return &rn, nil }