Source

LIME / lib / en2xml.awk

Full commit
#!/usr/bin/awk -f
##################################################################
# This AWK script performs translation of a simple language based
# on a sub-set English to XML files used in LIME
#
#Copyright (C) 2008 NXP Semiconductors B.V.
#
#This file is part of LIME.
#
#LIME is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License version 2
#as published by the Free Software Foundation; either version 2
#of the License, or (at your option) any later version.
#
#LIME is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with LIME.  If not, see <http://www.gnu.org/licenses/>.
##################################################################
func handle(s) {
if (s ~ /^take/) {
    Default[value["type"]]=value["f"]
    if (!value["f"]) Default[value["type"]]=target
} else if (s=="give") {
    delete Default[value["type"]]
} else if (s=="use-ns") {
    nstack[++nsp]=value["ns"] "_"
    Default[value["type"]]=value["f"]
} else if (s=="ban-ns") {
    delete nstack[nsp--]
    delete Default[value["type"]]
} else if (s ~ /^(use\.*|use-alias)$/) {
    value["sid"]=nstack[nsp] value["sid"]
    if (!value["id"]) value["id"]=value["sid"]
    if (!value["tag"]) value["tag"]=(value["stag"]=="node" ? "actor" : value["stag"])
    if (!value["xml"]) value["xml"]=Default["xml"]
    #if (!value["xml"]) fail("no Default value for xml")
    if (value["stag"] != "type" &&\
        value["stag"] != "core" &&\
	value["stag"] != "node" &&\
	value["stag"] !~ "fifo" &&\
	value["stag"] != "memory") fail(s ":don't understand this")
    if (value["id"] in db) fail(value["id"] " is already known")
    print "<" value["tag"],
      "xlink:type='locator'",
      "xlink:label='" value["id"] "'",
      "xlink:href='" value["xml"] "#" value["sid"] "'/>"
    db[value["id"]]=value["xml"] SUBSEP value["sid"]
    tag[value["id"]]=value["tag"]
} else if (s ~ /use-port\.*$/) {
    value["nid"]=nstack[nsp] value["nid"]
    if (!value["id"]) value["id"]=value["nid"] ":" value["pid"]
    		 else value["id"]=nstack[nsp] value["id"]
    if (!value["tag"]) value["tag"]="endpoint"
    if (!value["xml"]) value["xml"]=Default["xml"]
    #if (!value["xml"]) fail("no Default value for xml")
    if (value["ptag"] != "port" ||\
        value["ntag"] != "node") fail(s ":don't understand this:" value["ptag"] "," value["ntag"])
    if (value["id"] in db) fail(value["id"] " is already known")
    print "<" value["tag"],
      "xlink:type='locator'",
      "xlink:label='" value["id"] "'",
      "xlink:href='" value["xml"] "#" value["nid"] ":" value["pid"] "'/>"
    db[value["id"]]=value["nid"] SUBSEP value["pid"]
} else if (s ~ /^connect/) {
    value["id_out"]=nstack[nsp] value["id_out"]
    value["id_in"]=nstack[nsp] value["id_in"]
    #if (value["tag_in"] != "endpoint" ||\
    #    value["tag_out"] != "endpoint") fail("don't understand this")
    if (!value["id"]) value["id"]=value["id_out"] "_to_" value["id_in"]
    if (value["id"] in db) fail(value["id"] " is already known")
    db[value["id"]]=value["id"]
    print "<edge",
      "id='" value["id"] "'",
      "type='" value["type"] "'",
      "xlink:type='arc'",
      "xlink:from='" value["id_out"] "'",
      "xlink:to='" value["id_in"] "'>"
    if (split(db[value["id_out"]],fr,SUBSEP)!=2) fail("no info on endpoint " value["id_out"])
    if (split(db[value["id_in"]],to,SUBSEP)!=2) fail("no info on endpoint " value["id_in"])
    printf space(2) "<from-node id='%s' port-id='%s'/>\n",fr[1],fr[2]
    printf space(2) "<to-node id='%s' port-id='%s'/>\n",to[1],to[2]
    print "</edge>"
} else if (s=="port") {
   pdesc=append(pdesc,sprintf("<port id='%s' type='%s' size='%s' %s/>",
   		value["id"], value["tid"], value["size"],
		value["type"]=="input" ? "const='1'" : ""),"\n")
} else if (s ~ /^(clock|res)$/) {
   if (s=="res") value["tag"]=value["resource"]
   else if (value["tag"] != "core") fail("don't understand this")
   rdesc=append(rdesc,sprintf("<rtype "\
   			      "xlink:type='locator' "\
                              "xlink:label='_%s' "\
			      "xlink:href='%%s#%%s:%s'/>",
   		value["tag"],value["tag"]),"\n")
   if (s=="clock") rdesc=append(rdesc,sprintf("<resource "\
   			      "id='%%s:%s' clock='%s' "\
                              "xlink:type='resource' "\
			      "xlink:label='%s'/>",
   		value["tag"],value["freq"],value["tag"]),"\n")
   if (s=="res") rdesc=append(rdesc,sprintf("<resource "\
   			      "id='%%s:%s' amount='%s' "\
                              "xlink:type='resource' "\
			      "xlink:label='%s'/>",
   		value["tag"],value["amount"],value["tag"]),"\n")
   rdesc=append(rdesc,sprintf("<rtype-is xlink:type='arc' "\
                              "xlink:from='%s' "\
			      "xlink:to='_%s'/>",
   		value["tag"],value["tag"]),"\n")
   rdesc=append(rdesc,sprintf("<rinst-is xlink:type='arc' "\
                              "xlink:from='_%s' "\
			      "xlink:to='%s'/>",
   		value["tag"],value["tag"]),"\n")
} else if (s ~ /^define/) {
    if ((value["tag"] != "core" &&\
         value["tag"] != "memory" &&\
         value["tag"] != "node" &&\
	 value["tag"] != "actor")||\
        value["ttag"] != "type") fail("don't understand this")
    if (split(db[value["tid"]],ts,SUBSEP)!=2) fail("don't know about " value["ttag"] " " value["tid"])
    value["id"]=nstack[nsp] value["id"]
    if (!value["aid"]) value["aid"]=value["id"]
    		  else value["aid"]=nstack[nsp] value["aid"]
    print "<" value["tag"],
      "id='" value["id"] "'",
      "type='" value["tid"] "'",
      "xlink:type='resource'",
      "xlink:label='" value["aid"] "'>"
    if (value["tag"]=="node") {
    	print pdesc
	pdesc=""
    }
    if (value["tag"] ~ /^(core|memory)$/ ) {
    	printf rdesc "\n",
	             ts[1],ts[2],value["id"],
	             ts[1],ts[2],value["id"],
	             ts[1],ts[2],value["id"],
                     ts[1],ts[2],value["id"]
 
	rdesc=""
    }
    print "</" value["tag"] ">"
    if (value["tid"] in db); else fail("no info on " value["ttag"] " " value["tid"])
    printf "<inst-is xlink:type='arc' xlink:from='%s' xlink:to='%s'/>\n",
    	value["tid"],value["aid"]
    printf "<type-is xlink:type='arc' xlink:from='%s' xlink:to='%s'/>\n",
    	value["aid"],value["tid"]
} else if (s ~ /^(run|put)$/) {
    if ((value["tag"] != "actor" &&\
         value["tag"] !~ "fifo") ||\
        (value["ttag"] != "core" &&\
         value["ttag"] != "side" &&\
         value["ttag"] != "cores" &&\
	 value["ttag"] != "memory")) fail("don't understand this:" value["ttag"] " " value["tag"])
    if (value["tid"] in db); else fail("no info on " value["ttag"] " " value["tid"])
    if (value["id"] in db); else fail("no info on " value["tag"] " " value["id"])
    if (tag[value["tid"]] != value["ttag"]) fail(value["tid"] " is not " value["ttag"])
    print "<core-of-node",
      "xlink:type='arc'",
      "xlink:from='" value["id"] "'",
      "xlink:to='" value["tid"] "'/>"
    print "<node-of-core",
      "xlink:type='arc'",
      "xlink:from='" value["tid"] "'",
      "xlink:to='" value["id"] "'/>"
    #if (value["id"] in core) fail(value["id"] " already mapped to " core[value["id"]])
    core[value["id"]]=append(core[value["id"]],value["tid"])
    cores[value["id"],value["tid"]]=1
} else if (s ~ /^(needs.*|size)$/) {
    if(0) if ((value["tag"] != "actor" &&\
               value["tag"] !~ "fifo") ||\
        (value["type"] != "core" &&\
	 value["type"] != "memory" &&\
	 value["type"] != "icache" &&\
	 value["type"] != "dcache")) fail("don't understand this:" value["tag"] " " value["type"])
    if (value["id"] in db); else fail(value["tag"] " " value["id"] " not known")
    if (s=="size") {
    	value["type"]="FIFO_SIZE"
	value["quantity"]=value["size"]
	if (value["id"] in core); else fail(value["tag"] " " value["id"] " must be mapped first")
	value["tid"]=core[value["id"]]
    }
    if (split(db[value["tid"]],ts,SUBSEP)!=2) fail("don't know about " value["tid"])
    # TODO handle type refinement in case node is mapped on a specific core
    # and requires resources from a generic type
    if ((value["id"],value["tid"]) in cores); else fail(value["id"] " not mapped on " value["tid"])
    if ((value["tid"],value["type"]) in defined); else {
      printf "<resource "\
      	"xlink:type='locator' "\
      	"xlink:label='%s_%s' "\
      	"xlink:href='%s#%s:%s'/>\n",
      	value["tid"],value["type"],
      	ts[1],ts[2],value["type"]
      defined[value["tid"],value["type"]]=1
    }
    print "<requires",
      "xlink:type='arc'",
      "xlink:from='" value["id"] "'",
      "xlink:to='" value["tid"] "_" value["type"] "'",
      "resource='" value["type"] "'",
      "quantity='" value["quantity"] "'",
      attwrap("address",value["addr"]),
      "/>"
    print "<provides",
      "xlink:type='arc'",
      "xlink:from='" value["tid"] "_" value["type"] "'",
      "xlink:to='" value["id"] "'",
      "resource='" value["type"] "'",
      "quantity='" value["quantity"] "'",
      attwrap("address",value["addr"]),
      "/>"
}
}

