Henning Schröder avatar Henning Schröder committed 4f80473

signature tokenizer/parser

Comments (0)

Files changed (1)

pycode/stubgen.py

     recv(buffersize[, flags]) -> data
     recv_into(buffer, [nbytes[, flags]]) -> nbytes_read
     sendto(data[, flags], address) -> count
+    trunc(x:Real) -> Integral
+    sinh(x)
+    log(x[, base])
+    hypot(x, y)
+    factorial(x) -> Integral
+    foo(arg=None) -> str
     """
     
     def tokenize(self, s):
+        s = s.strip()
         pos = 0
         buf = ""
         state = 0
-        optional = False
+        optional = 0
+        ST_NORMAL = 0
+        ST_STRING = 1
+        string_start = -1
         while pos < len(s):
             char = s[pos]
-            if state == 0:
+            if state == ST_STRING:
+                yield "STRING", s[string_start:pos]
+                state = ST_NORMAL
+                pos += 1
+            elif state == ST_NORMAL:
                 if char == ",":
                     yield "COMMA", ","
+                    pos += 1
                 elif char in ('"', "'"):
-                    state = 1
+                    state = ST_STRING
+                    string_start = pos
+                    pos += 1
+                elif s.startswith("->", pos):
+                    yield "RETURNS", "->"
+                    pos += 2
                 elif char == "[":
-                    optional = True
-                elif char.upper() >= "A" and char.upper() <= "Z" or char == "_"
-            pos += 1
-    
+                    optional += 1
+                    pos += 1
+                elif char == "]":
+                    optional -= 1
+                    pos += 1
+                elif char == "(":
+                    pos += 1
+                    yield "LPAREN", "("
+                elif char == ")":
+                    pos += 1
+                    yield "RPAREN", ")"
+                elif char == ":":
+                    pos += 1
+                    yield "COLON", ":"
+                elif char == "=":
+                    pos += 1
+                    yield "EQUALS", "="
+                elif char == " ":
+                    pos += 1 # skip whitespace
+                else:
+                    ident = re.match("^([A-Za-z_][A-Za-z_0-9]*)", s[pos:])
+                    if ident:
+                        length = ident.end()
+                        yield "IDENT", s[pos:pos+length]
+                        pos += length
+                    else:
+                        yield "UNKNOWN", char
+                        pos += 1
+
+
+    def parse(self, s):
+        next_token = self.tokenize(s).next
+        args = []
+        returns = None
+        name = None
+        try:
+            token = next_token()
+        except StopIteration:
+            return
+        if token[0] != "IDENT":
+            return
+        name = token[1]
+        token = next_token()
+        if token[0] != "LPAREN":
+            return
+        while 1:
+            try:
+                token = next_token()
+            except StopIteration:
+                return
+            if token[0] == "RPAREN":
+                break
+            if token[0] == "IDENT":
+                args.append(token[1])
+        try:
+            token = next_token()
+        except StopIteration:
+            pass
+        if token[0] == "RETURNS":
+            try:
+                token = next_token()
+                if token[0] == "IDENT":
+                    returns = token[1]
+            except StopIteration:
+                pass
+        return name, args, returns
+                
+                        
+
 class StubCreator(object):
+
     
     def __init__(self, module_name):
         mod = __import__(module_name, {}, {}, [])
 if __name__ == "__main__":        
     #s = StubCreator("math")
     #s = StubCreator("PyQt4.QtGui")
-    s = StubCreator("_socket")
-    print s
+    #s = StubCreator("_socket")
+    #print s
+    sp = SignatureParser()
+    for line in sp.examples.splitlines():
+        print line.strip(), sp.parse(line)
+            
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.