Beispiel #1
0
func dumpDB(db *DB, tag string) (string, error) {
	var buf bytes.Buffer
	f := strutil.IndentFormatter(&buf, "\t")
	f.Format("---- %s%i\n", tag)
	for nm, tab := range db.root.tables {
		h := tab.head
		f.Format("%u%q: head %d, scols0 %q, scols %q%i\n", nm, h, cols2meta(tab.cols0), cols2meta(tab.cols))
		for h != 0 {
			rec, err := db.store.Read(nil, h, tab.cols...)
			if err != nil {
				return "", err
			}

			f.Format("record @%d: %v\n", h, rec)
			h = rec[0].(int64)
		}
		f.Format("%u")
		for i, v := range tab.indices {
			if v == nil {
				continue
			}

			xname := v.name
			cname := "id()"
			if i != 0 {
				cname = tab.cols0[i-1].name
			}
			f.Format("index %s on %s%i\n", xname, cname)
			it, _, err := v.x.Seek(nil)
			if err != nil {
				return "", err
			}

			for {
				k, v, err := it.Next()
				if err != nil {
					if err == io.EOF {
						break
					}

					return "", err
				}

				f.Format("%v: %v\n", k, v)
			}
			f.Format("%u")
		}
	}

	return buf.String(), nil
}
Beispiel #2
0
// String implements fmt.Stringer
func (l List) String() string {
	var b bytes.Buffer
	f := strutil.IndentFormatter(&b, "\t")
	for _, s := range l.l {
		switch s.(type) {
		case beginTransactionStmt:
			f.Format("%s\n%i", s)
		case commitStmt, rollbackStmt:
			f.Format("%u%s\n", s)
		default:
			f.Format("%s\n", s)
		}
	}
	return b.String()
}
Beispiel #3
0
func prettyPrint(w io.Writer, v interface{}) {
	if v == nil {
		return
	}

	f := strutil.IndentFormatter(w, "· ")

	defer func() {
		if e := recover(); e != nil {
			f.Format("\npanic: %v", e)
		}
	}()

	prettyPrint0(nil, f, "", "", v)
}
Beispiel #4
0
func _dump() {
	s := fmt.Sprintf("%#v", _parserResult)
	s = strings.Replace(s, "%", "%%", -1)
	s = strings.Replace(s, "{", "{%i\n", -1)
	s = strings.Replace(s, "}", "%u\n}", -1)
	s = strings.Replace(s, ", ", ",\n", -1)
	var buf bytes.Buffer
	strutil.IndentFormatter(&buf, ". ").Format(s)
	buf.WriteString("\n")
	a := strings.Split(buf.String(), "\n")
	for _, v := range a {
		if strings.HasSuffix(v, "(nil)") || strings.HasSuffix(v, "(nil),") {
			continue
		}

		fmt.Println(v)
	}
}
Beispiel #5
0
func main1(in string) (err error) {
	var out io.Writer
	if nm := *oOut; nm != "" {
		var f *os.File
		var e error
		if f, err = os.Create(nm); err != nil {
			return err
		}

		defer func() {
			if e1 := f.Close(); e1 != nil && err == nil {
				err = e1
			}
		}()
		w := bufio.NewWriter(f)
		defer func() {
			if e1 := w.Flush(); e1 != nil && err == nil {
				err = e1
			}
		}()
		buf := bytes.NewBuffer(nil)
		out = buf
		defer func() {
			var dest []byte
			if dest, e = format.Source(buf.Bytes()); e != nil {
				dest = buf.Bytes()
			}

			if _, e = w.Write(dest); e != nil && err == nil {
				err = e
			}
		}()
	}

	var rep io.Writer
	if nm := *oReport; nm != "" {
		f, err1 := os.Create(nm)
		if err1 != nil {
			return err1
		}

		defer func() {
			if e := f.Close(); e != nil && err == nil {
				err = e
			}
		}()
		w := bufio.NewWriter(f)
		defer func() {
			if e := w.Flush(); e != nil && err == nil {
				err = e
			}
		}()
		rep = w
	}

	var xerrors []byte
	if nm := *oXErrors; nm != "" {
		b, err1 := ioutil.ReadFile(nm)
		if err1 != nil {
			return err1
		}

		xerrors = b
	}

	p, err := y.ProcessFile(token.NewFileSet(), in, &y.Options{
		//NoDefault:   *oNoDefault,
		AllowConflicts: true,
		Closures:       *oClosures,
		LA:             *oLA,
		Reducible:      *oReducible,
		Report:         rep,
		Resolved:       *oResolved,
		XErrorsName:    *oXErrors,
		XErrorsSrc:     xerrors,
	})
	if err != nil {
		return err
	}

	if fn := *oXErrorsGen; fn != "" {
		f, err := os.OpenFile(fn, os.O_RDWR|os.O_CREATE, 0666)
		if err != nil {
			return err
		}

		b := bufio.NewWriter(f)
		if err := p.SkeletonXErrors(b); err != nil {
			return err
		}

		if err := b.Flush(); err != nil {
			return err
		}

		if err := f.Close(); err != nil {
			return err
		}
	}

	msu := make(map[*y.Symbol]int, len(p.Syms)) // sym -> usage
	for nm, sym := range p.Syms {
		if nm == "" || nm == "ε" || nm == "$accept" || nm == "#" {
			continue
		}

		msu[sym] = 0
	}
	var minArg, maxArg int
	for _, state := range p.Table {
		for _, act := range state {
			msu[act.Sym]++
			k, arg := act.Kind()
			if k == 'a' {
				continue
			}

			if k == 'r' {
				arg = -arg
			}
			minArg, maxArg = mathutil.Min(minArg, arg), mathutil.Max(maxArg, arg)
		}
	}
	su := make(symsUsed, 0, len(msu))
	for sym, used := range msu {
		su = append(su, symUsed{sym, used})
	}
	sort.Sort(su)

	// ----------------------------------------------------------- Prologue
	f := strutil.IndentFormatter(out, "\t")
	f.Format("// CAUTION: Generated file - DO NOT EDIT.\n\n")
	f.Format("%s", injectImport(p.Prologue))
	f.Format(`
type %[1]sSymType %i%s%u

type %[1]sXError struct {
	state, xsym int
}
`, *oPref, p.UnionSrc)

	// ---------------------------------------------------------- Constants
	nsyms := map[string]*y.Symbol{}
	a := make([]string, 0, len(msu))
	maxTokName := 0
	for sym := range msu {
		nm := sym.Name
		if nm == "$default" || nm == "$end" || sym.IsTerminal && nm[0] != '\'' && sym.Value > 0 {
			maxTokName = mathutil.Max(maxTokName, len(nm))
			a = append(a, nm)
		}
		nsyms[nm] = sym
	}
	sort.Strings(a)
	f.Format("\nconst (%i\n")
	for _, v := range a {
		nm := v
		switch nm {
		case "error":
			nm = *oPref + "ErrCode"
		case "$default":
			nm = *oPref + "Default"
		case "$end":
			nm = *oPref + "EofCode"
		}
		f.Format("%s%s = %d\n", nm, strings.Repeat(" ", maxTokName-len(nm)+1), nsyms[v].Value)
	}
	minArg-- // eg: [-13, 42], minArg -14 maps -13 to 1 so zero cell values -> empty.
	f.Format("\n%sMaxDepth = 200\n", *oPref)
	f.Format("%sTabOfs   = %d\n", *oPref, minArg)
	f.Format("%u)")

	// ---------------------------------------------------------- Variables
	f.Format("\n\nvar (%i\n")

	// Lex translation table
	f.Format("%sXLAT = map[int]int{%i\n", *oPref)
	xlat := make(map[int]int, len(su))
	var errSym int
	for i, v := range su {
		if v.sym.Name == "error" {
			errSym = i
		}
		xlat[v.sym.Value] = i
		f.Format("%6d: %3d, // %s (%dx)\n", v.sym.Value, i, v.sym.Name, msu[v.sym])
	}
	f.Format("%u}\n")

	// Symbol names
	f.Format("\n%sSymNames = []string{%i\n", *oPref)
	for _, v := range su {
		f.Format("%q,\n", v.sym.Name)
	}
	f.Format("%u}\n")

	// Reduction table
	f.Format("\n%sReductions = []struct{xsym, components int}{%i\n", *oPref)
	for _, rule := range p.Rules {
		f.Format("{%d, %d},\n", xlat[rule.Sym.Value], len(rule.Components))
	}
	f.Format("%u}\n")

	// XError table
	f.Format("\n%[1]sXErrors = map[%[1]sXError]string{%i\n", *oPref)
	for _, xerr := range p.XErrors {
		state := xerr.Stack[len(xerr.Stack)-1]
		xsym := -1
		if xerr.Lookahead != nil {
			xsym = xlat[xerr.Lookahead.Value]
		}
		f.Format("%[1]sXError{%d, %d}: \"%s\",\n", *oPref, state, xsym, xerr.Msg)
	}
	f.Format("%u}\n\n")

	// Parse table
	tbits := 32
	switch n := mathutil.BitLen(maxArg - minArg + 1); {
	case n < 8:
		tbits = 8
	case n < 16:
		tbits = 16
	}
	f.Format("%sParseTab = [%d][]uint%d{%i\n", *oPref, len(p.Table), tbits)
	nCells := 0
	var tabRow sortutil.Uint64Slice
	for si, state := range p.Table {
		tabRow = tabRow[:0]
		max := 0
		for _, act := range state {
			sym := act.Sym
			xsym, ok := xlat[sym.Value]
			if !ok {
				panic("internal error 001")
			}

			max = mathutil.Max(max, xsym)
			kind, arg := act.Kind()
			switch kind {
			case 'a':
				arg = 0
			case 'r':
				arg *= -1
			}
			tabRow = append(tabRow, uint64(xsym)<<32|uint64(arg-minArg))
		}
		nCells += max
		tabRow.Sort()
		col := -1
		if si%5 == 0 {
			f.Format("// %d\n", si)
		}
		f.Format("{")
		for i, v := range tabRow {
			xsym := int(uint32(v >> 32))
			arg := int(uint32(v))
			if col+1 != xsym {
				f.Format("%d: ", xsym)
			}
			switch {
			case i == len(tabRow)-1:
				f.Format("%d", arg)
			default:
				f.Format("%d, ", arg)
			}
			col = xsym
		}
		f.Format("},\n")
	}
	f.Format("%u}\n")
	fmt.Fprintf(os.Stderr, "Parse table entries: %d of %d, x %d bits == %d bytes\n", nCells, len(p.Table)*len(msu), tbits, nCells*tbits/8)
	if n := p.ConflictsSR; n != 0 {
		fmt.Fprintf(os.Stderr, "conflicts: %d shift/reduce\n", n)
	}
	if n := p.ConflictsRR; n != 0 {
		fmt.Fprintf(os.Stderr, "conflicts: %d reduce/reduce\n", n)
	}

	f.Format(`%u)

var %[1]sDebug = 0

type %[1]sLexer interface {
	Lex(lval *%[1]sSymType) int
	Errorf(format string, a ...interface{})
	Errors() []error
}

type %[1]sLexerEx interface {
	%[1]sLexer
	Reduced(rule, state int, lval *%[1]sSymType) bool
}

func %[1]sSymName(c int) (s string) {
	x, ok := %[1]sXLAT[c]
	if ok {
		return %[1]sSymNames[x]
	}

	return __yyfmt__.Sprintf("%%d", c)
}

func %[1]slex1(yylex %[1]sLexer, lval *%[1]sSymType) (n int) {
	n = yylex.Lex(lval)
	if n <= 0 {
		n = %[1]sEofCode
	}
	if %[1]sDebug >= 3 {
		__yyfmt__.Printf("\nlex %%s(%%#x %%d), %[4]s: %[3]s\n", %[1]sSymName(n), n, n, %[4]s)
	}
	return n
}

func %[1]sParse(yylex %[1]sLexer, parser *Parser) int {
	const yyError = %[2]d

	yyEx, _ := yylex.(%[1]sLexerEx)
	var yyn int
	parser.yylval = %[1]sSymType{}
	parser.yyVAL = %[1]sSymType{}
	yyS := parser.cache

	Nerrs := 0   /* number of errors */
	Errflag := 0 /* error recovery flag */
	yyerrok := func() { 
		if %[1]sDebug >= 2 {
			__yyfmt__.Printf("yyerrok()\n")
		}
		Errflag = 0
	}
	_ = yyerrok
	yystate := 0
	yychar := -1
	var yyxchar int
	var yyshift int
	yyp := -1
	goto yystack

ret0:
	return 0

ret1:
	return 1

yystack:
	/* put a state and value onto the stack */
	yyp++
	if yyp >= len(yyS) {
		nyys := make([]%[1]sSymType, len(yyS)*2)
		copy(nyys, yyS)
		yyS = nyys
		parser.cache = yyS
	}
	yyS[yyp] = parser.yyVAL
	yyS[yyp].yys = yystate

yynewstate:
	if yychar < 0 {
		yychar = %[1]slex1(yylex, &parser.yylval)
		var ok bool
		if yyxchar, ok = %[1]sXLAT[yychar]; !ok {
			yyxchar = len(%[1]sSymNames) // > tab width
		}
	}
	if %[1]sDebug >= 4 {
		var a []int
		for _, v := range yyS[:yyp+1] {
			a = append(a, v.yys)
		}
		__yyfmt__.Printf("state stack %%v\n", a)
	}
	row := %[1]sParseTab[yystate]
	yyn = 0
	if yyxchar < len(row) {
		if yyn = int(row[yyxchar]); yyn != 0 {
			yyn += %[1]sTabOfs
		}
	}
	switch {
	case yyn > 0: // shift
		yychar = -1
		parser.yyVAL = parser.yylval
		yystate = yyn
		yyshift = yyn
		if %[1]sDebug >= 2 {
			__yyfmt__.Printf("shift, and goto state %%d\n", yystate)
		}
		if Errflag > 0 {
			Errflag--
		}
		goto yystack
	case yyn < 0: // reduce
	case yystate == 1: // accept
		if %[1]sDebug >= 2 {
			__yyfmt__.Println("accept")
		}
		goto ret0
	}

	if yyn == 0 {
		/* error ... attempt to resume parsing */
		switch Errflag {
		case 0: /* brand new error */
			if %[1]sDebug >= 1 {
				__yyfmt__.Printf("no action for %%s in state %%d\n", %[1]sSymName(yychar), yystate)
			}
			msg, ok := %[1]sXErrors[%[1]sXError{yystate, yyxchar}]
			if !ok {
				msg, ok = %[1]sXErrors[%[1]sXError{yystate, -1}]
			}
			if !ok && yyshift != 0 {
				msg, ok = %[1]sXErrors[%[1]sXError{yyshift, yyxchar}]
			}
			if !ok {
				msg, ok = %[1]sXErrors[%[1]sXError{yyshift, -1}]
			}
			if !ok || msg == "" {
				msg = "syntax error"
			}
			// ignore goyacc error message
			yylex.Errorf("")
			Nerrs++
			fallthrough

		case 1, 2: /* incompletely recovered error ... try again */
			Errflag = 3

			/* find a state where "error" is a legal shift action */
			for yyp >= 0 {
				row := %[1]sParseTab[yyS[yyp].yys]
				if yyError < len(row) {
					yyn = int(row[yyError])+%[1]sTabOfs
					if yyn > 0 { // hit
						if %[1]sDebug >= 2 {
							__yyfmt__.Printf("error recovery found error shift in state %%d\n", yyS[yyp].yys)
						}
						yystate = yyn /* simulate a shift of "error" */
						goto yystack
					}
				}

				/* the current p has no shift on "error", pop stack */
				if %[1]sDebug >= 2 {
					__yyfmt__.Printf("error recovery pops state %%d\n", yyS[yyp].yys)
				}
				yyp--
			}
			/* there is no state on the stack with an error shift ... abort */
			if %[1]sDebug >= 2 {
				__yyfmt__.Printf("error recovery failed\n")
			}
			goto ret1

		case 3: /* no shift yet; clobber input char */
			if %[1]sDebug >= 2 {
				__yyfmt__.Printf("error recovery discards %%s\n", %[1]sSymName(yychar))
			}
			if yychar == %[1]sEofCode {
				goto ret1
			}

			yychar = -1
			goto yynewstate /* try again in the same state */
		}
	}

	r := -yyn
	x0 := %[1]sReductions[r]
	x, n := x0.xsym, x0.components
	yypt := yyp
	_ = yypt // guard against "declared and not used"

	yyp -= n
	if yyp+1 >= len(yyS) {
		nyys := make([]%[1]sSymType, len(yyS)*2)
		copy(nyys, yyS)
		yyS = nyys
		parser.cache = yyS
	}
	parser.yyVAL = yyS[yyp+1]

	/* consult goto table to find next state */
	exState := yystate
	yystate = int(%[1]sParseTab[yyS[yyp].yys][x])+%[1]sTabOfs
	/* reduction by production r */
	if %[1]sDebug >= 2 {
		__yyfmt__.Printf("reduce using rule %%v (%%s), and goto state %%d\n", r, %[1]sSymNames[x], yystate)
	}

	switch r {%i
`,
		*oPref, errSym, *oDlvalf, *oDlval)
	for r, rule := range p.Rules {
		if rule.Action == nil {
			continue
		}

		action := rule.Action.Values
		if len(action) == 0 {
			continue
		}

		if len(action) == 1 {
			part := action[0]
			if part.Type == parser.ActionValueGo {
				src := part.Src
				src = src[1 : len(src)-1] // Remove lead '{' and trail '}'
				if strings.TrimSpace(src) == "" {
					continue
				}
			}
		}

		components := rule.Components
		typ := rule.Sym.Type
		max := len(components)
		if p1 := rule.Parent; p1 != nil {
			max = rule.MaxParentDlr
			components = p1.Components
		}
		f.Format("case %d: ", r)
		for _, part := range action {
			num := part.Num
			switch part.Type {
			case parser.ActionValueGo:
				f.Format("%s", part.Src)
			case parser.ActionValueDlrDlr:
				f.Format("parser.yyVAL.%s", typ)
				if typ == "" {
					panic("internal error 002")
				}
			case parser.ActionValueDlrNum:
				typ := p.Syms[components[num-1]].Type
				if typ == "" {
					panic("internal error 003")
				}
				f.Format("yyS[yypt-%d].%s", max-num, typ)
			case parser.ActionValueDlrTagDlr:
				f.Format("parser.yyVAL.%s", part.Tag)
			case parser.ActionValueDlrTagNum:
				f.Format("yyS[yypt-%d].%s", max-num, part.Tag)
			}
		}
		f.Format("\n")
	}
	f.Format(`%u
	}

	if yyEx != nil && yyEx.Reduced(r, exState, &parser.yyVAL) {
		return -1
	}
	goto yystack /* stack new state and value */
}

%[2]s
`, *oPref, p.Tail)
	_ = oNoLines //TODO Ignored for now
	return nil
}
Beispiel #6
0
func (t *Tree) dump() string {
	var buf bytes.Buffer
	f := strutil.IndentFormatter(&buf, "\t")

	num := map[interface{}]int{}
	visited := map[interface{}]bool{}

	handle := func(p interface{}) int {
		if isNil(p) {
			return 0
		}

		if n, ok := num[p]; ok {
			return n
		}

		n := len(num) + 1
		num[p] = n
		return n
	}

	var pagedump func(interface{}, string)
	pagedump = func(p interface{}, pref string) {
		if isNil(p) || visited[p] {
			return
		}

		visited[p] = true
		switch x := p.(type) {
		case *x:
			h := handle(p)
			n := 0
			for i, v := range x.x {
				if v.ch != nil || v.k != nil {
					n = i + 1
				}
			}
			f.Format("%sX#%d(%p) n %d:%d {", pref, h, x, x.c, n)
			a := []interface{}{}
			for i, v := range x.x[:n] {
				a = append(a, v.ch)
				if i != 0 {
					f.Format(" ")
				}
				f.Format("(C#%d K %v)", handle(v.ch), v.k)
			}
			f.Format("}\n")
			for _, p := range a {
				pagedump(p, pref+". ")
			}
		case *d:
			h := handle(p)
			n := 0
			for i, v := range x.d {
				if v.k != nil || v.v != nil {
					n = i + 1
				}
			}
			f.Format("%sD#%d(%p) P#%d N#%d n %d:%d {", pref, h, x, handle(x.p), handle(x.n), x.c, n)
			for i, v := range x.d[:n] {
				if i != 0 {
					f.Format(" ")
				}
				f.Format("%v:%v", v.k, v.v)
			}
			f.Format("}\n")
		}
	}

	pagedump(t.r, "")
	s := buf.String()
	if s != "" {
		s = s[:len(s)-1]
	}
	return s
}
Beispiel #7
0
func prettyPrint0(protect map[interface{}]struct{}, sf strutil.Formatter, prefix, suffix string, v interface{}) {
	if v == nil {
		return
	}

	switch x := v.(type) {
	case *Token:
		if x == nil {
			return
		}

		sf.Format("%s%v"+suffix, prefix, x.String())
		return
	}

	rt := reflect.TypeOf(v)
	rv := reflect.ValueOf(v)
	switch rt.Kind() {
	case reflect.Slice:
		if rv.Len() == 0 {
			return
		}

		sf.Format("%s[]%T{ // len %d%i\n", prefix, rv.Index(0).Interface(), rv.Len())
		for i := 0; i < rv.Len(); i++ {
			prettyPrint0(protect, sf, fmt.Sprintf("%d: ", i), ",\n", rv.Index(i).Interface())
		}
		sf.Format("%u}" + suffix)
	case reflect.Struct:
		sf.Format("%s%T{%i\n", prefix, v)
		for i := 0; i < rt.NumField(); i++ {
			f := rv.Field(i)
			if !f.CanInterface() {
				continue
			}

			prettyPrint0(protect, sf, fmt.Sprintf("%s: ", rt.Field(i).Name), ",\n", f.Interface())
		}
		sf.Format("%u}" + suffix)
	case reflect.Ptr:
		if rv.IsNil() {
			return
		}

		rvi := rv.Interface()
		if _, ok := protect[rvi]; ok {
			sf.Format("%s&%T{ /* recursive/repetitive pointee not shown */ }"+suffix, prefix, rv.Elem().Interface())
			return
		}

		if protect == nil {
			protect = map[interface{}]struct{}{}
		}
		protect[rvi] = struct{}{}
		prettyPrint0(protect, sf, prefix+"&", suffix, rv.Elem().Interface())
	case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int8:
		if v := rv.Int(); v != 0 {
			sf.Format("%s%v"+suffix, prefix, v)
		}
	case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint8:
		if v := rv.Uint(); v != 0 {
			sf.Format("%s%v"+suffix, prefix, rv.Uint())
		}
	case reflect.Bool:
		if v := rv.Bool(); v {
			sf.Format("%s%v"+suffix, prefix, rv.Bool())
		}
	case reflect.String:
		s := rv.Interface().(string)
		if s == "" {
			return
		}

		sf.Format("%s%q"+suffix, prefix, s)
	case reflect.Map:
		keys := rv.MapKeys()
		if len(keys) == 0 {
			return
		}

		var buf bytes.Buffer
		nf := strutil.IndentFormatter(&buf, "· ")
		var skeys []string
		for i, k := range keys {
			prettyPrint0(protect, nf, "", "", k.Interface())
			skeys = append(skeys, fmt.Sprintf("%s%10d", buf.Bytes(), i))
		}
		sort.Strings(skeys)
		sf.Format("%s%T{%i\n", prefix, v)
		for _, k := range skeys {
			si := strings.TrimSpace(k[len(k)-10:])
			k = k[:len(k)-10]
			n, _ := strconv.ParseUint(si, 10, 64)
			mv := rv.MapIndex(keys[n])
			prettyPrint0(protect, sf, fmt.Sprintf("%s: ", k), ",\n", mv.Interface())
		}
		sf.Format("%u}" + suffix)
	default:
		panic(fmt.Sprintf("prettyPrint: missing support for reflect.Kind == %v", rt.Kind()))
	}
}
Beispiel #8
0
func str(v interface{}) string {
	var buf bytes.Buffer
	f := strutil.IndentFormatter(&buf, ". ")
	g := func(interface{}) {}
	g = func(v interface{}) {
		switch x := v.(type) {
		case nil:
			f.Format("<nil>")
		case int:
			f.Format("'%c'\n", x)
		case string:
			f.Format("%q\n", x)
		case []*Act:
			f.Format("%T{%i\n", x)
			for _, v := range x {
				g(v)
			}
			f.Format("%u}\n")
		case *Act:
			f.Format("%T{%i\n", x)
			f.Format("Src: %q\n", x.Src)
			if x.Tok != 0 {
				f.Format("Tok: %s, Tag: %q, Num: %d\n", x.Tok, x.Tag, x.Num)
			}
			f.Format("%u}\n")
		case *Def:
			f.Format("%T{%i\n", x)
			f.Format("Rword: %s, ", x.Rword)
			f.Format("Tag: %q, ", x.Tag)
			f.Format("Nlist: %T{%i\n", x.Nlist)
			for _, v := range x.Nlist {
				g(v)
			}
			f.Format("%u}\n")
			f.Format("%u}\n")
		case *Nmno:
			var s string
			switch v := x.Identifier.(type) {
			case string:
				s = fmt.Sprintf("%q", v)
			case int:
				s = fmt.Sprintf("'%c'", v)
			}
			f.Format("%T{Identifier: %s, Number: %d}\n", x, s, x.Number)
		case *Prec:
			var s string
			switch v := x.Identifier.(type) {
			case string:
				s = fmt.Sprintf("%q", v)
			case int:
				s = fmt.Sprintf("'%c'", v)
			}
			f.Format("%T{%i\n", x)
			f.Format("Identifier: %s\n", s)
			g(x.Act)
			f.Format("%u}\n")
		case *Rule:
			f.Format("%T{%i\n", x)
			f.Format("Name: %q, ", x.Name)
			f.Format("Body: %T{%i\n", x.Body)
			for _, v := range x.Body {
				g(v)
			}
			f.Format("%u}\n")
			if x.Prec != nil {
				f.Format("Prec: ")
				g(x.Prec)
			}
			f.Format("%u}\n")
		case *Spec:
			f.Format("%T{%i\n", x)
			f.Format("Defs: %T{%i\n", x.Defs)
			for _, v := range x.Defs {
				g(v)
			}
			f.Format("%u}\n")
			f.Format("Rules: %T{%i\n", x.Rules)
			for _, v := range x.Rules {
				g(v)
			}
			f.Format("%u}\n")
			f.Format("Tail: %q\n", x.Tail)
			f.Format("%u}\n")
		default:
			f.Format("%s(str): %T(%#v)\n", todo, x, x)
		}
	}
	g(v)
	return buf.String()
}
Beispiel #9
0
Datei: y.go Projekt: postfix/y
func (y *y) report(w io.Writer) {
	f := strutil.IndentFormatter(w, "  ")
	if y.opts.debugSyms {
		var a []string
		max := 0
		for _, v := range y.syms {
			max = mathutil.Max(max, len(v.Name))
		}
		for _, v := range y.syms {
			a = append(a, fmt.Sprintf("%[2]*[1]s val %6[3]d, id %3[5]d, type %[4]q",
				v.Name, -max-1, v.Value, v.Type, v.id),
			)
		}
		sort.Strings(a)
		for _, v := range a {
			f.Format("%s\n", v)
		}
	}
	for si, state := range y.States {
		f.Format("state %d //", si)

		syms, la := state.Syms0()
		for _, s := range syms {
			switch {
			case s == nil:
				f.Format(" <?>")
			case !s.IsTerminal:
				f.Format(" <%s>", s)
			default:
				f.Format(" %s", s)
			}
		}
		if la != nil {
			f.Format(" [%s]", la)
		}
		f.Format("%i\n\n")

		switch {
		case y.opts.Closures:
			for _, item := range state.kernel.closure(y) {
				rule := y.Rules[item.rule()]
				f.Format("%v", item.dump(y))
				if y.opts.LA || item.next(y) == nil {
					switch i, ok := state.kernel.find(item); {
					case ok:
						f.Format("  [%s]", state.lookahead[i].dump(y))
					default:
						if i, ok := state.xitems.find(item); ok {
							f.Format("  [%s]", state.xla[i].dump(y))
						}
					}
				}
				if as := assocStr[rule.Associativity]; as != "" || rule.Precedence >= 0 {
					f.Format("  // assoc %s, prec %d", as, rule.Precedence)
				}
				f.Format("\n")
			}
		default:
			for i, item := range state.kernel {
				rule := y.Rules[item.rule()]
				f.Format("%v", item.dump(y))
				if y.opts.LA || item.dot() == len(rule.Components) {
					f.Format("  [%s]", state.lookahead[i].dump(y))
				}
				if as := assocStr[rule.Associativity]; as != "" || rule.Precedence >= 0 {
					f.Format("  // assoc %s, prec %d", as, rule.Precedence)
				}
				f.Format("\n")
			}
			for i, item := range state.xitems {
				rule := y.Rules[item.rule()]
				f.Format("%v  [%s]", item.dump(y), state.xla[i].dump(y))
				if as := assocStr[rule.Associativity]; as != "" || rule.Precedence >= 0 {
					f.Format(" // assoc %s, prec %d", as, rule.Precedence)
				}
				f.Format("\n")
			}
		}

		f.Format("%i\n")
		a := []string{}
		var w int
		for sym := range state.actions {
			w = mathutil.Max(w, len(sym.Name))
			a = append(a, sym.Name)
		}
		sort.Strings(a)
		type conflict struct {
			sym  *Symbol
			acts []action
		}
		var conflicts []conflict
		for _, nm := range a {
			sym := y.Syms[nm]
			acts := state.actions[sym]
			act := acts[0]
			f.Format("%-*s  %v", w, nm, act)
			if act.kind == 'r' {
				f.Format(" (%s)", y.Rules[act.arg].Sym.Name)
			}
			if len(acts) > 1 {
				conflicts = append(conflicts, conflict{sym, acts})
			}
			f.Format("\n")
		}
		a = a[:0]
		w = 0
		for sym := range state.gotos {
			w = mathutil.Max(w, len(sym.Name))
			a = append(a, sym.Name)
		}
		sort.Strings(a)
		for i, nm := range a {
			if i == 0 {
				f.Format("\n")
			}
			f.Format("%-*s  %v\n", w, nm, state.gotos[y.Syms[nm]])
		}
		for i, conflict := range conflicts {
			if i == 0 {
				if len(state.gotos) != 0 {
					f.Format("\n")
				}
			}
			sym := conflict.sym
			nm := sym.Name
			f.Format("conflict on %v", nm)
			for _, act := range conflict.acts {
				f.Format(", %s", act.String())
			}
			if as := assocStr[sym.Associativity]; as != "" || sym.Precedence >= 0 {
				f.Format(" // %v: assoc %s, prec %d", nm, assocStr[sym.Associativity], sym.Precedence)
			}
			f.Format("\n")
		}
		if len(state.resolved) != 0 {
			f.Format("\n")
		}
		for _, v := range state.resolved {
			f.Format("%s\n", v)
		}
		f.Format("%u%u\n")
	}
}
Beispiel #10
0
Datei: main.go Projekt: cznic/yy
func genASTExamples(spec *y.Parser) {
	f0 := bytes.NewBuffer(nil)
	f := strutil.IndentFormatter(f0, "\t")

	defer func() {
		file, err := os.Create(*oASTExamples)
		if err != nil {
			log.Fatal(err)
		}

		b, err := format.Source(f0.Bytes())
		if err != nil {
			b = f0.Bytes()
		}
		if _, err := file.Write(b); err != nil {
			log.Fatal(err)
		}

		if err := file.Close(); err != nil {
			log.Fatal(err)
		}
	}()

	fmt.Fprintf(f, caution)
	if copyright != "" {
		fmt.Fprintf(f, "%s\n", copyright)
	}
	fmt.Fprintf(f, `package %s

import (
	"fmt"
)
`, *oPkg)

	states := spec.Reductions()
	for _, sym := range nonTerminals {
		nm := sym.Name
		rules := sym.Rules
		w := len(strconv.Itoa(len(rules)))
	nextExample:
		for icase, rule := range rules {
			if isIgnored(rule.Sym) {
				continue
			}

			for _, c := range rule.Components {
				if c == "error" {
					continue nextExample
				}
			}

			src := ""
			for _, d := range ruleDirectives[rule] {
				if d.cmd != "example" {
					continue
				}

				src = unquote(d.arg)
				break
			}

			ruleNum := rule.RuleNum
			if src == "" {
				ilit = 0
				var r []string
				state, ok := states[ruleNum]
				if !ok { // State not reachable?
					continue nextExample
					//TODO- panic("internal error")
				}

				syms := spec.States[state[0]].Reduce0(rule)
				if len(syms) == 0 {
					log.Fatalf("rule %d not reduced in state %d", ruleNum, state[0])
				}

				for _, v := range syms {
					nm := v.Name
					if nm == "$end" {
						continue
					}

					if nm == "error" {
						continue nextExample
					}

					ls := v.LiteralString
					tokDirective := false
					for _, d := range tokenDirectives[nm] {
						if d.cmd != "token" {
							continue
						}

						ls = unquote(d.arg)
						tokDirective = true
						break
					}
					if ls == "" {
						if nm[0] == '\'' {
							ls = unquote(nm)
						} else {
							log.Fatalf("%v: no literal string for %s", fset.Position(v.Pos), nm)
						}
					}
					if tokDirective {
						s := strings.Replace(ls, "%%", "", -1)
						if strings.Contains(s, "%") {
							ls = fmt.Sprintf(ls, lits[ilit])
							ilit = (ilit + 1) % len(lits)
						}
					} else {
						ls = unquote(ls)
					}
					r = append(r, strings.Trim(ls, " \t\v\f"))
				}
				src = strings.Join(r, *oTokenSep)
			}

			switch {
			case icase == 0:
				f.Format("\nfunc Example%s() {%i\n", nm)
			default:
				f.Format("\nfunc Example%s_case%0*d() {%i\n", nm, w, icase)
			}
			switch len(normalizedBody(rule.Body)) {
			case 1:
				f.Format("fmt.Println(%s(%d, %q) == (%s)(nil))\n", *oExAST, ruleNum, src, nodes[nm].typ)
			default:
				f.Format("fmt.Println(%s(%d, %q))\n", *oExAST, ruleNum, src)
			}
			f.Format("// Output:\n%u}\n")
		}
	}
}
Beispiel #11
0
func (j *job) render(w io.Writer, start string) (err error) {
	f := strutil.IndentFormatter(w, "\t")
	f.Format(`%%{

//%s Put your favorite license here
		
// yacc source generated by ebnf2y[1]
// at %s
//
//  $ %s
//
// CAUTION: If this file is a Go source file (*.go), it was generated
// automatically by '$ go tool yacc' from a *.y file - DO NOT EDIT in that case!
// 
//   [1]: http://github.com/cznic/ebnf2y

package %s //%s real package name

//%s required only be the demo _dump function
import (
	"bytes"
	"fmt"
	"strings"

	"github.com/cznic/strutil"
)

%%}

%%union {
	item interface{} //%s insert real field(s)
}

`, todo, time.Now(), strings.Join(os.Args, " "), j.pkg, todo, todo, todo)
	j.term2name = map[string]string{}
	a := []string{}
	for name := range j.rep.Tokens {
		token := j.inventName(j.tPrefix+strings.ToUpper(name), "")
		j.term2name[name] = token
		a = append(a, token)
	}
	if len(a) != 0 {
		sort.Strings(a)
		for _, name := range a {
			f.Format("%%token\t%s\n", name)
		}
		f.Format("\n%%type\t<item> \t/*%s real type(s), if/where applicable */\n", todo)
		for _, name := range a {
			f.Format("\t%s\n", name)
		}
		f.Format("\n")
	}

	j.inventName(j.tPrefix+"TOK", "")
	a = a[:0]
	for lit := range j.rep.Literals {
		if len(lit) == 1 || toAscii(lit) != "" {
			continue
		}

		j.term2name[lit] = j.inventName(j.tPrefix+"TOK", "")
		a = append(a, lit)
	}
	if len(a) != 0 {
		for _, lit := range a {
			f.Format("%%token\t%s\t/*%s Name for %q */\n", j.term2name[lit], todo, lit)
		}
		f.Format("\n")
		f.Format("%%type\t<item> \t/*%s real type(s), if/where applicable */\n", todo)
		for _, lit := range a {
			f.Format("\t%s\n", j.term2name[lit])
		}
		f.Format("\n")
	}

	a = a[:0]
	for lit := range j.rep.Literals {
		nm := toAscii(lit)
		if len(lit) == 1 || nm == "" {
			continue
		}

		name := j.inventName(j.tPrefix+strings.ToUpper(nm), "")
		j.term2name[lit] = name
		a = append(a, name)
	}
	if len(a) != 0 {
		sort.Strings(a)
		for _, name := range a {
			f.Format("%%token %s\n", name)
		}
		f.Format("\n")
	}

	a = a[:0]
	for name := range j.rep.NonTerminals {
		a = append(a, name)
	}
	sort.Strings(a)
	f.Format("%%type\t<item> \t/*%s real type(s), if/where applicable */\n", todo)
	for _, name := range a {
		f.Format("\t%s\n", name)
	}
	f.Format("\n")

	f.Format("/*%s %%left, %%right, ... declarations */\n\n%%start %s\n\n%%%%\n\n", todo, start)

	rule := 0
	for _, name := range a {
		f.Format("%s:\n\t", name)
		expr := j.grm[name].Expr
		switch x := expr.(type) {
		case ebnf.Alternative:
			for i, v := range x {
				if i != 0 {
					f.Format("|\t")
				}
				rule++
				f.Format("%s\n\t{\n\t\t%s //%s %d\n\t}\n", j.str(v), j.ystr(v, name, start, i), todo, rule)
			}
		default:
			rule++
			f.Format("%s\n\t{\n\t\t%s //%s %d\n\t}\n", j.str(x), j.ystr(x, name, start, -1), todo, rule)
		}
		f.Format("\n")
	}

	f.Format(`%%%%

//%s remove demo stuff below

var _parserResult interface{}

type (%i
`, todo)

	for _, name := range a {
		f.Format("%s interface{}\n", name)
	}

	f.Format(`%u)
	
func _dump() {
	s := fmt.Sprintf("%%#v", _parserResult)
	s = strings.Replace(s, "%%", "%%%%", -1)
	s = strings.Replace(s, "{", "{%%i\n", -1)
	s = strings.Replace(s, "}", "%%u\n}", -1)
	s = strings.Replace(s, ", ", ",\n", -1)
	var buf bytes.Buffer
	strutil.IndentFormatter(&buf, ". ").Format(s)
	buf.WriteString("\n")
	a := strings.Split(buf.String(), "\n")
	for _, v := range a {
		if strings.HasSuffix(v, "(nil)") || strings.HasSuffix(v, "(nil),") {
			continue
		}
	
		fmt.Println(v)
	}
}

// End of demo stuff
`)
	return
}