From da2008c597efbbaf9d15393e974942db832a069b Mon Sep 17 00:00:00 2001 From: Greg Date: Thu, 18 Apr 2019 14:04:01 -0400 Subject: [PATCH] Function to print text version of a C TypeName. Fix bugs in Nest(), ZeroOrMore(), OneOrMore() and Objective-C Generics parsers. --- types/combinators.go | 14 +++++++++----- types/ctypes.go | 10 ++++------ types/main.go | 1 + types/node.go | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/types/combinators.go b/types/combinators.go index 865cf4a..b932c89 100644 --- a/types/combinators.go +++ b/types/combinators.go @@ -1,6 +1,7 @@ package types import ( + //"fmt" "regexp" ) @@ -180,13 +181,15 @@ func Seq(ps ...Parser) Parser { func Nest(ps ...Parser) Parser { dbg("Nest(%p)\n",ps) p := func(s string, n *Node) (string, *Node) { - s2,n2 := Seq(ps...)(s,n) + ret := NewNode("Nest") + s2,n2 := Seq(ps...)(s,ret) if n2 == nil { return s,nil } - ret := NewNode("Nest") + ocs := n2.Children + ret.Children = []*Node{} n3 := ret - for _,c := range n2.Children { + for _,c := range ocs { n3.AddChild(c) n3 = c } @@ -197,7 +200,7 @@ func Nest(ps ...Parser) Parser { //ZeroOrMore returns a sequence of zero or more nodes func ZeroOrMore(p Parser) Parser { - return func(s string, n *Node) (string, *Node) { + ret := func(s string, n *Node) (string, *Node) { ret := NewNode("ZeroOrMore") dbg("ZeroOrMore(%s %p) ret = %p\n",n.Kind,n,ret) var s2 string @@ -211,10 +214,11 @@ func ZeroOrMore(p Parser) Parser { } return s,n } + return Children(ret) } func OneOrMore(p Parser) Parser { - return Seq(p,Children(ZeroOrMore(p))) + return Seq(p,ZeroOrMore(p)) } func Parenthesized(p Parser) Parser { diff --git a/types/ctypes.go b/types/ctypes.go index 878c775..b980978 100644 --- a/types/ctypes.go +++ b/types/ctypes.go @@ -104,12 +104,10 @@ func Declarator(s string, n *Node) (string, *Node) { } func DirectDeclarator(s string, n *Node) (string, *Node) { - return NodeNamed("DirectDeclarator", - OneOf( + return OneOf( Identifier, Parenthesized(Declarator), // INCOMPLETE - ), )(s,n) } @@ -189,10 +187,10 @@ func Generic(s string, n *Node) (string, *Node) { } func GenericList(s string, n *Node) (string, *Node) { - return OneOf( - Seq(Generic,Lit(","),GenericList), + return ChildOf(NewNode("GenericList"),Seq( Generic, - )(s,n) + ZeroOrMore(Seq(Lit(","),Generic)), + ))(s,n) } func BareTypedefName(s string, n *Node) (string, *Node) { diff --git a/types/main.go b/types/main.go index 001e097..29cb05c 100644 --- a/types/main.go +++ b/types/main.go @@ -14,6 +14,7 @@ func dbg(f string, xs ...interface{}) { } } + func Parse(s string) *Node { _, n2 := TypeName(s,NewNode("AST")) return n2 diff --git a/types/node.go b/types/node.go index 9247742..f4ef7ff 100644 --- a/types/node.go +++ b/types/node.go @@ -67,3 +67,42 @@ func (n *Node) AddChild(c *Node) *Node { return n } +func (n *Node) Ctype() string { + if n == nil { + return "" + } + var ret strings.Builder + childStrings := func(n *Node) []string { + if n == nil { return []string{} } + ret := []string{} + for _,c := range n.Children { + if x := c.Ctype(); x != "" { + ret = append(ret, c.Ctype()) + } + } + return ret + } + switch n.Kind { + case "Parenthesized": + ret.WriteString("(" + strings.Join(childStrings(n)," ") + ")") + case "Function": + ret.WriteString("(" + strings.Join(childStrings(n),", ") + ")") + case "GenericList": + ret.WriteString("<" + strings.Join(childStrings(n),", ") + ">") + case "Array": + ret.WriteString("[" + strings.Join(childStrings(n)," ") + "]") + default: + ret.WriteString(n.Content) + cc := strings.Join(childStrings(n)," ") + if n.Content != "" && cc != "" { + ret.WriteString(" ") + } + ret.WriteString(cc) + } + s := ret.String() + s = strings.ReplaceAll(s," *","*") + s = strings.ReplaceAll(s," [","[") + s = strings.ReplaceAll(s,") (",")(") + return s +} +