BEGIN {
	pat[pats[++npat]="use-ns"]="use namespace $ns from $type $_ $f"
	pat[pats[++npat]="ban-ns"]="ban namespace $ns"
	pat[pats[++npat]="take"]="take $type $_ $f"
	pat[pats[++npat]="take."]="take $type $_"
	pat[pats[++npat]="give"]="give $type $_"
	pat[pats[++npat]="use-port"]="use $ptag $pid in $ntag $nid from $xml as $id $tag"
	pat[pats[++npat]="use-port...."]="use $ptag $pid in $ntag $nid from $xml as $id"
	pat[pats[++npat]="use-port."]="use $ptag $pid in $ntag $nid from $xml"
	pat[pats[++npat]="use-port.."]="use $ptag $pid in $ntag $nid as $id $tag"
	pat[pats[++npat]="use-port....."]="use $ptag $pid in $ntag $nid as $id"
	pat[pats[++npat]="use-port..."]="use $ptag $pid in $ntag $nid"
	pat[pats[++npat]="use"]="use $stag $sid from $xml as $id $tag"
	pat[pats[++npat]="use."]="use $stag $sid from $xml"
	pat[pats[++npat]="use.."]="use $stag $sid"
	pat[pats[++npat]="use..."]="use $stag $sid as $id $tag"
	pat[pats[++npat]="use...."]="use $stag $sid as $tag"
	pat[pats[++npat]="use-alias"]="use $stag $sid alias $id"
	pat[pats[++npat]="connect"]="connect $type $id $tag_out $id_out to $tag_in $id_in"
	pat[pats[++npat]="connect."]="connect $type $tag_out $id_out to $tag_in $id_in"
	pat[pats[++npat]="define"]="define $tag $id of $ttag $tid"
	pat[pats[++npat]="port"]="with $type port $id of $ttag $tid sized $size"
	pat[pats[++npat]="clock"]="on $freq $tag clock"
	pat[pats[++npat]="res"]="having $amount of $resource"
	pat[pats[++npat]="define-alias"]="define $tag $id alias $aid of $ttag $tid"
	pat[pats[++npat]="run"]="run $tag $id on $tid $ttag"
	pat[pats[++npat]="put"]="put $tag $id on $tid $ttag"
	pat[pats[++npat]="needs"]="$tag $id needs $quantity of $tid $type"
	pat[pats[++npat]="needs-at"]="$tag $id needs $quantity of $tid $type at address $addr"
	pat[pats[++npat]="size"]="$tag $id has size $size"
}

