summaryrefslogtreecommitdiff
path: root/Parser/asdl_c.py
diff options
context:
space:
mode:
authorEli Bendersky <eliben@gmail.com>2014-05-09 17:58:22 -0700
committerEli Bendersky <eliben@gmail.com>2014-05-09 17:58:22 -0700
commit5e3d338a741682e82adbb8c6978bf157b9d0d884 (patch)
tree26d58d2dec39a9f3d6a598b934f2add8e2be6e13 /Parser/asdl_c.py
parent732ac654c8a3e5f9048a53efaee7380e1775a630 (diff)
downloadcpython-git-5e3d338a741682e82adbb8c6978bf157b9d0d884.tar.gz
Issue #19655: Replace the ASDL parser carried with CPython
The new parser does not rely on Spark (which is now removed from our repo), uses modern 3.x idioms and is significantly smaller and simpler. It generates exactly the same AST files (.h and .c), so in practice no builds should be affected.
Diffstat (limited to 'Parser/asdl_c.py')
-rwxr-xr-xParser/asdl_c.py54
1 files changed, 25 insertions, 29 deletions
diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py
index d6086e68bf..a5e35d93fd 100755
--- a/Parser/asdl_c.py
+++ b/Parser/asdl_c.py
@@ -1,9 +1,6 @@
#! /usr/bin/env python
"""Generate C code from an ASDL description."""
-# TO DO
-# handle fields that have a type but no name
-
import os, sys
import asdl
@@ -14,12 +11,8 @@ MAX_COL = 80
def get_c_type(name):
"""Return a string for the C name of the type.
- This function special cases the default types provided by asdl:
- identifier, string, int.
+ This function special cases the default types provided by asdl.
"""
- # XXX ack! need to figure out where Id is useful and where string
- if isinstance(name, asdl.Id):
- name = name.value
if name in asdl.builtin_types:
return name
else:
@@ -144,7 +137,7 @@ class TypeDefVisitor(EmitVisitor):
class StructVisitor(EmitVisitor):
- """Visitor to generate typdefs for AST."""
+ """Visitor to generate typedefs for AST."""
def visitModule(self, mod):
for dfn in mod.dfns:
@@ -188,9 +181,6 @@ class StructVisitor(EmitVisitor):
self.visit(f, depth + 1)
self.emit("} %s;" % cons.name, depth)
self.emit("", depth)
- else:
- # XXX not sure what I want here, nothing is probably fine
- pass
def visitField(self, field, depth):
# XXX need to lookup field.type, because it might be something
@@ -198,7 +188,7 @@ class StructVisitor(EmitVisitor):
ctype = get_c_type(field.type)
name = field.name
if field.seq:
- if field.type.value in ('cmpop',):
+ if field.type == 'cmpop':
self.emit("asdl_int_seq *%(name)s;" % locals(), depth)
else:
self.emit("asdl_seq *%(name)s;" % locals(), depth)
@@ -253,7 +243,7 @@ class PrototypeVisitor(EmitVisitor):
name = f.name
# XXX should extend get_c_type() to handle this
if f.seq:
- if f.type.value in ('cmpop',):
+ if f.type == 'cmpop':
ctype = "asdl_int_seq *"
else:
ctype = "asdl_seq *"
@@ -437,7 +427,7 @@ class Obj2ModVisitor(PickleVisitor):
self.emit("", 0)
for f in t.fields:
self.visitField(f, t.name, sum=sum, depth=2)
- args = [f.name.value for f in t.fields] + [a.name.value for a in sum.attributes]
+ args = [f.name for f in t.fields] + [a.name for a in sum.attributes]
self.emit("*out = %s(%s);" % (t.name, self.buildArgs(args)), 2)
self.emit("if (*out == NULL) goto failed;", 2)
self.emit("return 0;", 2)
@@ -465,7 +455,7 @@ class Obj2ModVisitor(PickleVisitor):
self.emit("", 0)
for f in prod.fields:
self.visitField(f, name, prod=prod, depth=1)
- args = [f.name.value for f in prod.fields]
+ args = [f.name for f in prod.fields]
self.emit("*out = %s(%s);" % (name, self.buildArgs(args)), 1)
self.emit("return 0;", 1)
self.emit("failed:", 0)
@@ -487,8 +477,8 @@ class Obj2ModVisitor(PickleVisitor):
def isSimpleSum(self, field):
# XXX can the members of this list be determined automatically?
- return field.type.value in ('expr_context', 'boolop', 'operator',
- 'unaryop', 'cmpop')
+ return field.type in ('expr_context', 'boolop', 'operator',
+ 'unaryop', 'cmpop')
def isNumeric(self, field):
return get_c_type(field.type) in ("int", "bool")
@@ -960,7 +950,7 @@ static int exists_not_none(PyObject *obj, _Py_Identifier *id)
def visitProduct(self, prod, name):
if prod.fields:
- fields = name.value+"_fields"
+ fields = name+"_fields"
else:
fields = "NULL"
self.emit('%s_type = make_type("%s", &AST_type, %s, %d);' %
@@ -987,7 +977,7 @@ static int exists_not_none(PyObject *obj, _Py_Identifier *id)
def visitConstructor(self, cons, name, simple):
if cons.fields:
- fields = cons.name.value+"_fields"
+ fields = cons.name+"_fields"
else:
fields = "NULL"
self.emit('%s_type = make_type("%s", %s_type, %s, %d);' %
@@ -1170,7 +1160,7 @@ class ObjVisitor(PickleVisitor):
def set(self, field, value, depth):
if field.seq:
# XXX should really check for is_simple, but that requires a symbol table
- if field.type.value == "cmpop":
+ if field.type == "cmpop":
# While the sequence elements are stored as void*,
# ast2obj_cmpop expects an enum
self.emit("{", depth)
@@ -1249,12 +1239,15 @@ class ChainOfVisitors:
common_msg = "/* File automatically generated by %s. */\n\n"
-def main(srcfile):
+def main(srcfile, dump_module=False):
argv0 = sys.argv[0]
components = argv0.split(os.sep)
argv0 = os.sep.join(components[-2:])
auto_gen_msg = common_msg % argv0
mod = asdl.parse(srcfile)
+ if dump_module:
+ print('Parsed Module:')
+ print(mod)
if not asdl.check(mod):
sys.exit(1)
if INC_DIR:
@@ -1301,16 +1294,19 @@ if __name__ == "__main__":
INC_DIR = ''
SRC_DIR = ''
- opts, args = getopt.getopt(sys.argv[1:], "h:c:")
- if len(opts) != 1:
- sys.stdout.write("Must specify exactly one output file\n")
- sys.exit(1)
+ dump_module = False
+ opts, args = getopt.getopt(sys.argv[1:], "dh:c:")
for o, v in opts:
if o == '-h':
INC_DIR = v
if o == '-c':
SRC_DIR = v
- if len(args) != 1:
- sys.stdout.write("Must specify single input file\n")
+ if o == '-d':
+ dump_module = True
+ if INC_DIR and SRC_DIR:
+ print('Must specify exactly one output file')
+ sys.exit(1)
+ elif len(args) != 1:
+ print('Must specify single input file')
sys.exit(1)
- main(args[0])
+ main(args[0], dump_module)