summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README19
-rwxr-xr-xpp2cc.py42
2 files changed, 44 insertions, 17 deletions
diff --git a/README b/README
index 08fa293..3d3a774 100644
--- a/README
+++ b/README
@@ -8,6 +8,9 @@ Dependencies:
- pycparser - http://code.google.com/p/pycparser/
- PLY (Python Lex-Yacc) - http://www.dabeaz.com/ply/
+Recommended:
+- cpp - a C preprocessor
+
Python is often installed by default on Linux distributions. For Windows, you
probably need to run the installer from the above link. Extract the pycparser
ZIP file (see link above) and copy the pycparser subdirectory to the directory
@@ -16,7 +19,15 @@ the ply/ directory into the directory containing pp2cc. pp2cc is a console
program, you need to open a terminal (or cmd on Windows) to see compiler
messages.
-Usage: python pp2cc.py [options] filename..
+The cpp program is installed on most Linux distributions. If not, install a
+conforming cpp, say gcc (GNU C Compiler). On Windows, you might want to
+download mcpp from http://mcpp.sourceforge.net/. Put it in your %PATH% (or the
+directory containing pp2cc) and rename it to "cpp.exe". If you do not install
+a C preprocessor, you need to pass the --no-cpp option in order to skip the
+processing through cpp. You will not be able to use comments or macros in this
+case.
+
+Usage: pp2cc.py [options] filename..
Multiple input files can be specified, options can be specified before and
after filenames.
Options:
@@ -25,6 +36,10 @@ Options:
added.
--tree Instead of compiling the file into assembly, show the parse
tree.
+ -D name
+ -D name=definition This option is passed to the cpp program, and acts like
+ adding #define name or #define name definition respectively
+ --no-cpp Disable the use of the C Preprocessor
Conformance with the K&R interpretation of C and feature support
================================================================
@@ -118,4 +133,4 @@ Not supported by parser, use a dedicated preprocessor like cpp and enable
removal of comments. Example: cpp -P file.c
A13 Grammar
-Not checked \ No newline at end of file
+Not checked
diff --git a/pp2cc.py b/pp2cc.py
index c50bff2..a76cb7f 100755
--- a/pp2cc.py
+++ b/pp2cc.py
@@ -11,7 +11,7 @@ this license.
"""
import sys, re, os, operator
-from pycparser import c_parser, c_ast
+from pycparser import c_parser, c_ast, parse_file
from Asm import Asm
from Registers import Registers
from LinkedNode import LinkedNode
@@ -45,7 +45,6 @@ class Logger(object):
class Parse(object):
def __init__(self):
- self.parser = c_parser.CParser()
self.logger = Logger()
self.node = None
@@ -90,12 +89,9 @@ class Parse(object):
self.asm = Asm()
# watches which registers are used and which are not
self.registers = Registers()
- def loadFile(self, filename):
+ def loadFile(self, filename, use_cpp=True, cpp_args=[]):
"""Loads a file and parses the contents of it"""
- file = open(filename, 'r')
- source = file.read()
- file.close()
- self.node = self.parser.parse(source, filename=filename);
+ self.node = parse_file(filename, use_cpp=use_cpp, cpp_args=cpp_args);
def show(self):
self.node.show(showcoord=True)
def uniqLbl(self, labelname):
@@ -1274,7 +1270,9 @@ if __name__ == "__main__":
settings = {
"input_files": [],
"dump_parsed_files": False,
- "output_filename": ""
+ "output_filename": "",
+ "cpp_args": [],
+ "use_cpp": True
}
set_arg = None
@@ -1282,7 +1280,7 @@ if __name__ == "__main__":
class ArgumentError(Exception):
pass
def usage():
- print """Usage: python pp2cc.py [options] filename..
+ print """Usage: pp2cc.py [options] filename..
Multiple input files can be specified, options can be specified before and
after filenames.
Options:
@@ -1290,7 +1288,12 @@ Options:
input file from which the extension is removed, and .asm is
added.
--tree Instead of compiling the file into assembly, show the parse
- tree."""
+ tree.
+ -D name
+ -D name=definition This option is passed to the cpp program, and acts like
+ adding #define name or #define name definition respectively
+ --no-cpp Disable the use of the C Preprocessor
+ """
try:
for arg in sys.argv[1:]:
if not set_arg is None:
@@ -1298,10 +1301,13 @@ Options:
setting = settings[set_arg]
if isinstance(setting, str):
settings[set_arg] = arg
- elif isinstance(arg, list):
- settings.append(arg)
- elif isinstance(arg, bool):
+ elif isinstance(setting, list):
+ setting.append(arg)
+ elif isinstance(setting, bool):
raise NotImplementedError("Booleans cannot be set in options")
+ else:
+ raise ArgumentError("Invalid type for command line setting"
+ " '{}'".format(type(setting).__name__))
set_arg = None
elif len(arg):
# if the argument is an option
@@ -1310,6 +1316,11 @@ Options:
set_arg = "output_filename"
elif arg == "--tree":
settings["dump_parsed_files"] = True
+ elif arg == "-D":
+ settings["cpp_args"].append("-D")
+ set_arg = "cpp_args"
+ elif arg == "--no-cpp":
+ settings["use_cpp"] = False
elif arg == "-h" or arg == "--help" or arg == "--usage":
usage()
sys.exit(0)
@@ -1335,7 +1346,8 @@ Options:
parse = Parse()
for filename in settings["input_files"]:
- parse.loadFile(filename)
+ parse.loadFile(filename, use_cpp=settings["use_cpp"],
+ cpp_args=settings["cpp_args"])
if settings["dump_parsed_files"]:
parse.show()
else:
@@ -1350,5 +1362,5 @@ Options:
print "The output is written to", settings["output_filename"]
except c_parser.ParseError:
e = sys.exc_info()[1]
- print "Parse error:", str(e)
+ print "A fatal (syntax) error was found during parsing:", str(e)
sys.exit(1)