Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 2a70672 in mainline


Ignore:
Timestamp:
2009-09-15T19:59:18Z (11 years ago)
Author:
Martin Decky <martin@…>
Branches:
master
Children:
ee5b35a
Parents:
ea5f46d
Message:

more sophisticated ADL parser

Location:
contrib/arch
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • contrib/arch/hadlbppp.py

    rea5f46d r2a70672  
    3434import os
    3535
     36INC, POST_INC, BLOCK_COMMENT, LINE_COMMENT, SYSTEM, ARCH, HEAD, BODY, NULL, \
     37        INST, VAR, FIN, BIND, TO, SEEN_NL, IFACE, PROTOTYPE, PAR_LEFT, PAR_RIGHT, SIGNATURE, PROTOCOL = range(21)
     38
     39context = set()
     40interface = None
     41architecture = None
     42protocol = None
     43
    3644def usage(prname):
    3745        "Print usage syntax"
     
    121129        return result
    122130
    123 def parse_bp(base, root, inname, nested, outname, outf, indent):
     131def preproc_adl(raw, inarg):
     132        "Preprocess %% statements in ADL"
     133       
     134        return raw.replace("%%", inarg)
     135
     136def identifier(token):
     137        "Check whether the token is an identifier"
     138       
     139        if (len(token) == 0):
     140                return False
     141       
     142        for i, char in enumerate(token):
     143                if (i == 0):
     144                        if ((not char.isalpha()) and (char != "_")):
     145                                return False
     146                else:
     147                        if ((not char.isalnum()) and (char != "_")):
     148                                return False
     149       
     150        return True
     151
     152def descriptor(token):
     153        "Check whether the token is an interface descriptor"
     154       
     155        parts = token.split(":")
     156        if (len(parts) != 2):
     157                return False
     158       
     159        return (identifier(parts[0]) and identifier(parts[1]))
     160
     161def word(token):
     162        "Check whether the token is a word"
     163       
     164        if (len(token) == 0):
     165                return False
     166       
     167        for i, char in enumerate(token):
     168                if ((not char.isalnum()) and (char != "_") and (char != ".")):
     169                        return False
     170       
     171        return True
     172
     173def parse_bp(base, root, inname, nested, outname, indent):
    124174        "Parse Behavior Protocol"
    125175       
     
    134184                if (not os.path.isfile(path)):
    135185                        print "%s: Unable to include file %s" % (outname, path)
    136                         return True
    137                
    138                 inf = file(path, "r")
     186                        return ""
    139187        else:
    140                 inf = file(inname, "r")
     188                path = inname
    141189                nested_root = root
    142190       
     191        inf = file(path, "r")
    143192        tokens = preproc_bp(outname, split_tokens(inf.read(), ["\n", " ", "\t", "(", ")", "{", "}", "[", "]", "/*", "*/", "#", "*", ";", "+", "||", "|", "!", "?"], True, True))
    144193       
     194        output = ""
    145195        inc = False
    146         empty = True
    147196        comment = False
    148197        lcomment = False
     
    170219                        continue
    171220               
    172                 if (empty):
    173                         empty = False
    174                
    175221                if (inc):
    176                         outf.write("\n%s(" % tabs(indent))
    177                        
    178                         inc_empty = parse_bp(base, nested_root, token, True, outname, outf, indent + 1)
    179                         if (inc_empty):
    180                                 outf.write("\n%sNULL" % tabs(indent + 1))
    181                        
    182                         outf.write("\n%s)" % tabs(indent))
     222                        output += "\n%s(" % tabs(indent)
     223                       
     224                        bp = parse_bp(base, nested_root, token, True, outname, indent + 1)
     225                        if (bp.strip() == ""):
     226                                output += "\n%sNULL" % tabs(indent + 1)
     227                        else:
     228                                output += bp
     229                       
     230                        output += "\n%s)" % tabs(indent)
    183231                        inc = False
    184232                        continue
    185233               
    186234                if ((token == ";") or (token == "+") or (token == "||") or (token == "|")):
    187                         outf.write(" %s" % token)
     235                        output += " %s" % token
    188236                elif (token == "["):
    189237                        inc = True
     
    191239                        inc = False
    192240                elif (token == "("):
    193                         outf.write("\n%s%s" % (tabs(indent), token))
     241                        output += "\n%s%s" % (tabs(indent), token)
    194242                        indent += 1
    195243                elif (token == ")"):
    196                         if (indent == 0):
    197                                 print "%s: Too many closing parentheses" % outname
     244                        if (indent <= 0):
     245                                print "%s: Wrong number of parentheses" % outname
    198246                       
    199247                        indent -= 1
    200                         outf.write("\n%s%s" % (tabs(indent), token))
     248                        output += "\n%s%s" % (tabs(indent), token)
    201249                elif (token == "{"):
    202                         outf.write(" %s" % token)
     250                        output += " %s" % token
    203251                        indent += 1
    204252                elif (token == "}"):
    205                         if (indent == 0):
    206                                 print "%s: Too many closing parentheses" % outname
     253                        if (indent <= 0):
     254                                print "%s: Wrong number of parentheses" % outname
    207255                       
    208256                        indent -= 1
    209                         outf.write("\n%s%s" % (tabs(indent), token))
     257                        output += "\n%s%s" % (tabs(indent), token)
    210258                elif (token == "*"):
    211                         outf.write("%s" % token)
     259                        output += "%s" % token
    212260                elif ((token == "!") or (token == "?") or (token == "NULL")):
    213                         outf.write("\n%s%s" % (tabs(indent), token))
     261                        output += "\n%s%s" % (tabs(indent), token)
    214262                else:
    215                         outf.write("%s" % token)
     263                        output += "%s" % token
    216264       
    217265        inf.close()
    218266       
    219         return empty
    220 
    221 def parse_adl(base, root, inname, nested, outname, outf, indent):
     267        return output
     268
     269def parse_adl(base, root, inname, nested, indent):
    222270        "Parse Architecture Description Language"
    223271       
    224272        if (nested):
    225                 (infname, inarg) = inname.split("%")
    226                
    227                 if (infname[0:1] == "/"):
    228                         path = os.path.join(base, ".%s" % infname)
     273                parts = inname.split("%")
     274               
     275                if (len(parts) > 1):
     276                        inarg = parts[1]
     277                else:
     278                        inarg = "%%"
     279               
     280                if (parts[0][0:1] == "/"):
     281                        path = os.path.join(base, ".%s" % parts[0])
    229282                        nested_root = os.path.dirname(path)
    230283                else:
    231                         path = os.path.join(root, infname)
     284                        path = os.path.join(root, parts[0])
    232285                        nested_root = root
    233286               
    234287                if (not os.path.isfile(path)):
    235                         print "%s: Unable to include file %s" % (outname, path)
    236                         return True
    237                
    238                 inf = file(path, "r")
     288                        print "%s: Unable to include file %s" % (inname, path)
     289                        return ""
    239290        else:
    240291                inarg = "%%"
    241                 inf = file(inname, "r")
     292                path = inname
    242293                nested_root = root
    243294       
    244         tokens = split_tokens(inf.read(), ["\n", " ", "\t", "%%", "[", "]"], False, True)
    245        
    246         inc = False
    247         empty = True
    248         newline = True
    249         locindent = 0
     295        inf = file(path, "r")
     296       
     297        raw = preproc_adl(inf.read(), inarg)
     298        tokens = split_tokens(raw, ["\n", " ", "\t", "(", ")", "{", "}", "[", "]", "/*", "*/", "#", ";"], True, True)
     299        output = ""
    250300       
    251301        for token in tokens:
    252                 if (empty):
    253                         empty = False
    254                
    255                 if (inc):
    256                         if (token.find("%") != -1):
    257                                 parse_adl(base, nested_root, token, True, outname, outf, locindent)
     302               
     303                # Includes
     304               
     305                if (INC in context):
     306                        context.remove(INC)
     307                       
     308                        if (PROTOCOL in context):
     309                                protocol += parse_bp(base, nested_root, token, True, "xxx", indent).strip()
    258310                        else:
    259                                 parse_bp(base, nested_root, token, True, outname, outf, locindent)
    260                        
    261                         inc = False
    262                         continue
    263                
    264                 if (token == "\n"):
    265                         newline = True
    266                         locindent = 0
    267                         outf.write("\n%s" % tabs(indent))
    268                 elif (token == "\t"):
    269                         if (newline):
    270                                 locindent += 1
    271                         outf.write("%s" % token)
    272                 elif (token == "%%"):
    273                         newline = False
    274                         outf.write("%s" % inarg)
    275                 elif (token == "["):
    276                         newline = False
    277                         inc = True
    278                 elif (token == "]"):
    279                         newline = False
    280                         inc = False
     311                                output += "\n%s" % tabs(indent)
     312                                output += parse_adl(base, nested_root, token, True, indent).strip()
     313                       
     314                        context.add(POST_INC)
     315                        continue
     316               
     317                if (POST_INC in context):
     318                        if (token != "]"):
     319                                print "%s: Expected ]" % inname
     320                       
     321                        context.add(SEEN_NL)
     322                        context.remove(POST_INC)
     323                        continue
     324               
     325                # Comments and newlines
     326               
     327                if (BLOCK_COMMENT in context):
     328                        if (token == "*/"):
     329                                context.remove(BLOCK_COMMENT)
     330                       
     331                        continue
     332               
     333                if (LINE_COMMENT in context):
     334                        if (token == "\n"):
     335                                context.remove(LINE_COMMENT)
     336                       
     337                        continue
     338               
     339                # Any context
     340               
     341                if (token == "/*"):
     342                        context.add(BLOCK_COMMENT)
     343                        continue
     344               
     345                if (token == "#"):
     346                        context.add(LINE_COMMENT)
     347                        continue
     348               
     349                if (token == "["):
     350                        context.add(INC)
     351                        continue
     352               
     353                # Seen newline
     354               
     355                if (SEEN_NL in context):
     356                        context.remove(SEEN_NL)
     357                        if (token == "\n"):
     358                                output += "\n%s" % tabs(indent)
     359                                continue
    281360                else:
    282                         newline = False;
    283                         outf.write("%s" % token)
     361                        if (token == "\n"):
     362                                continue
     363               
     364                # "interface"
     365               
     366                if (IFACE in context):
     367                        if (NULL in context):
     368                                if (token != ";"):
     369                                        print "%s: Expected ;" % inname
     370                                else:
     371                                        output += "%s\n" % token
     372                               
     373                                context.remove(NULL)
     374                                context.remove(IFACE)
     375                                interface = None
     376                                continue
     377                       
     378                        if (BODY in context):
     379                                if (PROTOCOL in context):
     380                                        if (token == "{"):
     381                                                indent += 1
     382                                        elif (token == "}"):
     383                                                indent -= 1
     384                                       
     385                                        if (indent == 1):
     386                                                output += protocol.strip()
     387                                                protocol = None
     388                                               
     389                                                output += "\n%s" % token
     390                                               
     391                                                context.remove(PROTOCOL)
     392                                                context.remove(BODY)
     393                                                context.add(NULL)
     394                                        else:
     395                                                protocol += token
     396                                       
     397                                        continue
     398                               
     399                                if (PROTOTYPE in context):
     400                                        if (FIN in context):
     401                                                if (token != ";"):
     402                                                        print "%s: Expected ;" % inname
     403                                                else:
     404                                                        output += "%s" % token
     405                                               
     406                                                context.remove(FIN)
     407                                                context.remove(PROTOTYPE)
     408                                                continue
     409                                       
     410                                        if (PAR_RIGHT in context):
     411                                                if (token == ")"):
     412                                                        output += "%s" % token
     413                                                        context.remove(PAR_RIGHT)
     414                                                        context.add(FIN)
     415                                                else:
     416                                                        output += " %s" % token
     417                                               
     418                                                continue
     419                                       
     420                                        if (SIGNATURE in context):
     421                                                output += "%s" % token
     422                                                if (token == ")"):
     423                                                        context.remove(SIGNATURE)
     424                                                        context.add(FIN)
     425                                               
     426                                                context.remove(SIGNATURE)
     427                                                context.add(PAR_RIGHT)
     428                                                continue
     429                                       
     430                                        if (PAR_LEFT in context):
     431                                                if (token != "("):
     432                                                        print "%s: Expected (" % inname
     433                                                else:
     434                                                        output += "%s" % token
     435                                               
     436                                                context.remove(PAR_LEFT)
     437                                                context.add(SIGNATURE)
     438                                                continue
     439                                       
     440                                        if (not identifier(token)):
     441                                                print "%s: Method identifier expected" % inname
     442                                        else:
     443                                                output += "%s" % token
     444                                       
     445                                        context.add(PAR_LEFT)
     446                                        continue
     447                               
     448                                if (token == "}"):
     449                                        if (indent != 1):
     450                                                print "%s: Wrong number of parentheses" % inname
     451                                        else:
     452                                                indent = 0
     453                                                output += "\n%s" % token
     454                                       
     455                                        context.remove(BODY)
     456                                        context.add(NULL)
     457                                        continue
     458                               
     459                                if (token == "ipcarg_t"):
     460                                        output += "\n%s%s " % (tabs(indent), token)
     461                                        context.add(PROTOTYPE)
     462                                        continue
     463                               
     464                                if (token == "protocol:"):
     465                                        output += "\n%s%s" % (tabs(indent - 1), token)
     466                                        context.add(PROTOCOL)
     467                                        protocol = ""
     468                                        continue
     469                               
     470                                print "%s: Unknown token %s in interface" % (inname, token)
     471                                continue
     472                       
     473                        if (HEAD in context):
     474                                if (token == "{"):
     475                                        output += "%s" % token
     476                                        indent += 2
     477                                        context.remove(HEAD)
     478                                        context.add(BODY)
     479                                        continue
     480                               
     481                                if (token == ";"):
     482                                        output += "%s\n" % token
     483                                        context.remove(HEAD)
     484                                        context.remove(ARCH)
     485                                        context.discard(SYSTEM)
     486                                        continue
     487                               
     488                                if (not word(token)):
     489                                        print "%s: Expected word" % inname
     490                                else:
     491                                        output += "%s " % token
     492                               
     493                                continue
     494                       
     495                        if (not identifier(token)):
     496                                print "%s: Expected interface name" % inname
     497                        else:
     498                                interface = token
     499                                output += "%s " % token
     500                       
     501                        context.add(HEAD)
     502                        continue
     503               
     504                # "architecture"
     505               
     506                if (ARCH in context):
     507                        if (NULL in context):
     508                                if (token != ";"):
     509                                        print "%s: Expected ;" % inname
     510                                else:
     511                                        output += "%s\n" % token
     512                               
     513                                context.remove(NULL)
     514                                context.remove(ARCH)
     515                                context.discard(SYSTEM)
     516                                architecture = None
     517                                continue
     518                       
     519                        if (BODY in context):
     520                                if (BIND in context):
     521                                        if (FIN in context):
     522                                                if (token != ";"):
     523                                                        print "%s: Expected ;" % inname
     524                                                else:
     525                                                        output += "%s" % token
     526                                               
     527                                                context.remove(FIN)
     528                                                context.remove(BIND)
     529                                                continue
     530                                       
     531                                        if (VAR in context):
     532                                                if (not descriptor(token)):
     533                                                        print "%s: Expected second interface descriptor" % inname
     534                                                else:
     535                                                        output += "%s" % token
     536                                               
     537                                                context.add(FIN)
     538                                                context.remove(VAR)
     539                                                continue
     540                                       
     541                                        if (TO in context):
     542                                                if (token != "to"):
     543                                                        print "%s: Expected to" % inname
     544                                                else:
     545                                                        output += "%s " % token
     546                                               
     547                                                context.add(VAR)
     548                                                context.remove(TO)
     549                                                continue
     550                                       
     551                                        if (not descriptor(token)):
     552                                                print "%s: Expected interface descriptor" % inname
     553                                        else:
     554                                                output += "%s " % token
     555                                       
     556                                        context.add(TO)
     557                                        continue
     558                               
     559                                if (INST in context):
     560                                        if (FIN in context):
     561                                                if (token != ";"):
     562                                                        print "%s: Expected ;" % inname
     563                                                else:
     564                                                        output += "%s" % token
     565                                               
     566                                                context.remove(FIN)
     567                                                context.remove(INST)
     568                                                continue
     569                                       
     570                                        if (VAR in context):
     571                                                if (not identifier(token)):
     572                                                        print "%s: Expected instance name" % inname
     573                                                else:
     574                                                        output += "%s" % token
     575                                               
     576                                                context.add(FIN)
     577                                                context.remove(VAR)
     578                                                continue
     579                                       
     580                                        if (not identifier(token)):
     581                                                print "%s: Expected frame/architecture type" % inname
     582                                        else:
     583                                                output += "%s " % token
     584                                       
     585                                        context.add(VAR)
     586                                        continue
     587                               
     588                                if (token == "}"):
     589                                        if (indent != 1):
     590                                                print "%s: Wrong number of parentheses" % inname
     591                                        else:
     592                                                indent -= 1
     593                                                output += "\n%s" % token
     594                                       
     595                                        context.remove(BODY)
     596                                        context.add(NULL)
     597                                        continue
     598                               
     599                                if (token == "inst"):
     600                                        output += "\n%s%s " % (tabs(indent), token)
     601                                        context.add(INST)
     602                                        continue
     603                               
     604                                if (token == "bind"):
     605                                        output += "\n%s%s " % (tabs(indent), token)
     606                                        context.add(BIND)
     607                                        continue
     608                               
     609                                print "%s: Unknown token %s in architecture" % (inname, token)
     610                                continue
     611                       
     612                        if (HEAD in context):
     613                                if (token == "{"):
     614                                        output += "%s" % token
     615                                        indent += 1
     616                                        context.remove(HEAD)
     617                                        context.add(BODY)
     618                                        continue
     619                               
     620                                if (token == ";"):
     621                                        output += "%s\n" % token
     622                                        context.remove(HEAD)
     623                                        context.remove(ARCH)
     624                                        context.discard(SYSTEM)
     625                                        continue
     626                               
     627                                if (not word(token)):
     628                                        print "%s: Expected word" % inname
     629                                else:
     630                                        output += "%s " % token
     631                               
     632                                continue
     633                       
     634                        if (not identifier(token)):
     635                                print "%s: Expected architecture name" % inname
     636                        else:
     637                                architecture = token
     638                                output += "%s " % token
     639                       
     640                        context.add(HEAD)
     641                        continue
     642               
     643                # "system architecture"
     644               
     645                if (SYSTEM in context):
     646                        if (token != "architecture"):
     647                                print "%s: Expected architecture" % inname
     648                        else:
     649                                output += "%s " % token
     650                       
     651                        context.add(ARCH)
     652                        continue
     653               
     654                if (token == "interface"):
     655                        output += "\n%s " % token
     656                        context.add(IFACE)
     657                        continue
     658               
     659                if (token == "system"):
     660                        output += "\n%s " % token
     661                        context.add(SYSTEM)
     662                        continue
     663               
     664                if (token == "architecture"):
     665                        output += "\n%s " % token
     666                        context.add(ARCH)
     667                        continue
     668               
     669                print "%s: Unknown token %s" % (inname, token)
    284670       
    285671        inf.close()
    286672       
    287         return empty
    288 
    289 def open_bp(base, root, inname, outname):
    290         "Open Behavior Protocol file"
    291        
    292         outf = file(outname, "w")
    293        
    294         outf.write("### %s\n" % inname)
    295        
    296         empty = parse_bp(base, root, inname, False, outname, outf, 0)
    297         if (empty):
    298                 outf.write("NULL")
    299        
    300         outf.close()
     673        return output
    301674
    302675def open_adl(base, root, inname, outname):
    303676        "Open Architecture Description file"
    304677       
     678        context.clear()
     679        interface = None
     680        architecture = None
     681        protocol = None
     682       
     683        adl = parse_adl(base, root, inname, False, 0)
     684        if (adl.strip() == ""):
     685                adl = "/* Empty */\n"
     686       
     687        if (os.path.isfile(outname)):
     688                print "%s: File already exists, overwriting" % outname
     689       
    305690        outf = file(outname, "w")
    306        
    307         empty = parse_adl(base, root, inname, False, outname, outf, 0)
    308         if (empty):
    309                 outf.write("/* Empty */")
    310        
     691        outf.write(adl.strip())
    311692        outf.close()
    312693
     
    321702                        cname = canon.split("/")
    322703                       
    323                         filtered = False
    324                         while (not filtered):
    325                                 try:
    326                                         cname.remove(".")
    327                                 except (ValueError):
    328                                         filtered = True
    329                        
    330                         output_path = os.path.join(output, ".".join(cname))
    331                        
    332                         if (fcomp[-1] == ".bp"):
    333                                 open_bp(base, root, canon, output_path)
    334                         elif (fcomp[-1] == ".adl"):
     704                        if (fcomp[-1] == ".adl"):
     705                                output_path = os.path.join(output, cname[-1])
    335706                                open_adl(base, root, canon, output_path)
    336707               
  • contrib/arch/uspace/app/klog/klog.adl

    rea5f46d r2a70672  
    22        requires:
    33                naming_service ns;
    4                 [/uspace/lib/libc/requires%]
     4                [/uspace/lib/libc/requires]
    55        protocol:
    66                [/uspace/lib/libc/protocol] +
  • contrib/arch/uspace/srv/bd/rd/rd.adl

    rea5f46d r2a70672  
    33                bd bd;
    44        requires:
    5                 [/uspace/lib/libc/requires%]
     5                [/uspace/lib/libc/requires]
    66                ns ns;
    77                devmap_driver devmap_driver;
  • contrib/arch/uspace/srv/devmap/devmap.adl

    rea5f46d r2a70672  
    6161                devmap_client devmap_client;
    6262        requires:
    63                 [/uspace/lib/libc/requires%]
     63                [/uspace/lib/libc/requires]
    6464        protocol:
    6565                [devmap_server.bp]
  • contrib/arch/uspace/srv/fs/devfs/devfs.adl

    rea5f46d r2a70672  
    33                fs fs
    44        requires:
    5                 [/uspace/lib/libc/requires%]
     5                [/uspace/lib/libc/requires]
    66                vfs vfs;
    77                ns ns;
  • contrib/arch/uspace/srv/fs/fat/fat.adl

    rea5f46d r2a70672  
    33                fs fs
    44        requires:
    5                 [/uspace/lib/libc/requires%]
     5                [/uspace/lib/libc/requires]
    66                vfs vfs;
    77                ns ns;
  • contrib/arch/uspace/srv/fs/tmpfs/tmpfs.adl

    rea5f46d r2a70672  
    33                fs fs
    44        requires:
    5                 [/uspace/lib/libc/requires%]
     5                [/uspace/lib/libc/requires]
    66                vfs vfs;
    77                ns ns;
  • contrib/arch/uspace/srv/kbd/kbd.adl

    rea5f46d r2a70672  
    2929                kbd kbd;
    3030        requires:
    31                 [/uspace/lib/libc/requires%]
     31                [/uspace/lib/libc/requires]
    3232                event event;
    3333                ns ns;
  • contrib/arch/uspace/srv/loader/loader.adl

    rea5f46d r2a70672  
    3131                loader loader;
    3232        requires:
    33                 [/uspace/lib/libc/requires%]
     33                [/uspace/lib/libc/requires]
    3434                ns ns;
    3535        protocol:
  • contrib/arch/uspace/srv/pci/pci.adl

    rea5f46d r2a70672  
    1313                pci pci;
    1414        requires:
    15                 [/uspace/lib/libc/requires%]
     15                [/uspace/lib/libc/requires]
    1616                ns ns;
    1717        protocol:
  • contrib/arch/uspace/srv/vfs/vfs.adl

    rea5f46d r2a70672  
    9696                vfs vfs;
    9797        requires:
    98                 [/uspace/lib/libc/requires%]
     98                [/uspace/lib/libc/requires]
    9999                fs fs;
    100100                ns ns;
Note: See TracChangeset for help on using the changeset viewer.