BEGIN {
	mat["'"]="'"; mat["\""]="\""; mat["`"]="`"
	mat["("]=")"; mat["{"]="}"; mat["<"]=">"; mat["["]="]"
}

{ for (i=1; i<=NF; i++) {
	if (!qu[1] && match($i,/^(["'{<\(\[])/,qu)) { #
		id=substr($i,2)
		if (match(id,mat[qu[1]] "$")) {
			id=substr(id,1,length(id)-1)
			delete qu
		} else continue
	} else if (qu[1] && match($i,mat[qu[1]] "$")) {
		id=append(id,substr($i,1,length($i)-1))
		delete qu
	} else 	id=$i

	if (id ~ /and/) continue

	stack[++sp]=id

	if (gsub(/[.][[:space:]]*$/,"",stack[sp])) while (sm=findmatch(sp)) {
		sp-=sm
		gsub(/[,:;][[:space:]]*/,"",stack[sp])
		if (DEBUG>1) {
		    print "sp=",sp >STDERR
		}
	}
  }
}

END {
	if (DEBUG) {
		print "sp",sp >STDERR
		for (i=1; i<=sp; i++) print "didn't understand:",stack[i] >STDERR
	}
}

func findmatch(sp, i,p,n,a,matching) {
	delete value
	for (p=1; p<=npat; p++) {
		n=split(pat[pats[p]],a)
		matching=1
		for (i=1; i<=n && matching; i++) if (gsub(/^\$/,"",a[i])) {
			value[a[i]]=stack[sp-n+i]	
		} else {
			if (tolower(stack[sp-n+i]) != tolower(a[i])) matching=0
			#if (!matching) print "!matching",stack[sp-n+i],a[i] >STDERR
		}
		if (!matching) { delete value; continue }

		if (DEBUG>1) {
		print "handling",pats[p],"n=" n >STDERR
		for (v in value) print v,value[v] >STDERR
		}

		handle(pats[p])
		return n
	}
	return 0
}

func dump(i) {
	for (i=1; i<=sp; i++) print i,stack[i] 
	sp=0
}
@include common.awk