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 convert(node *parser.Node) string { ret := "" switch node.Name { case "MethodDescriptor": ri := len(node.Children) - 1 ret += convert(node.Children[ri]) + " (" for i := range node.Children[:ri] { if i > 0 { ret += ", " } ret += convert(node.Children[i]) } ret += ")" return ret case "BaseType": fallthrough case "VoidDescriptor": return lut[node.Data()] case "Classname": return strings.Replace(node.Data(), "/", ".", -1) } for i := range node.Children { if ret != "" { ret += " " } ret += convert(node.Children[i]) } if node.Name == "ArrayType" { ret += "[]" } return ret }
func eval(node *parser.Node) string { switch node.Name { case "Env": name := eval(node.Children[0]) if ret := os.Getenv(name); ret == "" { return name + "_NOT_SET" } else { return ret } case "Folder": return filepath.Dir(eval(node.Children[0])) case "String", "NonOperation", "RecNonOp": return node.Data() case "Home": if u, err := user.Current(); err != nil { log4go.Warn("Couldn't lookup current user: %s", err) } else { return u.HomeDir } case "EXPAND_PATH", "RecOp": buf := bytes.NewBuffer(nil) for _, c := range node.Children { buf.WriteString(eval(c)) } return buf.String() } return "" }
func data(n *parser.Node) string { switch n.Name { default: return n.Data() case "InheritedName": return data(n.Children[1]) case "OptionalArgument": return data(n.Children[0]) } }
func (c *Net) variable(n *parser.Node) string { switch n.Name { case "Access": default: if len(n.Children) == 0 { return n.Data() } for _, child := range n.Children { if v := c.variable(child); v != "" { return v } } } return "" }
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 }
func (p *Pattern) CreateCaptureNodes(data string, pos int, d parser.DataSource, mo MatchObject, parent *parser.Node, cap Captures) { ranges := make([]text.Region, len(mo)/2) parentIndex := make([]int, len(ranges)) parents := make([]*parser.Node, len(parentIndex)) for i := range ranges { ranges[i] = text.Region{mo[i*2+0], mo[i*2+1]} if i < 2 { parents[i] = parent continue } r := ranges[i] for j := i - 1; j >= 0; j-- { if ranges[j].Covers(r) { parentIndex[i] = j break } } } for k, v := range cap { i64, err := strconv.ParseInt(k, 10, 32) i := int(i64) if err != nil || i >= len(parents) { continue } if ranges[i].A == -1 { continue } child := &parser.Node{Name: v.Name, Range: ranges[i], P: d} parents[i] = child if i == 0 { parent.Append(child) continue } var p *parser.Node for p == nil { i = parentIndex[i] p = parents[i] } p.Append(child) } }
func ToContentType(node *parser.Node) (ret content.Type) { if node.Name == "ArrayType" { ret.Flags |= content.FLAG_TYPE_ARRAY ret.Specialization = append(ret.Specialization, ToContentType(node.Children[0])) return } switch node.Name { case "BaseType": fallthrough case "VoidDescriptor": ret.Name.Relative = lut[node.Data()] ret.Name.Absolute = ret.Name.Relative case "Classname": ret.Name = ToContentFQN(node.Data()) default: return ToContentType(node.Children[0]) } return }
func typeresolve(td *TypeDef, node *parser.Node) (*content.Type, error) { switch n := node.Name; n { case "MethodCall": if methods, err := td.Methods(); err != nil { return nil, err } else { for _, method := range methods { if method.Name.Relative == node.Children[0].Data() { return &method.Returns[0].Type, nil } } } case "Identifier": if fields, err := td.Fields(); err != nil { return nil, err } else { for _, field := range fields { if field.Name.Relative == node.Data() { return &field.Type, nil } } } // Is it a Property then perhaps? name := "get_" + node.Data() if methods, err := td.Methods(); err != nil { return nil, err } else { for _, method := range methods { if method.Name.Relative == name { return &method.Returns[0].Type, nil } } } // TODO: could also be an inner class } // Found nothing. // TODO: Try parents return nil, fmt.Errorf("No such type found: %s, %s", td.Name(), node) }
func Eval(v *reflect.Value, node *parser.Node) (int, error) { switch node.Name { case "EXPRESSION": if l := len(node.Children); l != 2 { return 0, fmt.Errorf("Unexpected child length: %d, %s", l, node) } return Eval(v, node.Children[0]) case "DotIdentifier": curr := v.Type().Name() children := node.Children if len(children) > 0 { // The last one will be handled by the fallthrough instead children = node.Children[:len(node.Children)-1] } for _, child := range children { f := v.FieldByName(child.Data()) if !f.IsValid() { return 0, fmt.Errorf("No field by name %s in struct %s", node.Data(), curr) } v = &f } node = node.Children[len(node.Children)-1] fallthrough case "Identifier": if f := v.FieldByName(node.Data()); !f.IsValid() { return 0, fmt.Errorf("No field by name %s in struct %s", node.Data(), v) } else { switch f.Kind() { case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return int(f.Uint()), nil case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return int(f.Int()), nil case reflect.Bool: if f.Bool() { return 1, nil } else { return 0, nil } default: return 0, fmt.Errorf("Unexpected identifier kind: %v %v", f, f.Kind()) } } case "Constant": i, err := strconv.ParseInt(node.Data(), 0, 32) return int(i), err case "EndOfFile": return 0, nil default: if l := len(node.Children); l != 2 { return 0, fmt.Errorf("Unexpected child length: %d, %s", l, node) } if a, err := Eval(v, node.Children[0]); err != nil { return 0, err } else if b, err := Eval(v, node.Children[1]); err != nil { return 0, err } else { switch node.Name { case "Ne": if a != b { return 1, nil } else { return 0, nil } case "Eq": if a == b { return 1, nil } else { return 0, nil } case "Lt": if a < b { return 1, nil } else { return 0, nil } case "Gt": if a > b { return 1, nil } else { return 0, nil } case "Le": if a <= b { return 1, nil } else { return 0, nil } case "Ge": if a >= b { return 1, nil } else { return 0, nil } case "Add": return a + b, nil case "Sub": return a - b, nil case "Mul": return a * b, nil case "ShiftLeft": return int(uint(a) << uint(b)), nil case "ShiftRight": return int(uint(a) >> uint(b)), nil case "Mask": return a & b, nil case "AndNot": return a &^ b, nil default: return 0, fmt.Errorf("Unimplemented operation: %s", node.Name) } } } }
func Eval(v *reflect.Value, node *parser.Node) (int, error) { switch node.Name { case "EXPRESSION": if l := len(node.Children); l != 2 { return 0, fmt.Errorf("Unexpected child length: %d, %s", l, node) } return Eval(v, node.Children[0]) case "Identifier": if f := v.FieldByName(node.Data()); !f.IsValid() { return 0, fmt.Errorf("No field by name %s in struct %s", node.Data(), v) } else { switch f.Kind() { case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return int(f.Uint()), nil case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return int(f.Int()), nil default: return 0, fmt.Errorf("Unexpected identifier kind: %v %v", f, f.Kind()) } } case "Constant": i, err := strconv.ParseInt(node.Data(), 0, 32) return int(i), err case "EndOfFile": return 0, nil default: if l := len(node.Children); l != 2 { return 0, fmt.Errorf("Unexpected child length: %d, %s", l, node) } if a, err := Eval(v, node.Children[0]); err != nil { return 0, err } else if b, err := Eval(v, node.Children[1]); err != nil { return 0, err } else { switch node.Name { case "Eq": if a == b { return 1, nil } else { return 0, nil } case "Lt": if a < b { return 1, nil } else { return 0, nil } case "Gt": if a > b { return 1, nil } else { return 0, nil } case "Le": if a <= b { return 1, nil } else { return 0, nil } case "Ge": if a >= b { return 1, nil } else { return 0, nil } case "Add": return a + b, nil case "Sub": return a - b, nil case "Mul": return a * b, nil case "ShiftLeft": return int(uint(a) << uint(b)), nil case "ShiftRight": return int(uint(a) >> uint(b)), nil case "Mask": return a & b, nil case "AndNot": return a &^ b, nil default: return 0, fmt.Errorf("Unimplemented operation: %s", node.Name) } } } }