$ template make_makesystem() $ $ // Generate the Makefile.am file $ output $basedir + '/Makefile.am' # This file was generated by SableCC (http://www.sablecc.org/). # set the include path found by configure INCLUDES = $$(all_includes) -I$libname # the library search path. lib_LTLIBRARIES = lib$libname.la lib${$libname}_la_LDFLAGS = lib${$libname}_la_SOURCES = node.cpp lexer.cpp typeinfo.cpp list.cpp analysis.cpp parser.cpp AM_CXXFLAGS = -Wall -Wno-unused noinst_PROGRAMS = test_lexer test_parser test_lexer_LDFLAGS = test_lexer_SOURCES = test_lexer.cpp test_lexer_LDADD = lib${$libname}.la test_parser_LDFLAGS = $$(GTK_LIBS) test_parser_CXXFLAGS = $$(GTK_CFLAGS) test_parser_SOURCES = test_parser.cpp test_parser_LDADD = lib${$libname}.la nobase_include_HEADERS = $libname/node.h $libname/token.h $libname/lexer.h $libname/prod.h $libname/list.h $libname/parser.h $libname/analysis.h $libname/all.h $ end output $ // Generate the Doxyfile file $ output $basedir + '/Doxyfile' # This file was generated by SableCC (http://www.sablecc.org/). # Doxyfile 1.3 #--------------------------------------------------------------------------- # General configuration options #--------------------------------------------------------------------------- PROJECT_NAME = $libname #PROJECT_NUMBER = 0.1 OUTPUT_DIRECTORY = docs OUTPUT_LANGUAGE = English USE_WINDOWS_ENCODING = NO EXTRACT_ALL = YES EXTRACT_PRIVATE = NO EXTRACT_STATIC = NO EXTRACT_LOCAL_CLASSES = YES HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO HIDE_FRIEND_COMPOUNDS = YES HIDE_IN_BODY_DOCS = NO BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = YES FULL_PATH_NAMES = NO STRIP_FROM_PATH = INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES SHORT_NAMES = NO HIDE_SCOPE_NAMES = YES VERBATIM_HEADERS = YES SHOW_INCLUDE_FILES = YES JAVADOC_AUTOBRIEF = YES MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = NO INHERIT_DOCS = YES INLINE_INFO = YES SORT_MEMBER_DOCS = YES DISTRIBUTE_GROUP_DOC = NO TAB_SIZE = 8 GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ALIASES = ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO SHOW_USED_FILES = YES #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_FORMAT = "$$file:$$line: $$text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = $libname FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.idl \ *.odl \ *.C \ *.H \ *.tlh \ *.diff \ *.patch \ *.moc \ *.xpm RECURSIVE = YES EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXAMPLE_PATH = EXAMPLE_PATTERNS = * EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = YES INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = NO REFERENCES_RELATION = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = YES COLS_IN_ALPHA_INDEX = 3 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = htmlapi HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = doxygen.css HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = YES CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO BINARY_TOC = NO TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NO TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = NO LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = YES PAPER_TYPE = a4 EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = YES USE_PDFLATEX = YES LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = NO XML_SCHEMA = XML_DTD = #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::addtions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES HIDE_UNDOC_RELATIONS = YES HAVE_DOT = YES CLASS_GRAPH = YES COLLABORATION_GRAPH = NO TEMPLATE_RELATIONS = YES INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES GRAPHICAL_HIERARCHY = YES DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = MAX_DOT_GRAPH_WIDTH = 1024 MAX_DOT_GRAPH_HEIGHT = 1024 MAX_DOT_GRAPH_DEPTH = 1000 GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::addtions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO CGI_NAME = search.cgi CGI_URL = DOC_URL = DOC_ABSPATH = BIN_ABSPATH = /usr/local/bin/ EXT_DOC_PATHS = $ end output $ // Generate the doxygen.css $ output $basedir + '/doxygen.css' /* This file was generated by SableCC (http://www.sablecc.org/). */ body, table { font-family: Verdana, sans-serif; font-size: 10pt; } H1 { text-align: center; } CAPTION { font-weight: bold } a:link { color: #000080; } A.qindex {} A.qindexRef {} A.el { text-decoration: none; font-weight: bold; line-height:1.2em; } A.elRef { font-weight: bold } A.code { text-decoration: none; font-weight: normal; color: #4444ee } A.codeRef { font-weight: normal; color: #4444ee } A:hover { background-color: #f2f2ff } DL.el { margin-left: -1cm } DIV.fragment { width: 100%; border: none; background-color: #eeeeee } DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } TD.md { background-color: #f2f2ff; font-weight: bold; } TD.mdname1 { background-color: #f2f2ff; font-weight: bold; color: #602020; } TD.mdname { background-color: #f2f2ff; font-weight: bold; color: #602020; width: 600px; } DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold } DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller } BODY { background: white } TD.indexkey { background-color: #eeeeff; font-weight: bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px } TD.indexvalue { background-color: #eeeeff; font-style: italic; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px } .keyword { color: #008000 } .keywordtype { color: #604020 } .keywordflow { color: #e08000 } .comment { color: #800000 } .preprocessor { color: #806020 } .stringliteral { color: #002080 } .charliteral { color: #008080 } pre { font-family: Lucida Console, Courier New, monospace; font-size: 10pt; } p { line-height:1.2em; } td.head { color: white; background: #BFBED0 url("b2w.jpg") top repeat-x; padding-left:1.2cm; } @@media print { td.head { color: black; background: white; } body, table { font-family: Georgia, serif; } } $ end output $ // Generate the README.parser $ output $basedir + '/README.parser' This is a parser generated by SableCC (http://www.sablecc.org/). Please read on for instruction on how to use. Installation ~~~~~~~~~~~~~ The build system currently has been tuned towards gcc/UNIX and the GNU auto system. Building on Windows/.NET might be possible. Some kind soul should provide me with a Makefile.win32 that people on Windows could use. To build the parser please do the following. For the freshly generated parser data you need at first to generate the GNU auto system. You should have all the auto packages installed in your system (automake, autoconf, libtool). For your convenience a small shell script called autogen.sh is provided. Run it. $$ . autogen.sh This will generate the configure script. Run it next: $$ CXXFLAGS="-O2" ./configure --disable-shared If everything worked you should now have the parser library and couple of test applications. You only need to run the autogen once. You can later reconfigure with different arguments and options. See ./configure --help. To install the library just type $$ make install That will place the libraries and include files into your system's directories (/usr/local by default) for usage. The include files are placed into a separate directory. Test applications/demos ~~~~~~~~~~~~~~~~~~~~~~~~ Test applications will also be built. Feel free to run them: $$ ./test_lexer $$ ./test_parser $$ ./test_parser -ansi If your system had GTK libraries a gtk tree viewer will be available: $$ ./test_parser -gtk API documentation/doxygen ~~~~~~~~~~~~~~~~~~~~~~~~~~ There is also a Doxyfile here. If you have doxygen installed you can use that to generate an API reference for the parser: $$ doxygen The documentation will be placed into docs/ directory. The workflow ~~~~~~~~~~~~~ You should generate the build system only once so that you could add new files into the Makefile.am and also into the include-path/all.h. You should be able to generate the parser files from modified grammar any time. Because of that you should never modify the parser generated .cpp and .h files. If you choose to regenerate the build system you have to reinsert your files into Makefile.am and include-path/all.h. The parser ~~~~~~~~~~~ The generated parser is designed to promote more ease of use than raw efficiency. For example the user mostly does not have to worry about memory problems as the entire system uses reference counting to track and free unused memory. The generated output was tuned to produce small sized libraries. Now if you look at the bloat that has been generated here and think "are you serious?!?" then let me tell you it can be much much worse. Compile times and memory requirements were also adressed in the design (gcc can grow extreamly large). Due to reference counting there is not much point in passing around pointers or references of nodes. In fact that may cause bugs in some circumstances. Of course every rule has exceptions but if you're not sure then do pass on just simple nodes. All nodes have to be created using Nodename::make(). .clone() can be used to make copies of trees. If a node goes out of scope it is deleted. Reference counting brings in one peculiarity in regards with the generated tree structure: node-s implementation of parent(). Circular referencing was avoided but the downside is that if you have only one node reference in your system then you can be sure its parent() is null. Downcasting. This is supported through special inline template methods: Node n = AMyNode::make(); // safe cast, returns null node if can't do AMyNode mn1 = n.cast(); // unsafe cast, you must be sure it's it // or risk problems AMyNode mn2 = n.unsafe_cast(); // testing if ( n.is() ) { .. } And do check out test_lexer.cpp and test_parser.cpp for an example. Currently UNICODE/wide characters are not supported. The end token is named TEOF and not EOF as other sablecc outputs to avoid C defined EOF-s conflict. $ end output $ // Generate the autogen.sh $ output $basedir + '/autogen.sh' #!/bin/sh touch COPYING touch NEWS touch README touch AUTHORS touch ChangeLog aclocal autoheader libtoolize -c -f automake -ac autoconf $ end output $ // Generate the configure.in $ output $basedir + '/configure.in' AC_INIT(configure.in) AM_CONFIG_HEADER(config.h) AM_INIT_AUTOMAKE($libname, 0.1) AC_LANG_CPLUSPLUS AC_PROG_CXX AM_PROG_LIBTOOL AC_PATH_PROG(GTK_CONFIG, gtk-config, no) AC_MSG_CHECKING(for GTK) no_gtk="" if test "$$GTK_CONFIG" = "no" ; then no_gtk=yes AC_MSG_RESULT([no]) else GTK_CFLAGS=`$$GTK_CONFIG $$gtk_config_args --cflags` GTK_CFLAGS="-DUSE_GTK $$GTK_CFLAGS" GTK_LIBS=`$$GTK_CONFIG $$gtk_config_args --libs` AC_MSG_RESULT([yes]) fi AC_SUBST(GTK_CFLAGS) AC_SUBST(GTK_LIBS) AC_OUTPUT(Makefile) $ end output $ end template