Franck Pommereau

started to replace parser

This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
......@@ -177,7 +177,14 @@ class CodeGenVisitor (Visitor) :
def concat (cls, outfile, chunks) :
outfile.write("# Generated by cct\n"
"# Franck Pommereau (2018)\n"
"# Adapted from Atul Varma's c.py (Spring 2004)\n")
"# Adapted from Atul Varma's c.py (Spring 2004)\n\n")
outfile.write("#\n"
"# on computer start: call main and halt\n"
"#\n\n"
"IRQ0:\n"
" set R9 @main\n"
" call R9\n"
" halt\n")
for c in chunks :
s = c.curr_str.getvalue()
if s.strip() :
......@@ -194,13 +201,6 @@ class CodeGenVisitor (Visitor) :
outfile.write("\n#\n# string literals from file %r\n#\n\n"
% c.path)
outfile.write(s)
outfile.write("\n#\n"
"# call main\n"
"#\n\n"
"IRQ0:\n"
" set R9 @main\n"
" call R9\n"
" halt\n")
def _calc_function_var_addrs(self, symtab, last_fp_loc):
self._calc_function_arg_addrs(symtab)
......@@ -353,7 +353,7 @@ class CodeGenVisitor (Visitor) :
label_str = "_LC%d" % self.__str_literal_label
self.str_literal_dict[str] = label_str
str = str.replace('\n', '\\12')
str = str.replace('\n', '\\n')
self.str_literal_str.write("""%s:\n str "%s\\0"\n""" % (label_str, str))
self.__class__.__str_literal_label += 1
return label_str
......
......@@ -340,11 +340,9 @@ class SymtabVisitor(Visitor):
# TODO: might be best to just move this to the code
# generation phase, since this doesn't have anything to
# do with symbol table generation.
param_num = 0
for param in node.nodes:
for param_num, param in enumerate(node.nodes):
param.accept(self)
param.param_num = param_num
param_num += 1
def vTranslationUnit(self, node):
self.root_symtab = Symtab()
......
import pycparser
from . import cast
def _coord (node) :
if node.coord is not None :
return {"lineno" : node.coord.line,
"colno" : node.coord.column - 1,
"filename" : node.coord.file}
else :
return {}
class ast2ast (object) :
def __call__ (self, node) :
return getattr(self, "v" + node.__class__.__name__)(node)
# # This is the top of the AST, representing a single C file (a
# # translation unit in K&R jargon). It contains a list of
# # "external-declaration"s, which is either declarations (Decl),
# # Typedef or function definitions (FuncDef).
# #
# FileAST: [ext**]
def vFileAST (self, node) :
ret = cast.TranslationUnit(None, **_coord(node))
for _, child in node.children() :
ret.add(self(child))
return ret
# # name: the variable being declared
# # quals: list of qualifiers (const, volatile)
# # funcspec: list function specifiers (i.e. inline in C99)
# # storage: list of storage specifiers (extern, register, etc.)
# # type: declaration type (probably nested with all the modifiers)
# # init: initialization value, or None
# # bitsize: bit field size, or None
# #
# Decl: [name, quals, storage, funcspec, type*, init*, bitsize*]
def vDecl (self, node) :
typ = self(node.type)
ret = cast.Declaration(node.name, typ, **_coord(node))
ret.extern = "extern" in node.storage
ret.static = "static" in node.quals
return ret
# # A typedef declaration.
# # Very similar to Decl, but without some attributes
# #
# Typedef: [name, quals, storage, type*]
def vTypedef (self, node) :
raise NotImplementedError("typdef")
# # type <decl>(args)
# #
# FuncDecl: [args*, type*]
def vFuncDecl (self, node) :
return cast.FunctionType(self(node.args), self(node.type))
# # a list of comma separated function parameter declarations
# #
# ParamList: [params**]
def vParamList (self, node) :
pass
# # A base type declaration
# #
# TypeDecl: [declname, quals, type*]
def vTypeDecl (self, node) :
pass
# # Function definition: a declarator for the function name and
# # a body, which is a compound statement.
# # There's an optional list of parameter declarations for old
# # K&R-style definitions
# #
# FuncDef: [decl*, param_decls**, body*]
def vFuncDef (self, node) :
pass
# # ArrayDecl is a nested declaration of an array with the given type.
# # dim: the dimension (for example, constant 42)
# # dim_quals: list of dimension qualifiers, to support C99's allowing 'const'
# # and 'static' within the array dimension in function declarations.
# ArrayDecl: [type*, dim*, dim_quals]
# ArrayRef: [name*, subscript*]
# # op: =, +=, /= etc.
# #
# Assignment: [op, lvalue*, rvalue*]
# BinaryOp: [op, left*, right*]
# Break: []
# Case: [expr*, stmts**]
# Cast: [to_type*, expr*]
# # Compound statement in C99 is a list of block items (declarations or
# # statements).
# #
# Compound: [block_items**]
# # Compound literal (anonymous aggregate) for C99.
# # (type-name) {initializer_list}
# # type: the typename
# # init: InitList for the initializer list
# #
# CompoundLiteral: [type*, init*]
# # type: int, char, float, etc. see CLexer for constant token types
# #
# Constant: [type, value]
# Continue: []
# DeclList: [decls**]
# Default: [stmts**]
# DoWhile: [cond*, stmt*]
# # Represents the ellipsis (...) parameter in a function
# # declaration
# #
# EllipsisParam: []
# # An empty statement (a semicolon ';' on its own)
# #
# EmptyStatement: []
# # Enumeration type specifier
# # name: an optional ID
# # values: an EnumeratorList
# #
# Enum: [name, values*]
# # A name/value pair for enumeration values
# #
# Enumerator: [name, value*]
# # A list of enumerators
# #
# EnumeratorList: [enumerators**]
# # A list of expressions separated by the comma operator.
# #
# ExprList: [exprs**]
# # for (init; cond; next) stmt
# #
# For: [init*, cond*, next*, stmt*]
# # name: Id
# # args: ExprList
# #
# FuncCall: [name*, args*]
# Goto: [name]
# ID: [name]
# # Holder for types that are a simple identifier (e.g. the built
# # ins void, char etc. and typedef-defined types)
# #
# IdentifierType: [names]
# If: [cond*, iftrue*, iffalse*]
# # An initialization list used for compound literals.
# #
# InitList: [exprs**]
# Label: [name, stmt*]
# # A named initializer for C99.
# # The name of a NamedInitializer is a sequence of Nodes, because
# # names can be hierarchical and contain constant expressions.
# #
# NamedInitializer: [name**, expr*]
# PtrDecl: [quals, type*]
# Return: [expr*]
# # name: struct tag name
# # decls: declaration of members
# #
# Struct: [name, decls**]
# # type: . or ->
# # name.field or name->field
# #
# StructRef: [name*, type, field*]
# Switch: [cond*, stmt*]
# # cond ? iftrue : iffalse
# #
# TernaryOp: [cond*, iftrue*, iffalse*]
# Typename: [name, quals, type*]
# UnaryOp: [op, expr*]
# # name: union tag name
# # decls: declaration of members
# #
# Union: [name, decls**]
# While: [cond*, stmt*]
# Pragma: [string]
def parse (path, *cpp_args) :
ast = pycparser.parse_file(path, use_cpp=True, cpp_args=list(cpp_args))
return ast2ast()(ast)
if __name__ == "__main__" :
tree = parse(",test.c", "-DTTC")