[llvm-commits] CVS: llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/Makefile developers-reference.xml fdl.xml kc2kc++.tex kpp-cook.xml kpp-intro.xml kpp-main.xml kpp-manual.xml kpp-rpn.xml
John Criswell
criswell at cs.uiuc.edu
Tue Apr 6 15:26:03 PDT 2004
Changes in directory llvm/test/Programs/MultiSource/Applications/kimwitu++/doc:
Makefile added (r1.1)
developers-reference.xml added (r1.1)
fdl.xml added (r1.1)
kc2kc++.tex added (r1.1)
kpp-cook.xml added (r1.1)
kpp-intro.xml added (r1.1)
kpp-main.xml added (r1.1)
kpp-manual.xml added (r1.1)
kpp-rpn.xml added (r1.1)
---
Log message:
Initial import of kimwitu++. This is based on version 2.3.8.
Kimwitu++ is analagous to a midterm exam for LLVM C++ programs. If LLVM
can handle kimwitu++, we're in pretty good shape.
---
Diffs of the changes: (+4146 -0)
Index: llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/Makefile
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/Makefile:1.1
*** /dev/null Tue Apr 6 15:25:32 2004
--- llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/Makefile Tue Apr 6 15:25:22 2004
***************
*** 0 ****
--- 1,101 ----
+ # Kimwitu++ documentation Makefile
+ # Copyright (c) 2000 Michael Piefel, Humboldt-University Berlin
+ # This is GPLed, but who would want it?
+
+ .PHONY: all pdf tex dvi force index clean html
+
+ XMLs := kpp-main.xml kpp-intro.xml kpp-manual.xml kpp-cook.xml kpp-rpn.xml
+ FIGs := syntaxtreex.fig simplify.fig fprintdot.fig
+ FIGDIR:= figures
+ IMGDIR:= imagesgen
+ DEST:=manual
+
+ EPSs := $(subst .fig,.eps,$(FIGs))
+ PDFs := $(subst .fig,.pdf,$(FIGs))
+ PNGs := $(subst .fig,.png,$(FIGs))
+ PSTEXs := $(addprefix $(IMGDIR)/, $(subst .fig,.tex,$(FIGs)))
+ FIGs := $(addprefix $(FIGDIR)/,$(FIGs))
+ EPSs := $(addprefix $(IMGDIR)/,$(EPSs))
+ PDFs := $(addprefix $(IMGDIR)/,$(PDFs))
+ PNGs := $(addprefix $(IMGDIR)/,$(PNGs))
+
+ all:
+ @echo "Call with pdf, tex or target document name"
+
+ pdf: $(DEST).pdf
+
+ tex: $(DEST).tex
+
+ dvi: $(DEST).dvi
+
+ html: $(DEST).html
+
+ force:
+ touch $(DEST).tex
+
+ index:
+ makeindex $(MIFLAGS) $(DEST)
+
+ $(DEST).dvi: $(DEST).tex $(EPSs) $(PSTEXs)
+ %.dvi: %.tex
+ latex $<
+
+
+ #%.tex: %.xml
+ # xsltproc formatters/docbook2tex.xsl $< > $@
+
+ .PRECIOUS: kpp-main.fo
+
+ %.fo: %.xml
+ xsltproc formatters/kimwitu++.xsl $< > $@
+
+ %.pdf: %.fo
+ # New FOP does not seem to need this adaption any more
+ # xsltproc formatters/fo2fop.xsl $< > $@-fop.fo
+ # fop $@-fop.fo $@
+ fop $< -pdf $@
+
+ $(DEST).tex: $(XMLs) formatters/docbook2tex.xsl
+ formatters/docbook2tex.sh $< $@
+
+ %.tex: %.xml formatters/docbook2tex.xsl
+ formatters/docbook2tex.sh $< $@
+
+ $(DEST).html: $(XMLs) $(PNGs)
+ formatters/docbook2html.sh $< $@
+
+ $(IMGDIR)/%.eps:$(FIGDIR)/%.fig
+ if [ ! -d $(IMGDIR) ] ; then \
+ mkdir $(IMGDIR) ; \
+ fi
+ fig2dev -L pstex -b1 $? $@
+
+ $(IMGDIR)/%.pdf:$(FIGDIR)/%.fig
+ if [ ! -d $(IMGDIR) ] ; then \
+ mkdir $(IMGDIR) ; \
+ fi
+ fig2dev -L pdftex -b1 $? $@
+
+ $(IMGDIR)/%.png:$(FIGDIR)/%.fig
+ if [ ! -d $(IMGDIR) ] ; then \
+ mkdir $(IMGDIR) ; \
+ fi
+ fig2dev -L png -b1 -S4 $? $@
+
+ $(IMGDIR)/%.tex:$(FIGDIR)/%.fig
+ if [ ! -d $(IMGDIR) ] ; then \
+ mkdir $(IMGDIR) ; \
+ fi
+ fig2dev -L pstex_t -p $(basename $@) $? $@
+
+ $(DEST).pdf: $(DEST).tex $(PDFs) $(PSTEXs)
+ %.pdf: %.tex
+ pdflatex $<
+
+ clean:
+ rm -f *.aux *.log *.toc *.dvi *.out *.idx *.ind *.loe *.ilg *.fot *.fo
+ rm -f .kkkk_eeee .kkkk_kkkk
+ rm -rf $(IMGDIR)
+
+ veryclean: clean
+ rm -f manual.tex manual.pdf manual.html
Index: llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/developers-reference.xml
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/developers-reference.xml:1.1
*** /dev/null Tue Apr 6 15:25:33 2004
--- llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/developers-reference.xml Tue Apr 6 15:25:22 2004
***************
*** 0 ****
--- 1,219 ----
+ <?xml version="1.0" encoding="iso-8859-1"?>
+ <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+ <!ENTITY app-fdl SYSTEM "fdl.xml">
+ ]>
+ <!-- "file:/usr/share/sgml/docbook/dtd/xml/4.1.2/docbookx.dtd" [ -->
+
+ <!-- This is the developers documentation for the term processor Kimwitu++ -->
+
+ <book lang="en" xml:lang="en">
+ <bookinfo>
+ <title>Kimwitu++ developers reference</title>
+ <author>
+ <firstname>Michael</firstname>
+ <surname>Piefel</surname>
+ <affiliation>
+ <orgname>Humboldt-University Berlin</orgname>
+ <orgdiv>Institute for Informatics</orgdiv>
+ </affiliation>
+ </author>
+ <edition>This document is $Id: developers-reference.xml,v 1.1 2004/04/06 20:25:22 criswell Exp $.</edition>
+ </bookinfo>
+
+ <toc/>
+
+ <!-- - - - - - - - - - - - - - - - Smart Pointers - - - - - - - - - - - - -->
+ <chapter><title>Smart Pointers</title>
+ <para>Smart pointers were implemented by Gerd Kurzbach. Their usage is not
+ straightforward, because that is made impossible by a few challenges.</para>
+ <sect1><title>Usage</title>
+ <qandaset>
+ <qandaentry>
+ <question>
+ <para>
+ What are the pointer types called?
+ </para>
+ </question>
+ <answer>
+ <para>
+ For a phylum called <replaceable>phylum</replaceable> there'll be the following
+ pointer types:<itemizedlist>
+ <listitem><para><replaceable>phylum</replaceable>, a simple C
+ pointer,</para></listitem>
+ <listitem><para>c_<replaceable>phylum</replaceable>, a simple constant C
+ pointer,</para></listitem>
+ <listitem><para><replaceable>phylum</replaceable>_ptr, the normal smart
+ pointer,</para></listitem>
+ <listitem><para>weak_<replaceable>phylum</replaceable>_ptr, the weak smart
+ pointer (does increment reference count),</para></listitem>
+ </itemizedlist>
+ </para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </sect1>
+ <sect1><title>Implementation</title>
+ <para>TODO</para>
+ </sect1>
+ </chapter>
+
+ <!-- - - - - - - - - - - - - - Kimwitu++ Source Management - - - - - - - - - - - - -->
+ <chapter><title>Kimwitu++ Source Management</title>
+ <sect1><title>Formatting the Kimwitu++ source code</title>
+ <sect2><title>The input (<abbrev>ie.</abbrev> Kimwitu++ text)</title>
+ <para>Tabs have a width of 8, in words eight, which means they are exactly 8 characters
+ wide, not two (2), not 4 (four), but 2<superscript>3</superscript> characters.</para>
+ <para>The indentation however should be four characters, <abbrev>ie.</abbrev>
+ 2<superscript>2</superscript>.</para>
+ <para>If you don't want to use tabs, but expand them to spaces, fine. However, recall it's
+ shorter. In a proper editor, it should be easy to get the desired behaviour,
+ <abbrev>eg.</abbrev> in Vim you can set <userinput>set tabstop=8 softtabstop=4
+ shiftwidth=4</userinput>.</para>
+ </sect2>
+ <sect2><title>The output (<abbrev>ie.</abbrev> generated text)</title>
+ <para>In general care should be taken to make the generated source code human readable.
+ It should always look according to the guidelines above.</para>
+ <para>Kimwitu++ features a smart printer. This means you don't have to worry about
+ spaces, tabs and alignment, the printer will do it automatically. It will even ignore
+ your spaces and tabs, so don't bother except for making the input more readable.
+ Occasionally the printer will fail (it's simple, and not a complete parser like
+ entity), so you have to use the following hints in the output strings:
+ <variablelist>
+ <varlistentry><term><userinput>\b</userinput></term>
+ <listitem><para>The printer likes to elide superfluous spaces. Sometimes spaces
+ are important (most notably to avoid nested template specifications with
+ <userinput>> ></userinput> being interpreted as the
+ <userinput>>></userinput> operator. The space following
+ <userinput>\b</userinput> will <emphasis>not</emphasis> be ignored.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry><term><userinput>\v</userinput></term>
+ <listitem><para>This causes the following text to be indented one additional level.
+ Mnemonic for <wordasword lang="de">vorwärts</wordasword>, which is German for
+ <wordasword>forward</wordasword>.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry><term><userinput>\r</userinput></term>
+ <listitem><para>This causes the following text to one level of indenting less.
+ Mnemonic for <wordasword lang="de">rückwärts</wordasword>, which is German for
+ <wordasword>backward</wordasword>.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+ </sect1>
+ <sect1><title>CVS</title>
+ <para>All changes which have an influence on the user should be marked with a
+ <literal>USER:</literal> prefix in the CSV change log message. This allows to collect
+ all user visible changes in the <filename>CHANGELOG</filename> file on release.</para>
+ </sect1>
+ </chapter>
+
+ <!-- - - - - - - - - - - - - - Uniq Phyla - - - - - - - - - - - - -->
+ <chapter><title>Uniq Phyla</title>
+ <sect1><title>Hash Sets</title>
+ <qandaset>
+ <qandaentry><question>
+ <para>Why are hash sets used?</para>
+ </question><answer>
+ <para>Performance. Red-Black trees are known to be always good, hash tables can have
+ poor performance. But usually they are fast. As very many casestrings are created
+ in common programs, we optimize for this.</para>
+ </answer></qandaentry>
+ <qandaentry><question>
+ <para>Why another level of indirection?</para>
+ </question><answer>
+ <para>Performance (compute hash only once).</para>
+ </answer></qandaentry>
+ <qandaentry><question>
+ <para>What are the preprocessor decisions for?</para>
+ </question><answer>
+ <para>Hash sets are not standardized yet.</para>
+ <para>There are different implementations. The three compilers I looked at (gcc and
+ Intel's compiler) use three different ways to implement it. (The two gccs only
+ differ in the location of the header file.)</para>
+ <para>The GNU compiler expects two functors: One doing a hash, one doing a test for
+ equality. Predefined tests are not suitable, of course.</para>
+ <para>The Intel compiler expects a single functor both unary and binary: A unary
+ function doing a hash, a binary function doing a test for lessness. Predefined
+ tests are not suitable, of course.</para>
+ <para>There is no knowing how other compilers might implement this. If a known
+ compiler is used, hash sets are employed by default, but can be deactivated by
+ defining DONT_USE_HASHSET. If an unknown compiler is used, hash sets are not
+ employed by default, but can be activated by defining USE_HASHSET (but then keep
+ fingers crossed we guess the right way to use them).</para>
+ </answer></qandaentry>
+ </qandaset>
+ </sect1>
+ </chapter>
+
+ <!-- - - - - - - - - - - - - - Patterns - - - - - - - - - - - - -->
+ <chapter><title>Patterns</title>
+ <sect1><title>Allowed patterns</title>
+ <para>Patterns over phyla are not allowed. Patterns over predefined operators (e. g. _Str)
+ are not allowed.</para>
+ <sect2><title>Patterns over predefined operators</title>
+ <para>It is not desirable to define new unparse and rewrite rules for the predefined phyla.
+ Predefined phyla are primitive, rewriting should not need to change them.
+ Different unparse behaviour can easily be implemented in the unparse function, should
+ it really be needed.</para>
+ <para>A pattern over a predefined operator might be useful in a with-statement.
+ However, this is not necessary or possible: All operators in a with-statement must
+ be of the same phylum, as patterns over phyla are (not yet) allowed.</para>
+ <para>Primitive phyla only have one operator, so a with-statement would have only one
+ alternative and is superfluous.</para>
+ </sect2>
+ <sect2><title>Patterns over phyla</title>
+ <para>Patterns over phyla are not allowed. This should be changed, considering the
+ following.</para>
+ <para>In a pattern over a phylum, there cannot be any references to subphyla.
+ Therefore, they are a bit limited. One possible exception could be lists and
+ abstract_list, as they always have two children.</para>
+ <para>Patterns over phyla are useless in with-statements. They can equally well be
+ implemented with a switch-statement over prod_sel().</para>
+ </sect2>
+ </sect1>
+ <sect1><title>Pattern sorting</title>
+ <para>The sorting of patterns is a difficult area. There are some obvious cases, and
+ some which are more twisted.</para>
+ <para>If, at a certain point, two patterns may match the current phylum, which one will
+ be chosen? Let us consider the following cases:</para>
+ <itemizedlist>
+ <listitem><para>A pattern that is truly more specific than another, i. e. all
+ terms that match it would also match the other, but not vice versa, should be
+ tested for before the other.</para></listitem>
+ <listitem><para>For two patterns that are disjunct, i. e. there cannot exist any
+ terms that match both, ordering does not matter.</para></listitem>
+ <listitem><para>Two patterns which cover the same terms should be considered an
+ error. Otherwise one would always be preferred over the other, probably not
+ what the user intended. This is not so when there is a guard condition on the
+ pattern (<userinput>provided</userinput>); it is difficult to decide for us what
+ the semantics of these are (except when there are two identical conditions,
+ verbatim).</para></listitem>
+ <listitem><para>For overlapping patterns, the situation is complex. There must
+ exist a pattern (or multiple patterns) that covers exactly the intersection.
+ In general, for each term, there must always be a most specific
+ pattern.</para>
+ <para>This condition is difficult to implement, and it is hoped to be rare. We
+ might focus on easy special cases (as <emphasis>one</emphasis> pattern
+ covering the intersection of <emphasis>two</emphasis> others) and give
+ warnings whenever we are not sure.</para></listitem>
+ </itemizedlist>
+ <para>In all other cases, the patterns have to be sorted, and a warning might be issued
+ to the user if that ordering is not obvious. Currently, pattern sorting in Kimwitu is
+ through an algorithm that is unintuitive. It frequently leads to an unexpected order.
+ A pattern is considered more specific if it is more specific further to the left; when
+ in doubt, the order of appearance in the input is taken.</para>
+ <para>To this end, Gerd proposed two different algorithms, both intuitive but already
+ fairly complex, which both resulted in different orderings. I believe this problem
+ cannot be solved.</para>
+ <para>Unfortunately, for some projects, Kimwitu++ issues many warnings, when order
+ doesn't matter or is indeed obvious. A way to silence this warnings selectively is on
+ the wishlist</para>
+ </sect1>
+ </chapter>
+
+ </book>
+ <!-- vim:set sw=2 ts=8: -->
Index: llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/fdl.xml
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/fdl.xml:1.1
*** /dev/null Tue Apr 6 15:25:33 2004
--- llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/fdl.xml Tue Apr 6 15:25:22 2004
***************
*** 0 ****
--- 1,466 ----
+ <appendix id="gfdl">
+ <title>GNU Free Documentation License</title>
+ <!-- - GNU Project - Free Software Foundation (FSF) -->
+ <!-- LINK REV="made" HREF="mailto:webmasters at gnu.org" -->
+
+
+ <!-- sect1>
+ <title>GNU Free Documentation License</title -->
+
+ <para>Version 1.1, March 2000</para>
+
+ <blockquote>
+ <para>Copyright © 2000 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.</para>
+ </blockquote>
+
+ <sect1 label="0">
+ <title>Preamble</title>
+
+ <para>The purpose of this License is to make a manual, textbook,
+ or other written document ‘free’ in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by
+ others.</para>
+
+ <para>This License is a kind of ‘copyleft’, which means that
+ derivative works of the document must themselves be free in the
+ same sense. It complements the GNU General Public License, which
+ is a copyleft license designed for free software.</para>
+
+ <para>We have designed this License in order to use it for manuals
+ for free software, because free software needs free documentation:
+ a free program should come with manuals providing the same
+ freedoms that the software does. But this License is not limited
+ to software manuals; it can be used for any textual work,
+ regardless of subject matter or whether it is published as a
+ printed book. We recommend this License principally for works
+ whose purpose is instruction or reference.</para>
+ </sect1>
+
+ <sect1 label="1">
+ <title>Applicability and Definitions</title>
+
+ <para>This License applies to any manual or other work that
+ contains a notice placed by the copyright holder saying it can be
+ distributed under the terms of this License. The ‘Document’,
+ below, refers to any such manual or work. Any member of the
+ public is a licensee, and is addressed as ‘you’.</para>
+
+ <para>A ‘Modified Version’ of the Document means any work
+ containing the Document or a portion of it, either copied
+ verbatim, or with modifications and/or translated into another
+ language.</para>
+
+ <para>A ‘Secondary Section’ is a named appendix or a front-matter
+ section of the Document that deals exclusively with the
+ relationship of the publishers or authors of the Document to the
+ Document's overall subject (or to related matters) and contains
+ nothing that could fall directly within that overall subject.
+ (For example, if the Document is in part a textbook of
+ mathematics, a Secondary Section may not explain any mathematics.)
+ The relationship could be a matter of historical connection with
+ the subject or with related matters, or of legal, commercial,
+ philosophical, ethical or political position regarding
+ them.</para>
+
+ <para>The ‘Invariant Sections’ are certain Secondary Sections
+ whose titles are designated, as being those of Invariant Sections,
+ in the notice that says that the Document is released under this
+ License.</para>
+
+ <para>The ‘Cover Texts’ are certain short passages of text that
+ are listed, as Front-Cover Texts or Back-Cover Texts, in the
+ notice that says that the Document is released under this
+ License.</para>
+
+ <para>A ‘Transparent’ copy of the Document means a
+ machine-readable copy, represented in a format whose specification
+ is available to the general public, whose contents can be viewed
+ and edited directly and straightforwardly with generic text
+ editors or (for images composed of pixels) generic paint programs
+ or (for drawings) some widely available drawing editor, and that
+ is suitable for input to text formatters or for automatic
+ translation to a variety of formats suitable for input to text
+ formatters. A copy made in an otherwise Transparent file format
+ whose markup has been designed to thwart or discourage subsequent
+ modification by readers is not Transparent. A copy that is not
+ ‘Transparent’ is called ‘Opaque’.</para>
+
+ <para>Examples of suitable formats for Transparent copies include
+ plain ASCII without markup, Texinfo input format, LaTeX input
+ format, SGML or XML using a publicly available DTD, and
+ standard-conforming simple HTML designed for human modification.
+ Opaque formats include PostScript, PDF, proprietary formats that
+ can be read and edited only by proprietary word processors, SGML
+ or XML for which the DTD and/or processing tools are not generally
+ available, and the machine-generated HTML produced by some word
+ processors for output purposes only.</para>
+
+ <para>The ‘Title Page’ means, for a printed book, the title page
+ itself, plus such following pages as are needed to hold, legibly,
+ the material this License requires to appear in the title page.
+ For works in formats which do not have any title page as such,
+ ‘Title Page’ means the text near the most prominent appearance of
+ the work's title, preceding the beginning of the body of the
+ text.</para>
+ </sect1>
+
+ <sect1 label="2">
+ <title>Verbatim Copying</title>
+
+ <para>You may copy and distribute the Document in any medium,
+ either commercially or noncommercially, provided that this
+ License, the copyright notices, and the license notice saying this
+ License applies to the Document are reproduced in all copies, and
+ that you add no other conditions whatsoever to those of this
+ License. You may not use technical measures to obstruct or
+ control the reading or further copying of the copies you make or
+ distribute. However, you may accept compensation in exchange for
+ copies. If you distribute a large enough number of copies you
+ must also follow the conditions in section 3.</para>
+
+ <para>You may also lend copies, under the same conditions stated
+ above, and you may publicly display copies.</para>
+ </sect1>
+
+ <sect1 label="3">
+ <title>Copying in Quantity</title>
+
+ <para>If you publish printed copies of the Document numbering more
+ than 100, and the Document's license notice requires Cover Texts,
+ you must enclose the copies in covers that carry, clearly and
+ legibly, all these Cover Texts: Front-Cover Texts on the front
+ cover, and Back-Cover Texts on the back cover. Both covers must
+ also clearly and legibly identify you as the publisher of these
+ copies. The front cover must present the full title with all
+ words of the title equally prominent and visible. You may add
+ other material on the covers in addition. Copying with changes
+ limited to the covers, as long as they preserve the title of the
+ Document and satisfy these conditions, can be treated as verbatim
+ copying in other respects.</para>
+
+ <para>If the required texts for either cover are too voluminous to
+ fit legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.</para>
+
+ <para>If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a
+ machine-readable Transparent copy along with each Opaque copy, or
+ state in or with each Opaque copy a publicly-accessible
+ computer-network location containing a complete Transparent copy
+ of the Document, free of added material, which the general
+ network-using public has access to download anonymously at no
+ charge using public-standard network protocols. If you use the
+ latter option, you must take reasonably prudent steps, when you
+ begin distribution of Opaque copies in quantity, to ensure that
+ this Transparent copy will remain thus accessible at the stated
+ location until at least one year after the last time you
+ distribute an Opaque copy (directly or through your agents or
+ retailers) of that edition to the public.</para>
+
+ <para>It is requested, but not required, that you contact the
+ authors of the Document well before redistributing any large
+ number of copies, to give them a chance to provide you with an
+ updated version of the Document.</para>
+ </sect1>
+
+ <sect1 label="4">
+ <title>Modifications</title>
+
+ <para>You may copy and distribute a Modified Version of the
+ Document under the conditions of sections 2 and 3 above, provided
+ that you release the Modified Version under precisely this
+ License, with the Modified Version filling the role of the
+ Document, thus licensing distribution and modification of the
+ Modified Version to whoever possesses a copy of it. In addition,
+ you must do these things in the Modified Version:</para>
+
+ <orderedlist numeration="upperalpha">
+ <listitem><para>Use in the Title Page
+ (and on the covers, if any) a title distinct from that of the
+ Document, and from those of previous versions (which should, if
+ there were any, be listed in the History section of the
+ Document). You may use the same title as a previous version if
+ the original publisher of that version gives permission.</para>
+ </listitem>
+
+ <listitem><para>List on the Title Page,
+ as authors, one or more persons or entities responsible for
+ authorship of the modifications in the Modified Version,
+ together with at least five of the principal authors of the
+ Document (all of its principal authors, if it has less than
+ five).</para>
+ </listitem>
+
+ <listitem><para>State on the Title page
+ the name of the publisher of the Modified Version, as the
+ publisher.</para>
+ </listitem>
+
+ <listitem><para>Preserve all the
+ copyright notices of the Document.</para>
+ </listitem>
+
+ <listitem><para>Add an appropriate
+ copyright notice for your modifications adjacent to the other
+ copyright notices.</para>
+ </listitem>
+
+ <listitem><para>Include, immediately
+ after the copyright notices, a license notice giving the public
+ permission to use the Modified Version under the terms of this
+ License, in the form shown in the Addendum below.</para>
+ </listitem>
+
+ <listitem><para>Preserve in that license
+ notice the full lists of Invariant Sections and required Cover
+ Texts given in the Document's license notice.</para>
+ </listitem>
+
+ <listitem><para>Include an unaltered
+ copy of this License.</para>
+ </listitem>
+
+ <listitem><para>Preserve the section
+ entitled ‘History’, and its title, and add to it an item stating
+ at least the title, year, new authors, and publisher of the
+ Modified Version as given on the Title Page. If there is no
+ section entitled ‘History’ in the Document, create one stating
+ the title, year, authors, and publisher of the Document as given
+ on its Title Page, then add an item describing the Modified
+ Version as stated in the previous sentence.</para>
+ </listitem>
+
+ <listitem><para>Preserve the network
+ location, if any, given in the Document for public access to a
+ Transparent copy of the Document, and likewise the network
+ locations given in the Document for previous versions it was
+ based on. These may be placed in the ‘History’ section. You
+ may omit a network location for a work that was published at
+ least four years before the Document itself, or if the original
+ publisher of the version it refers to gives permission.</para>
+ </listitem>
+
+ <listitem><para>In any section entitled
+ ‘Acknowledgements’ or ‘Dedications’, preserve the section's
+ title, and preserve in the section all the substance and tone of
+ each of the contributor acknowledgements and/or dedications
+ given therein.</para>
+ </listitem>
+
+ <listitem><para>Preserve all the
+ Invariant Sections of the Document, unaltered in their text and
+ in their titles. Section numbers or the equivalent are not
+ considered part of the section titles.</para>
+ </listitem>
+
+ <listitem><para>Delete any section
+ entitled ‘Endorsements’. Such a section may not be included in
+ the Modified Version.</para>
+ </listitem>
+
+ <listitem><para>Do not retitle any
+ existing section as ‘Endorsements’ or to conflict in title with
+ any Invariant Section.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>If the Modified Version includes new front-matter sections
+ or appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option
+ designate some or all of these sections as invariant. To do this,
+ add their titles to the list of Invariant Sections in the Modified
+ Version's license notice. These titles must be distinct from any
+ other section titles.</para>
+
+ <para>You may add a section entitled ‘Endorsements’, provided it
+ contains nothing but endorsements of your Modified Version by
+ various parties--for example, statements of peer review or that
+ the text has been approved by an organization as the authoritative
+ definition of a standard.</para>
+
+ <para>You may add a passage of up to five words as a Front-Cover
+ Text, and a passage of up to 25 words as a Back-Cover Text, to the
+ end of the list of Cover Texts in the Modified Version. Only one
+ passage of Front-Cover Text and one of Back-Cover Text may be
+ added by (or through arrangements made by) any one entity. If the
+ Document already includes a cover text for the same cover,
+ previously added by you or by arrangement made by the same entity
+ you are acting on behalf of, you may not add another; but you may
+ replace the old one, on explicit permission from the previous
+ publisher that added the old one.</para>
+
+ <para>The author(s) and publisher(s) of the Document do not by
+ this License give permission to use their names for publicity for
+ or to assert or imply endorsement of any Modified Version.</para>
+ </sect1>
+
+ <sect1 label="5">
+ <title>Combining Documents</title>
+
+ <para>You may combine the Document with other documents released
+ under this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination
+ all of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice.</para>
+
+ <para>The combined work need only contain one copy of this
+ License, and multiple identical Invariant Sections may be replaced
+ with a single copy. If there are multiple Invariant Sections with
+ the same name but different contents, make the title of each such
+ section unique by adding at the end of it, in parentheses, the
+ name of the original author or publisher of that section if known,
+ or else a unique number. Make the same adjustment to the section
+ titles in the list of Invariant Sections in the license notice of
+ the combined work.</para>
+
+ <para>In the combination, you must combine any sections entitled
+ ‘History’ in the various original documents, forming one section
+ entitled ‘History’; likewise combine any sections entitled
+ ‘Acknowledgements’, and any sections entitled ‘Dedications’. You
+ must delete all sections entitled ‘Endorsements.’</para>
+ </sect1>
+
+ <sect1 label="6">
+ <title>Collections of Documents</title>
+
+ <para>You may make a collection consisting of the Document and
+ other documents released under this License, and replace the
+ individual copies of this License in the various documents with a
+ single copy that is included in the collection, provided that you
+ follow the rules of this License for verbatim copying of each of
+ the documents in all other respects.</para>
+
+ <para>You may extract a single document from such a collection,
+ and distribute it individually under this License, provided you
+ insert a copy of this License into the extracted document, and
+ follow this License in all other respects regarding verbatim
+ copying of that document.</para>
+ </sect1>
+
+ <sect1 label="7">
+ <title>Aggregation with Independent Works</title>
+
+ <para>A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of
+ a storage or distribution medium, does not as a whole count as a
+ Modified Version of the Document, provided no compilation
+ copyright is claimed for the compilation. Such a compilation is
+ called an ‘aggregate’, and this License does not apply to the
+ other self-contained works thus compiled with the Document, on
+ account of their being thus compiled, if they are not themselves
+ derivative works of the Document.</para>
+
+ <para>If the Cover Text requirement of section 3 is applicable to
+ these copies of the Document, then if the Document is less than
+ one quarter of the entire aggregate, the Document's Cover Texts
+ may be placed on covers that surround only the Document within the
+ aggregate. Otherwise they must appear on covers around the whole
+ aggregate.</para>
+ </sect1>
+
+ <sect1 label="8">
+ <title>Translation</title>
+
+ <para>Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires
+ special permission from their copyright holders, but you may
+ include translations of some or all Invariant Sections in addition
+ to the original versions of these Invariant Sections. You may
+ include a translation of this License provided that you also
+ include the original English version of this License. In case of
+ a disagreement between the translation and the original English
+ version of this License, the original English version will
+ prevail.</para>
+ </sect1>
+
+ <sect1 label="9">
+ <title>Termination</title>
+
+ <para>You may not copy, modify, sublicense, or distribute the
+ Document except as expressly provided for under this License. Any
+ other attempt to copy, modify, sublicense or distribute the
+ Document is void, and will automatically terminate your rights
+ under this License. However, parties who have received copies, or
+ rights, from you under this License will not have their licenses
+ terminated so long as such parties remain in full
+ compliance.</para>
+ </sect1>
+
+ <sect1 label="10">
+ <title>Future Revisions of This License</title>
+
+ <para>The Free Software Foundation may publish new, revised
+ versions of the GNU Free Documentation License from time to time.
+ Such new versions will be similar in spirit to the present
+ version, but may differ in detail to address new problems or
+ concerns. See <ulink
+ url="http://www.gnu.org/copyleft/">http://www.gnu.org/copyleft/</ulink>.</para>
+
+ <para>Each version of the License is given a distinguishing
+ version number. If the Document specifies that a particular
+ numbered version of this License ‘or any later version’ applies to
+ it, you have the option of following the terms and conditions
+ either of that specified version or of any later version that has
+ been published (not as a draft) by the Free Software Foundation.
+ If the Document does not specify a version number of this License,
+ you may choose any version ever published (not as a draft) by the
+ Free Software Foundation.</para>
+ </sect1>
+
+ <sect1 label="">
+ <title>How to use this License for your documents</title>
+
+ <para>To use this License in a document you have written, include
+ a copy of the License in the document and put the following
+ copyright and license notices just after the title page:</para>
+
+ <blockquote><para>
+ Copyright © YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.1
+ or any later version published by the Free Software Foundation;
+ with the Invariant Sections being LIST THEIR TITLES, with the
+ Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+ A copy of the license is included in the section entitled "GNU
+ Free Documentation License".
+ </para></blockquote>
+
+ <para>If you have no Invariant Sections, write ‘with no Invariant
+ Sections’ instead of saying which ones are invariant. If you have
+ no Front-Cover Texts, write ‘no Front-Cover Texts’ instead of
+ ‘Front-Cover Texts being LIST’; likewise for Back-Cover
+ Texts.</para>
+
+ <para>If your document contains nontrivial examples of program
+ code, we recommend releasing these examples in parallel under your
+ choice of free software license, such as the GNU General Public
+ License, to permit their use in free software.</para>
+ </sect1>
+
+ </appendix>
+ <!-- Keep this comment at the end of the file
+ Local variables:
+ mode: sgml
+ sgml-omittag:nil
+ sgml-shorttag:t
+ sgml-minimize-attributes:nil
+ sgml-always-quote-attributes:t
+ sgml-indent-step:2
+ sgml-parent-document: ("referenz.sgml" "appendix")
+ sgml-exposed-tags:nil
+ sgml-local-ecat-files:nil
+ sgml-local-catalogs: CATALOG
+ sgml-validate-command: "nsgmls -s referenz.sgml"
+ ispell-skip-sgml: t
+ End:
+ -->
Index: llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kc2kc++.tex
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kc2kc++.tex:1.1
*** /dev/null Tue Apr 6 15:25:33 2004
--- llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kc2kc++.tex Tue Apr 6 15:25:22 2004
***************
*** 0 ****
--- 1,88 ----
+ \documentclass[a4paper,10pt]{article}
+ \usepackage{url,a4wide,newcent}
+ \usepackage[latin1]{inputenc}
+
+ \newcommand{\programtext}[1]{\texttt{\textbf{#1}}}
+
+ \begin{document}
+ \begin{center}\Huge From Kimwitu to Kimwitu++\end{center}
+
+ This document is meant as a short guide for converting projects that employ
+ Kimwitu to use Kimwitu++ instead. It is probably not complete. Please mail
+ any comments to \url{piefel at informatik.hu-berlin.de}. % @
+
+ \begin{itemize}
+ \item Generally Kimwitu++ works together with C++, while Kimwitu worked with C.
+ This will possibly cause some of the usual C to C++ hassle.
+
+ \item Kernighan \& Ritchie style for C functions is not allowed in *.k files.
+ Use proper ISO~C instead.
+
+ \item There is no longer a predefined phylum called `\programtext{int}'. There
+ is, however, a phylum providing the same functionality called
+ `\programtext{integer}'. When converting, please note that `\programtext{integer
+ i; i=5;}' will be caught by the compiler, while `\programtext{i=0;}' will not.
+ This is nasty, I'm sorry.
+
+ The right way to use them is `\programtext{integer i; i=mkinteger(5);} and
+ `\programtext{if (i->value==5) \dots}'.
+
+ \item Similar things apply to `\programtext{float}' et.\,al., there is now a
+ phylum `\programtext{real}'.
+
+ \item \programtext{Bool}, \programtext{True} and \programtext{False} disappeared and are
+ supplanted by their respective C++ counterparts.
+
+ \item Phyla are classes or objects, respectively. Instead of
+ `\programtext{unparse\_completeSyntaxTree( synTree, printer, view );}' you can
+ use the more natural `\programtext{synTree->unparse( printer, view );}'.
+
+ \item The keyword and typename `\programtext{\%view}' and `\programtext{view}'
+ are no longer available (they were deprecated anyway). Use
+ `\programtext{\%uview}' and `\programtext{uview}'.
+
+ \item Printers are now by default not functions taking \programtext{(char*,
+ uview)}, but rather objects of a class with \programtext{operator()(const char*,
+ uview)} defined. This allows a printer to have its own state. You can also still
+ use functions if you want, they will be wrapped when calling
+ \programtext{unparse}.
+
+ \item Everthing is in the namespace \programtext{kc}. If you put
+ \programtext{using namespace kc;} in your program, everthing else will continue
+ to work as it did.
+
+ \item If you want to interface with flex and bison, not that the union
+ \programtext{YYSTYPE} is not generated automatically anymore. Instead, use the
+ command line option --yystype, which will create a seperate yystype.h containing
+ the type definition.
+
+ \item CSGIO works a little different in two respects.\begin{itemize}
+ \item The old functions returned a string which indicated success or failure.
+ The new functions instead return \programtext{void}. Errors will be reported
+ by throwing exceptions of type \programtext{IO\_exception}; there is a
+ function \programtext{IO\_exception2char} turning that into a string.
+ \item While \programtext{CSGIOwrite} is a member function,
+ \programtext{CSGIOread} cannot be. The latter takes just the phylum type, not
+ a pointer to it---just write \programtext{CSGIOread(f, p)}.
+ \end{itemize}
+ \end{itemize}
+ \clearpage
+ \begin{center}\large New Features\end{center}
+ This is just a very brief list of some of the nicest new features, it is not
+ exhaustive.
+ \begin{itemize}
+ \item Everything can be unparsed. As long as the (somewhat limited) parser can
+ read it, it will be handed to a global unparse function (in namespace kc); define
+ your own function if it is needed.
+ \item All patterns (eg. for unparse rules) can have a guard condition; the
+ condition comes in parentheses after the pattern following the new keyword
+ \programtext{provided}.
+ \item New functions for phylum types can be defined, just write something like
+ \programtext{void foo::bar() \{ \dots~\}}.
+ \item There is a new (additional) syntax for defining attributes of phyla such as
+ \programtext{\%member int foo::baz}; when using \programtext{\%attr} instead, the
+ attribute will be written out and read in with CSGIO functions.
+ \item Likewise you can define additional constructors and destructors with
+ \programtext{\%ctor} and \programtext{\%dtor}.
+ \end{itemize}
+ \end{document}
Index: llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kpp-cook.xml
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kpp-cook.xml:1.1
*** /dev/null Tue Apr 6 15:25:33 2004
--- llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kpp-cook.xml Tue Apr 6 15:25:22 2004
***************
*** 0 ****
--- 1,7 ----
+ <!--
+ <!DOCTYPE DocBook>
+
+ < kimwitu++ part III: cookbook >
+ -->
+
+ <chapter><title>empty</title><para>empty</para></chapter>
Index: llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kpp-intro.xml
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kpp-intro.xml:1.1
*** /dev/null Tue Apr 6 15:25:33 2004
--- llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kpp-intro.xml Tue Apr 6 15:25:22 2004
***************
*** 0 ****
--- 1,683 ----
+ <!--
+ <!DOCTYPE DocBook>
+
+ < kimwitu++ part I: introduction >
+ -->
+
+ <chapter><title>What is &kpp;?</title>
+ <para>This chapter sketches out the field on which &kpp; is usefully employed and
+ explains important terms. It develops an example to outline the advantages
+ of this tool compared to conventional techniques. The example will be used
+ throughout the following chapters to introduce concept by concept. The
+ complete code to make it work can be found in appendix <xref
+ linkend="app:rpn"/>.</para>
+
+ <sect1><title>What for is &kpp; used?</title>
+ <para>To illustratively explain what we can do with the help of &kpp; we
+ call upon an example. Let us imagine we want to write a computer game.
+ Neat example. Respectable programmers as we are we calculate
+ the overall costs of the new project in advance. It will take us, say, 30
+ days, on each we need to have a pizza at 7 € and 3 beer at 2 €
+ each, but luckily meanwhile our grandma supports us with 100 €. We
+ get the expression <inlineequation><alt>30*(8+3*2)-100</alt>
+ <inlinemediaobject><imageobject><imagedata
+ fileref="figures/equation3.png"
+ format="PNG"/></imageobject>
+ </inlinemediaobject> <?latex \(30 ( 8 + 3 \times 2) - 100\)?>
+ </inlineequation> and type it in postfix notation into our
+ <acronym>RPN</acronym><indexterm><primary>rpn</primary></indexterm>-calculator.
+ You know, one of the antiquated devices knowing nothing about precedence
+ nor parentheses and expecting input in Reverse Polish Notation, where
+ operands precede their operator.</para>
+ <para>So we type <userinput>30 8 3 2 * + * 100 -</userinput>. Er, we cannot.
+ I remember. The calculator gave up the ghost last week. But don't
+ despair. We quickly program a new one.</para>
+ </sect1>
+
+ <sect1><title>A Simple Example</title>
+ <para>What exactly should the new calculator be able to do? Anyhow, it
+ better
+ would accept also variables. Why? Just imagine a drastic shortage of pizza
+ and beer what would urge us to setup a new expression again. We better use
+ a flexible one which can be seen in example <xref
+ linkend="exa:expression"/>, in which <varname>x</varname> is the price of
+ a beer and we know the price of a pizza always to be 4 times a beer.
+ </para>
+ <example id="exa:expression"><title>Sample Expression</title>
+ <informalequation><alt>30*(4*x+3*x)-100</alt>
+ <mediaobject><imageobject><imagedata fileref="figures/equation4.png"
+ format="PNG"/></imageobject>
+ </mediaobject><?latex \[30 ( 4 \times x + 3 \times x) - 100\]?>
+ </informalequation>
+ <para>(and resulting input in <acronym>RPN</acronym>:
+ <userinput>30 4 x * 3 x * + * 100 -</userinput>)
+ </para>
+ </example>
+ <para>We now list the requirements on the calculator in proper order.
+ <orderedlist numeration="arabic" spacing="compact">
+ <listitem><para>We want it to analyse an input expression (term) of
+ digits, arithmetical operators, and variables.</para></listitem>
+ <listitem><para>It should calculate the expression if possible or
+ simplify it at least.</para></listitem>
+ <listitem><para>It then should output a result.</para></listitem>
+ </orderedlist>
+ </para>
+
+ <para>We assume the existence of a code component (a scanner) providing
+ us with syntactical tokens like operators, numbers and identifiers
+ (variables). We then need a description of
+ correct input, a grammar<indexterm><primary>grammar</primary></indexterm>.
+ Our example demands a valid arithmetical term
+ only to consist of numbers, identifiers, and the four arithmetical operators.
+ A formal notation as used by the parser generator &yacc; (see <xref
+ linkend="sec:yacc"/>) would look like in example <xref
+ linkend="exa:gramyacc"/>.</para>
+ <example id="exa:gramyacc"><title>&yacc; Grammar for Sample</title>
+ <programlisting>
+ aritherm: simpleterm
+ | aritherm aritherm '+'
+ | aritherm aritherm '-'
+ | aritherm aritherm '*'
+ | aritherm aritherm '/';
+
+ simpleterm: NUMBER
+ | IDENT;
+ </programlisting>
+ </example>
+ <para>Such a grammar is made up of rules, each having two sides separated by
+ a colon. These rules describe how the left-hand side called
+ nonterminal<indexterm><primary>nonterminal</primary></indexterm> can be
+ composed of syntactical tokens called
+ terminals<indexterm><primary>terminal</primary></indexterm>, which
+ are typed in upper
+ case letters or as single quoted characters. Different alternatives are
+ separated by bar. The right-hand side may also contain nonterminals which
+ there can be regarded to be an application of their respective composition
+ rule.</para>
+ <para>The first rule of this grammar defines an &aritherm;
+ to be a &simpleterm; or a composition of two &aritherm;s and an operator
+ sign. These &aritherm;s in turn may be composed according to the
+ &aritherm; rule. The second rule describes what an &aritherm; looks
+ like, if it is a &simpleterm;.</para>
+ <para>A common way to hold an input term internally is to
+ keep it as a syntax
+ tree<indexterm><primary>tree</primary><secondary>syntax
+ tree</secondary></indexterm>, that is a hierarchical structure of
+ nodes<indexterm><primary>node</primary></indexterm> (upside
+ down tree). A nonterminal can be regarded as a node
+ type<indexterm><primary>node type</primary></indexterm> and every
+ alternative of the assigned right-hand side as one
+ &kind;<indexterm><primary>&kind;</primary></indexterm> of that type.
+ Every actual node thus is a &kind; of a node type with a specific number
+ of child nodes, which depends on the &kind;. For example
+ <constant>'+'</constant> is a &kind; of &aritherm; and it has 2 child
+ nodes, while <constant>NUMBER</constant> is a &kind; of &simpleterm; and
+ it has none. Figure <xref linkend="fig:syntaxtreex"/> shows a syntax tree
+ for our sample input term. Since every node is a
+ term<indexterm><primary>term</primary></indexterm> itself such a tree is
+ more generally called a term
+ tree<indexterm><primary>tree</primary><secondary>term tree</secondary></indexterm>.</para>
+ <figure id="fig:syntaxtreex">
+ <title>Syntax tree representing sample term</title>
+ <mediaobject><imageobject><imagedata
+ fileref="imagesgen/syntaxtreex.png" align="center" format="PNG"/>
+ </imageobject>
+ <imageobject><imagedata
+ fileref="imagesgen/syntaxtreex" align="center" format="TEX"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ <para>To summarise the task identified: we want to build a tree from the
+ term
+ which has been typed in, walk over the tree nodes, and perform appropriate
+ actions like calculating, simplifying or printing some results.</para>
+ </sect1>
+
+ <sect1><title>Conventional Approach</title>
+ <para>In a programming language a node type is usually represented as
+ a structured data type, that is, as a class in object oriented languages
+ and as a sort of record in others.
+ A &kind;, then, may be a class
+ variant or a subclass, and a variant record respectively. The
+ code fragment in example <xref linkend="exa:cppclass"/> illustrates a
+ possible implementation in &cpp; (the &kind; as a subclass). The classes
+ left out are to define similar.</para>
+ <example id="exa:cppclass"><title>Node Types as Classes with &cpp;</title>
+ <programlisting>
+ class Aritherm { /* ... */ };
+ class Simpleterm : Aritherm { /* ... */ };
+
+ class Plus : public Aritherm
+ {
+ public :
+ Plus( Aritherm *a, Aritherm *b ) : t1 ( a ), t2 ( b )
+ { /* ... */ };
+ private:
+ Aritherm *t1, *t2;
+ };
+
+ class Number : public Simpleterm
+ {
+ public :
+ Number( int a ) : n ( a )
+ { /* ... */ };
+ private:
+ int n;
+ };
+ </programlisting>
+ </example>
+ <para>From these classes we can instantiate &cpp; objects to represent our
+ sample tree. We can navigate through it by accessing the child nodes of
+ nodes. Not really yet, if you look closely at it. The child nodes are
+ private members and thus they can not be accessed. We have to make them
+ public or to add methods for their access. But what about the next step,
+ simplifying parts of the tree? The subtree
+ <inlineequation><alt>4*x+3*x</alt> <?latex \(4 \times x + 3 \times x\)?>
+ <inlinemediaobject><imageobject><imagedata fileref="figures/equation1.png" format="PNG"/></imageobject>
+ </inlinemediaobject>
+ </inlineequation> could be transformed to, right,
+ <inlineequation><alt>(4+3)*x</alt><?latex \(( 4 + 3 ) \times x\)?>
+ <inlinemediaobject><imageobject><imagedata fileref="figures/equation2.png"
+ format="PNG"/></imageobject>
+ </inlinemediaobject>
+ </inlineequation>, by putting <varname>x</varname> outside the parentheses,
+ as illustrated in figure <xref linkend="fig:simplify"/>.
+ For &cpp; this may look like listed in example <xref linkend="exa:cpp"/>.
+ </para>
+ <figure id="fig:simplify">
+ <title>Simplification of a samples subtree</title>
+ <mediaobject><imageobject><imagedata
+ align="center" fileref="imagesgen/simplify.png" format="PNG"/>
+ </imageobject>
+ <imageobject><imagedata
+ align="center" fileref="imagesgen/simplify" format="TEX"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <example id="exa:cpp"><title>Term Substitution with &cpp;</title>
+ <programlisting>
+ <![CDATA[
+ if( dynamic_cast<Sum> ( A ) !=0 &&
+ dynamic_cast<Mul> ( dynamic_cast<Sum>( A ) -> t1 ) !=0 &&
+ dynamic_cast<Mul> ( dynamic_cast<Sum>( A ) -> t2 ) !=0 &&
+ dynamic_cast<Mul> ( dynamic_cast<Sum>( A ) -> t1 ) -> t2 ==
+ dynamic_cast<Mul> ( dynamic_cast<Sum>( A ) -> t2 ) -> t2 )
+ {
+
+ A = new Mul ( new Sum (
+ dynamic_cast<Mul> ( dynamic_cast<Sum>( A ) -> t1 ) -> t1,
+ dynamic_cast<Mul> ( dynamic_cast<Sum>( A ) -> t2 ) -> t1 ),
+ dynamic_cast<Mul> ( dynamic_cast<Sum>( A ) -> t1 ) -> t2 );
+ };
+ ]]>
+ </programlisting>
+ </example>
+ <para>That seems quite complicated and it is even more so! Not only have we
+ to cast for every child node access, to avoid memory leaks we had to free
+ memory of unused nodes as old <varname>A</varname> and its child nodes.
+ Furthermore the equality check between <varname>t1</varname> and
+ <varname>t2</varname> will merely compare pointer values, instead of
+ checking whether the subtrees are structurally equal. Thus we additionally
+ need to overload the equality operators. What a lot of trouble for such
+ a simple example!</para>
+ </sect1>
+
+ <sect1><title>&kpp; Approach</title>
+ <para>&kpp;'s<indexterm><primary>&kpp;</primary></indexterm> name
+ is formed after Swahili while the ‘++’
+ reminds on &cpp;. </para>
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <?latex-table-head lcl?>
+ <tbody>
+ <row><entry>witu</entry>
+ <entry>:</entry>
+ <entry>‘tree’</entry>
+ </row>
+ <row><entry>m-</entry>
+ <entry>:</entry>
+ <entry>plural prefix</entry>
+ </row>
+ <row><entry>ki-</entry>
+ <entry>:</entry>
+ <entry>adjectival prefix: ‘being like’</entry>
+ </row>
+ <row><entry>kimwitu</entry>
+ <entry>=</entry>
+ <entry>‘tree-s-ish’</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ <para>Thus the name indicates affiliation to trees and to &cpp;. You
+ guessed it before, didn't you? More strictly spoken &kpp; is a tool which
+ allows to describe in an easy way how to manipulate and to evaluate a
+ given term tree. From these descriptions &cpp; code is
+ generated and compiled to a program which processes terms. That is why
+ &kpp; itself is called a term processor.</para>
+ <para>The code for building a tree, we have to write ourselves, or
+ we let preferably other tools generate it.
+ We use &yacc; to call term
+ creation routines which are generated from a &kpp; abstract grammar.
+ This we have to specify first. It is similar to the &yacc; grammar, but
+ its right-hand side alternatives are operators applied to nonterminals. An
+ abstract grammar for our sample can be seen in example <xref
+ linkend="exa:gramkpp"/>. The nonterminals <classname>integer</classname>
+ and <classname>casestring</classname> are predefined in &kpp;.</para>
+ <example id="exa:gramkpp"><title>Abstract Grammar for Sample</title>
+ <programlisting>
+ aritherm: SimpleTerm ( simpleterm )
+ | Plus ( aritherm aritherm )
+ | Minus ( aritherm aritherm )
+ | Mul ( aritherm aritherm )
+ | Div ( aritherm aritherm );
+
+ simpleterm: Number ( integer )
+ | Ident ( casestring );
+ </programlisting>
+ </example>
+ <para>Next we have to complete the &yacc; grammar by adding
+ semantic actions in braces to every alternative. These recursively
+ create a term tree which has its root element assigned to the variable
+ <varname>root_term</varname>. Example <xref linkend="exa:gramyaccp"/>
+ shows this grammar, in which <varname>$$</varname> denotes the term
+ under construction and <varname>$1</varname> and <varname>$2</varname>
+ its first and its second subterm<indexterm
+ significance="preferred"><primary>subterm</primary></indexterm> (child
+ node).</para>
+ <example id="exa:gramyaccp">
+ <title>Completed &yacc; Grammar for Sample</title>
+ <programlisting>
+ aritherm: simpleterm
+ { root_term = $$ = SimpleTerm( $1 ); }
+ | aritherm aritherm '+'
+ { root_term = $$ = Plus( $1, $2 ); }
+ | aritherm aritherm '-'
+ { root_term = $$ = Minus( $1, $2 ); }
+ | aritherm aritherm '*'
+ { root_term = $$ = Mul( $1, $2 ); }
+ | aritherm aritherm '/'
+ { root_term = $$ = Div( $1, $2 ); };
+
+ simpleterm: NUMBER
+ { $$ = Number( $1 ); }
+ | IDENT
+ { $$ = Ident( $1 ); };
+ </programlisting>
+ </example>
+ <para>That is it for building a tree. Everything else is left to the
+ automatic code generation. Modifying or evaluating the tree
+ needs its own rules (see chapter <xref linkend="cha:modify"/>).
+ </para>
+ </sect1>
+ <sect1 id="ch:summary"><title>Summary</title>
+ <para>The language &kpp; is an extension of &cpp; for handling of term trees.
+ It allows the definition of term types<indexterm><primary>term
+ type</primary><see>node type</see></indexterm>, creation of terms, and provides
+ mechanisms for transforming and traversing trees as well as saving and
+ restoring them. Besides creating it in static code a tree can dynamically
+ be obtained by interfacing with compiler generator &cpp; code (as from
+ &yacc;/&bison;). The &kpp; processor generates &cpp; code from the contents
+ of &kpp; input (<filename>.k</filename>-files). Compilation of that code
+ yields the term processing program.</para>
+ </sect1>
+ </chapter>
+
+ <chapter><title>How to Define Term Types</title>
+ <para>This chapter describes possibilities to define term types, which make up
+ the &kpp; input. In &kpp; they are called
+ phyla<indexterm><primary>phyla</primary><see>phylum</see></indexterm> (singular
+ phylum)<indexterm><primary>phylum</primary></indexterm>, and that
+ is what we will call them from now on. A phylum instance is called a
+ term<indexterm significance="preferred"><primary>term</primary></indexterm>.
+ </para>
+ <sect1><title>Definition</title>
+ <indexterm><primary>phylum</primary><secondary>definition</secondary></indexterm>
+ <para>How are phyla defined? Example <xref linkend="exa:gramkpp"/> shows
+ that each phylum is defined as an enumeration of its &kind;s, each being
+ an operator applied to a number of phyla, maybe zero. So the operator
+ <constant>SimpleTerm</constant> takes one &simpleterm; phylum,
+ <constant>Plus</constant> takes two &aritherm; phyla. There are several
+ predefined phyla, of which <constant>integer</constant> and
+ <constant>casestring</constant> already have been mentioned. The latter
+ denotes a case sensitive character string. If a phylum is
+ defined more than once, all occurrences contribute to the first one. For
+ each phylum, a &cpp; class is generated.</para>
+ </sect1>
+ <sect1><title>Lists<indexterm><primary>list</primary></indexterm></title>
+ <indexterm id="idx:list" class="startofrange"><primary>list</primary></indexterm>
+ <para>We may want to define a phylum as a list of phyla. Imagine we wanted
+ not only to type one expression into our calculator but several ones at
+ once, separated in input by, say, a semicolon. The main phylum,
+ representing whole the input, would be a list of
+ &aritherm;s. This is a right-recursive definition of a list which may be a
+ nil (empty) list. The name of the list phylum prefixed by
+ <constant>Nil</constant><indexterm><primary>Nil</primary></indexterm> and
+ <constant>Cons</constant><indexterm><primary>Cons</primary></indexterm> make up
+ common names for the two list operators. The other way to define a list
+ phylum is to use the built-in
+ <constant>list</constant> operator. This not
+ only looks more simple but causes the generation of additional list
+ functions.
+ Example <xref linkend="exa:lists"/> shows both definitions. </para>
+ <example id="exa:lists">
+ <title>Recursive and built-in List Definition</title>
+ <programlisting>
+ arithermlist: Nilarithermlist ( )
+ | Consarithermlist( aritherm arithermlist );
+
+ arithermlist: list aritherm;
+ </programlisting>
+ </example>
+ <indexterm class="endofrange" startref="idx:list"/>
+ </sect1>
+ <sect1><title>Attributes<indexterm id="intro_attributes"
+ class="startofrange"><primary>attributes</primary></indexterm>
+ </title>
+ <para>Each phylum definition can contain declarations of attributes of
+ phylum or arbitrary &cpp; types. They follow the operator
+ enumeration as a block enclosed in braces. What purpose do they serve?
+ With them, we can attach additional information to nodes, which otherwise
+ could only unfavourably be represented in the tree. In our example, we may
+ take advantage of attributes by saving intermediate results to support
+ the calculation. Therefore we extend the definition of &aritherm; from
+ example
+ <xref linkend="exa:gramkpp"/> to example <xref
+ linkend="exa:gramattr1"/>.</para>
+ <example id="exa:gramattr1"><title>Phylum Definition with Attributes</title>
+ <programlisting>
+ aritherm: SimpleTerm ( simpleterm )
+ | Plus ( aritherm aritherm )
+ | Minus ( aritherm aritherm )
+ | Mul ( aritherm aritherm )
+ | Div ( aritherm aritherm )
+ { int result = 0;
+ bool evaluated = false;
+ bool computable = true;
+ };
+ </programlisting>
+ </example>
+ <para>Attribute <varname>result</varname> should hold the intermediate
+ result of an &aritherm;, if it already has been evaluated
+ (<varname>evaluated</varname><constant>==true</constant>) and found
+ computable during the evaluation
+ (<varname>computable</varname><constant>==true</constant>), that is the
+ subterms contain no variables. The attributes can be initialized at the
+ declaration or inside an additional braces block which may follow
+ the declarations and can contain arbitrary &cpp; code. Example <xref
+ linkend="exa:gramattr2"/> shows an alternative to the initialization from
+ example <xref linkend="exa:gramattr1"/>.</para>
+ <example id="exa:gramattr2">
+ <title>Alternative Attributes Initialization</title>
+ <programlisting>
+ <![CDATA[ { int result;
+ bool evaluated;
+ bool computable;
+ { $0->result = 0;
+ $0->evaluated = false;
+ $0->computable = true; }
+ };]]>
+ </programlisting>
+ </example>
+ <para>That &cpp; code is executed when a term of that phylum has been
+ created. It can be referred to as <varname>$0</varname> and its
+ attributes can be accessed via the operator
+ <constant><![CDATA[->]]></constant>.</para>
+ <indexterm class="endofrange" startref="intro_attributes"/>
+ </sect1>
+ </chapter>
+
+ <chapter><title>Aid with Term Handling</title>
+ <para>This chapter describes techniques necessary and useful to traverse a
+ term structure: the application of term patterns and the
+ use of special &kpp; language constructs for term handling.</para>
+ <sect1
+ id="sec:patterns">
+ <title>Patterns<indexterm><primary>patterns</primary></indexterm></title>
+ <para>Patterns are a means to select specific terms which can be associated
+ with a desired action. Example <xref linkend="exa:pattern"/> shows some
+ patterns and explains what terms they match. Patterns are used in special
+ statements and in rewrite and unparse rules (see <xref
+ linkend="sec:specstatements"/>
+ and <xref linkend="cha:modify"/> respectively).</para>
+ <example id="exa:pattern"><title>Patterns</title>
+ <programlisting>
+ <![CDATA[ Plus( *, * )
+ // matches a term Plus with two subterms
+
+ c=Plus( a, b )
+ // matches a term Plus with two subterms, which are assigned to
+ // the variables a and b, while the term itself is assigned to c
+
+ Plus( a, a )
+ // similar to the previous case, but matches only if the two subterms
+ // are structurally equal; variable a gets assigned the first subterm
+
+ Plus( Mul( a, b ), * )
+ // matches a term Plus with two subterms, whereof the first one
+ // is a Mul term with the subterms assigned to the variables a and b
+
+ Plus( a, b ), Minus( a, b )
+ // matches if the term in question is either a Plus or a Minus; the
+ // two subterms then are assigned to the variables a and b]]>
+ </programlisting>
+ </example>
+ </sect1>
+ <sect1 id="sec:specstatements"><title>Special Statements</title>
+ <para>&kpp; provides two statements as extensions to &cpp; which make it
+ more comfortable to deal with terms. These are the &with;-statement and
+ the &foreach;-statement. They can be used in functions and in the &cpp;
+ parts of unparse rules (see <xref linkend="sec:traverse"/>).</para>
+ <para>The &with;<indexterm><primary>&with;</primary></indexterm>-statement
+ can be considered as a
+ <constant>switch</constant>-statement for a phylum. It contains an
+ enumeration of patterns which must describe &kind;s of the specified
+ phylum. From these, the one is chosen which matches a given term best.
+ Then the &cpp; code is executed, which was assigned to that pattern.
+ </para>
+ <para>Example <xref linkend="exa:with"/> takes a term of the phylum
+ &aritherm;
+ and calculates the attribute <varname>result</varname>, if the term is a
+ sum or a difference,
+ by adding or subtracting the results of the subterms. The keyword
+ <constant>default</constant> serves as a special pattern in &with;, which
+ matches when none of the others does.</para>
+ <para>In the first case, the two subterms are assigned to the variables
+ <varname>a</varname> and <varname>b</varname>, which can be used in the
+ &cpp; part. The term itself is assigned to variable <varname>c</varname>
+ which thus refers to the same term as the variable <varname>at</varname>.
+ Variable <varname>at</varname> is visible throughout the entire &with;
+ body and it can be accessed in all &cpp; parts. It may get a new term
+ assigned as it is done in the second case whithin which the variable
+ <varname>at</varname> refers to the first subterm.</para>
+ <example id="exa:with">
+ <title>&with;-statement</title>
+ <programlisting>
+ <![CDATA[ aritherm at;
+ ...
+ with ( at ) {
+ c = Plus ( a, b ) : { c -> result = a -> result + b -> result; }
+ Minus ( at, b ) : { c -> result = at -> result - b -> result; }
+ default : { }
+ }]]>
+ </programlisting>
+ </example>
+ <para>The second special construct is the
+ &foreach;<indexterm><primary>&foreach;</primary></indexterm>-statement, which
+ iterates over a term of a list phylum and performs the specified actions
+ for every list element. Example <xref linkend="exa:foreach"/> determines
+ the greatest <varname>result</varname> from the terms in the list
+ <varname>a</varname>.</para>
+ <example id="exa:foreach">
+ <title>&foreach;-statement</title>
+ <programlisting>
+ <![CDATA[ int max = 0;
+ foreach( a; arithermlist A ){
+ if( a -> result > max ) max = a -> result;
+ }]]>
+ </programlisting>
+ </example>
+ </sect1>
+ </chapter>
+
+ <chapter id="cha:modify"><title>Modifying and Evaluating Term Trees</title>
+ <para>This chapter describes how the tree of terms can be processed
+ once it has been created. On one hand we can change its structure and
+ hopefully simplify it by applying rewrite rules. On the other hand we
+ can step through it and create a formatted output by applying unparse
+ rules.
+ </para>
+ <sect1><title>Transforming</title>
+ <para>Rewriting<indexterm><primary>rewriting</primary></indexterm> denotes
+ the process of stepping through the tree, seeking
+ the terms that match a pattern and substituting them by the appropriate
+ substitution term. Rewrite rules consist of two parts, where the
+ left-hand side is a pattern (as described in <xref
+ linkend="sec:patterns"/>) and the right-hand side is a substitution term
+ enclosed by angle brackets. A term must always be substituted by a simpler
+ one, that is by one that is nearer to the desired form of result.
+ Otherwise the substitution process may never stop.</para>
+ <para>Let us try simplifying according to figure <xref
+ linkend="fig:simplify"/> to demonstrate the usage of rewrite rules. What
+ would the rules look like in &kpp; to achieve a simplification of that
+ kind?
+ Example <xref linkend="exa:rewrite"/> shows a solution using rewriting. It
+ is quite short in comparison with example <xref linkend="exa:cpp"/>, isn't
+ it?</para>
+ <example id="exa:rewrite">
+ <title>Term Substitution using &kpp;</title>
+ <programlisting>
+ <![CDATA[ Mul( Plus( a, b ), Plus( c, b ) ) -> <: Plus( Mul( a, c ), b )> ;]]>
+ </programlisting>
+ </example>
+ <para>An equivalent part would cover the case that <varname>b</varname>
+ takes the first position in both subterms. The meaning of the colon will
+ be explained in <xref linkend="sec:views"/>.</para>
+ </sect1>
+ <sect1 id="sec:traverse"><title>Traversing</title>
+ <para>Originally unparsing was meant to be a reverse parse, used to give a
+ formatted output of the tree built. In general it should better be
+ recognized
+ as a way to traverse the tree. Unparse rules have a structure similar to
+ that of rewrite rules. The left-hand side consists of a pattern, the
+ right-hand side of a
+ list of unparse items enclosed by square brackets. Some more common
+ unparse items are strings, pattern variables, attributes, and blocks of
+ arbitrary &cpp; code enclosed in braces.</para>
+ <para>Unparsing starts by calling the
+ <function>unparse</function><indexterm><primary>unparse()</primary></indexterm>-method
+ of a term, usually the root term,
+ and when a rule matches a term the
+ specified items are ‘printed’. Only string items are really
+ delivered to the current printer. This printer has to be defined by the
+ user, and it usually writes to the standard output or into a file.
+ Variable items and attribute items are further unparsed, code fragments
+ are executed. If no pattern matches then the default rule is used, which
+ exists for every phylum operator and which simply unparses the
+ subterms.</para>
+ <para>We could do quite a lot of different things with the information saved
+ in the tree. It just depends on the rules we use. For example we choose to
+ print the input term in infix notation, because it is better readable to
+ humans.</para>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ Plus( a, b ) -> [infix: "(" a "+" b ")" ];]]>
+ </programlisting>
+ </informalexample>
+ <para>
+ For every <constant>Plus</constant> term this rule prints an opening
+ parenthesis, unparses the first subterm, prints a plus sign, unparses the
+ second subterm, and then prints the closing parenthesis. The other
+ operators are handled by similar rules.</para>
+ <para>We also may want to eventually compute the result of
+ expressions. This can be achieved with rules like this.</para>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ c = Plus( a, b ) -> [: a b { c -> result = a -> result + b -> result; } ];]]>
+ </programlisting>
+ </informalexample>
+ <para>Here the subterms are unparsed and then an attribute of the term gets
+ assigned the sum of the subterm results. This will work only if these do
+ not contain <constant>Ident</constant>s. The meaning of the colon will be
+ explained in <xref linkend="sec:views"/>.</para>
+ <para>The &cpp; code is enclosed by braces, but can itself contain
+ braces in matching pairs. If a single brace is needed, as when
+ mixing code and variable items, it has to be escaped with the dollar
+ sign. Example <xref linkend="exa:escapedbrace"/> shows an application.
+ If the function yields <constant>true</constant> the first branch
+ is taken, and
+ <varname>b</varname> is unparsed before <varname>a</varname>.</para>
+ <example id="exa:escapedbrace">
+ <title>Escaped Braces in Unparse Rule</title>
+ <programlisting>
+ <![CDATA[ Plus( a, b ) -> [ : { if( smaller_than( a, b ) ) } ${
+ b "+" a $}
+ { else } ${
+ a "+" b $} ];]]>
+ </programlisting>
+ </example>
+ </sect1>
+ <sect1
+ id="sec:views">
+ <title>Views<indexterm class="startofrange"
+ id="idx:view"><primary>view</primary></indexterm></title>
+ <para>The whole process of rewriting and unparsing as well as parts of it
+ can be executed under different views. Each rule contains a view list
+ between the respective opening brace and the colon, and it is used only
+ if the current view appears
+ in the list. This allows to specify different rules for a pattern. If a
+ term is visited twice under different views, different rules are
+ applied. These rules can be merged into one by listing all right-hand sides
+ after one left-hand side, separating them by a comma.</para>
+ <para>Example <xref linkend="exa:rewriteview"/> defines two rewrite views
+ (<constant>simplify</constant> and <constant>canonify</constant>) and
+ two rules, each of which will only be applied to a matching term if the
+ current view is among
+ the specified ones. The first rule replaces the quotient of the same two
+ identifiers by the number <literal>1</literal>, the second expresses
+ the associativity of addition. Both change the tree.</para>
+ <example id="exa:rewriteview">
+ <title>Views in Rewrite Rules</title>
+ <indexterm><primary>mkinteger</primary></indexterm>
+ <programlisting>
+ <![CDATA[ %rview simplify, canonify;
+
+ Div( SimpleTerm( Ident( a ) ), SimpleTerm( Ident( a ) ) )
+ -> < simplify: SimpleTerm( Number( mkinteger( 1 ) ) ) >;
+
+ Plus( Plus( a, b ), c )
+ -> < canonify: Plus( a, Plus( b, c ) ) >;]]>
+ </programlisting>
+ </example>
+ <para>Example <xref linkend="exa:unparseview"/> defines two unparse views
+ (<constant>infix</constant> and <constant>postfix</constant>) and two
+ rules for the same pattern, the one of which is used which matches both
+ the term and the current view. It is possible to force a variable item to
+ be unparsed under a desired view by specifying it after the variable and
+ an intermediate colon. Subterm <varname>b</varname> is further
+ unparsed under the view <constant>check_zero</constant> instead of the
+ view <constant>infix</constant>.</para>
+ <informalexample id="exa:specview">
+ <indexterm><primary>%uview</primary></indexterm>
+ <programlisting>
+ <![CDATA[ %uview check_zero;
+
+ Div( a, b ) -> [ infix : a "/" b : check_zero ];
+ ]]>
+ </programlisting>
+ </informalexample>
+ <example id="exa:unparseview">
+ <title>Views in Unparse Rules</title>
+ <programlisting>
+ <![CDATA[ %uview infix, postfix;
+
+ Plus( a, b ) -> [ infix : a "+" b ],
+ [ postfix : a b "+" ];]]>
+ </programlisting>
+ </example>
+ <!-- Always move to end of enclosing chapter -->
+ <para><indexterm class="endofrange" startref="idx:view"/></para>
+ </sect1>
+ </chapter>
+ <!-- vim:set sw=2 ts=8 tw=80: -->
Index: llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kpp-main.xml
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kpp-main.xml:1.1
*** /dev/null Tue Apr 6 15:25:33 2004
--- llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kpp-main.xml Tue Apr 6 15:25:22 2004
***************
*** 0 ****
--- 1,136 ----
+ <?xml version="1.0" encoding="iso-8859-1"?>
+ <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1.2//EN"
+ "file:///usr/share/sgml/docbook/dtd/xml/4.1.2/docbookx.dtd" [
+ <!-- <!ATTLIST book xml:lang NMTOKEN 'en'> -->
+ <!-- <!ATTLIST book xml:lang NMTOKEN 'de'> -->
+ <!ENTITY kpp-intro SYSTEM "kpp-intro.xml">
+ <!ENTITY kpp-manual SYSTEM "kpp-manual.xml">
+ <!ENTITY kpp-cook SYSTEM "kpp-cook.xml">
+ <!ENTITY app-fdl SYSTEM "fdl.xml">
+ <!ENTITY app-rpn SYSTEM "kpp-rpn.xml">
+ <!ENTITY kpp "<application>Kimwitu++</application>">
+ <!ENTITY cpp "<application>C++</application>">
+ <!ENTITY yacc "<application>Yacc</application>">
+ <!ENTITY bison "<application>Bison</application>">
+ <!ENTITY with "<constant>with</constant>">
+ <!ENTITY foreach "<constant>foreach</constant>">
+ <!ENTITY aritherm "<classname>aritherm</classname>">
+ <!ENTITY simpleterm "<classname>simpleterm</classname>">
+ <!ENTITY kind "kind">
+ <!ENTITY Kind "Kind">
+ ]>
+
+ <!-- This is the documentation for the term processor Kimwitu++ -->
+
+ <book xml:lang="en">
+ <?latex \begin{titlepage}\noindent\vspace*{\fill}\begin{flushright}
+ \fontsize{48}{56}\fontshape{sl}\selectfont Kimwitu++\\
+ \fontsize{24}{28}\selectfont A Term Processor\\
+ \vfill\fontsize{12}{28}\selectfont Toby Neumann, Michael Piefel
+ \end{flushright}\vfill\end{titlepage}
+ \thispagestyle{empty}\cleardoublepage\lstset{language=C++}?>
+ <bookinfo>
+ <title>&kpp;</title>
+ <subtitle>A Term Processor</subtitle>
+ <author>
+ <firstname>Toby</firstname>
+ <surname>Neumann</surname>
+ <affiliation>
+ <orgname>Humboldt-Universität zu Berlin</orgname>
+ <orgdiv>Institute for Informatics</orgdiv>
+ </affiliation>
+ </author>
+ <author>
+ <firstname>Michael</firstname>
+ <surname>Piefel</surname>
+ <affiliation>
+ <orgname>Humboldt-Universität zu Berlin</orgname>
+ <orgdiv>Institute for Informatics</orgdiv>
+ </affiliation>
+ </author>
+ <edition>User's guide 1.01</edition>
+ <pubdate>2002</pubdate>
+ <printhistory>
+ <para>Initial version in December 2001</para>
+ <para>First draft in February 2002</para>
+ <para>Unamended version missing part III in May 2002</para>
+ <para>Amended version missing part III in July 2002</para>
+ </printhistory>
+ <releaseinfo>This document is still missing its third part.</releaseinfo>
+ <publisher>
+ <publishername>Humboldt-Universität zu Berlin</publishername>
+ <address>
+ <street>Unter den Linden 6</street>
+ <postcode>10099</postcode> <city>Berlin</city>
+ <country>Germany</country>
+ </address>
+ </publisher>
+ <copyright>
+ <year>2001</year>
+ <year>2002</year>
+ <holder>Toby Neumann, Institut für Informatik, Humboldt-Universität zu Berlin</holder>
+ </copyright>
+ <legalnotice>
+ <para>This document describes the term processor &kpp;. &kpp; is free software;
+ you can redistribute it and/or modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either version 2 of the Licence,
+ or (at your option) any later version.</para>
+ <para>Likewise this documentation is free. Permission is granted to copy, distribute
+ and/or modify this document under the terms of the GNU Free Documentation License,
+ Version 1.1 or any later version published by the Free Software Foundation; with no
+ Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of
+ the license is included in the section entitled ‘GNU Free Documentation
+ License’.</para>
+ </legalnotice>
+ <legalnotice>
+ <para>The program &kpp; is based on Kimwitu (with its own <ulink
+ url="http://purl.oclc.org/net/kimwitu">web site</ulink>), written by
+ Axel Belinfante (<email>belinfan at utwente.nl</email>). Kimwitu is also free software,
+ licensed under the GPL, since its 4.6.1 release.</para>
+ </legalnotice>
+ </bookinfo>
+
+ <!-- Table of contents -->
+ <toc />
+
+ <!-- Begin the document -->
+
+ <part><title>Introduction to &kpp;</title>
+ <partintro>
+ <para>This part explains what essentially &kpp; is and what advantages it
+ provides. It gives an overview of the functionality of
+ &kpp;, which is demonstrated with example. Detailed discussion of concepts
+ is left to the reference part later in this book.</para>
+ </partintro>
+ &kpp-intro;
+ </part>
+
+
+ <part><title>Reference Manual</title>
+ <partintro>
+ <para>This part lists all concepts of &kpp; and explains them in detail.
+ It is meant as a complete documentation of all features and contains
+ advices of do's and don'ts. To the advanced user it should serve as
+ a programming reference.</para>
+ </partintro>
+ &kpp-manual;
+ </part>
+
+ <!--part><title>Cook Book</title>
+ <partintro>
+ <para>This part is not written yet. It should contain a bunch of examples
+ demonstrating the abilities of &kpp; applied to problems actually occurred.
+ Dear experienced <application>Kimwitu</application>/&kpp; users, please make suggestions to which
+ interesting or useful solutions should appear here!</para>
+ </partintro>
+ &kpp-cook;
+ </part-->
+
+ <!-- Appendix -->
+
+ &app-rpn;
+ &app-fdl;
+
+ </book>
+
+ <!-- vim:set sw=2 ts=8 tw=80: -->
Index: llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kpp-manual.xml
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kpp-manual.xml:1.1
*** /dev/null Tue Apr 6 15:25:33 2004
--- llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kpp-manual.xml Tue Apr 6 15:25:22 2004
***************
*** 0 ****
--- 1,2114 ----
+ <!--
+ <!DOCTYPE DocBook>
+
+ < kimwitu++ part II: manual >
+ -->
+
+ <chapter><title>Definition of Phyla</title>
+ <sect1><title>Basic Definition</title>
+ <para>A phylum definition consists of two sides. The left-hand side
+ specifies the phylum name, the right-hand side, behind a colon, a set of
+ alternative operators, which are separated by bars. An operator is
+ followed by a matching pair of parentheses, which may enclose a list of
+ phyla as arguments. A nullary operator has an empty list.
+ Example <xref linkend="exa:phylumdef"/> presents a basic definition with
+ operators of different arity.
+ Before the semicolon closing the definition an attribute block may appear.
+ The definition of a phylum follows the general form:</para>
+ <informalexample>
+ <programlisting role="none">
+ <![CDATA[ phylum := phylum_name ":" operator { "|" operator } [ attributes ] ";"
+ operator := operator_name "(" [ phylum_name ] { " " phylum_name } ")"]]>
+ </programlisting>
+ </informalexample>
+ <para>For the names of phyla and operators, the same restrictions hold as
+ for &cpp; identifiers.
+ Multiple definitions of of a phylum with the same name are interpreted
+ as additional alternative branches of the first definition.</para>
+ <para>There are some simple predefined phyla:
+ <classname>integer</classname><indexterm significance="preferred"><primary>integer</primary></indexterm>, <classname>real</classname><indexterm significance="preferred"><primary>real</primary></indexterm>,
+ <classname>casestring</classname><indexterm significance="preferred"><primary>casestring</primary></indexterm>,
+ and <classname>nocasestring</classname><indexterm significance="preferred"><primary>nocasestring</primary></indexterm>, representing integer values,
+ real values, case sensitive
+ strings, and case insensitive strings respectively. Terms of these are not
+ created by calls of operators but of special generated functions:
+ <function>mkinteger()</function><indexterm><primary>mkinteger</primary></indexterm>,
+ <function>mkreal()</function><indexterm><primary>mkreal</primary></indexterm>,
+ <function>mkcasestring()</function><indexterm><primary>mkcasestring</primary></indexterm> and
+ <function>mknocasestring()</function><indexterm><primary>mknocasestring</primary></indexterm>.
+ </para>
+ <para>The phylum
+ <classname>abstract_phylum</classname> represents the direct base of all
+ phyla. Adding properties, like attributes or methods, to it makes them
+ available for all phyla. Other direct bases may be specified for a phylum
+ by using the keyword
+ <constant>%base</constant><indexterm significance="preferred"><primary>%base</primary></indexterm>.
+ One of them has to be derived from <classname>abstract_phylum</classname>,
+ not necessarily directly. Example <xref linkend="exa:base"/> makes phylum
+ <classname>math_expression</classname> to be derived from a phylum
+ <classname>expression</classname> and a user defined &cpp; class
+ <classname>counter_class</classname>. </para>
+ <example id="exa:phylumdef">
+ <title>Definition of a Phylum</title>
+ <programlisting>
+ <![CDATA[expression:
+ Plus ( expression expression )
+ | Neg ( expression )
+ | Null ( ) ;]]>
+ </programlisting>
+ </example>
+ <example id="exa:base">
+ <title>Changing base of a phylum</title>
+ <indexterm><primary>%base</primary></indexterm>
+ <programlisting>
+ <![CDATA[ %base math_expression : expression, counter_class;
+
+ %{ KC_TYPES_HEADER /* code redirection */
+ class counter_class {
+ ...
+ };
+ %}]]>
+ </programlisting>
+ </example>
+ </sect1>
+ <sect1>
+ <title>List Phyla<indexterm id="idx:list_man" significance="preferred"
+ class="startofrange"><primary>list</primary></indexterm></title>
+ <indexterm><primary>phylum</primary><secondary>list</secondary><see>list</see></indexterm>
+ <para>A list phylum can be defined by using the basic form of phylum
+ definitions in a (right-) recursive way. The nullary operator constructs
+ a list which is empty, and the binary, a list which is concatenated of
+ a single list element and a list.
+ The other variant uses the predefined operator <constant>list</constant>
+ after which is specified the phylum of the list elements. The latter
+ notation is to prefer because it is concise and causes the generation of
+ additional list functions. That includes two operators which are named
+ according to the scheme which is used in the right-recursive definition
+ (prefixes <constant>Nil</constant> and
+ <constant>Const</constant>). Other names could be chosen as
+ well but this may cause some confusion. With either variants, a term is
+ created by calling one of the two operators.
+ The two definitions in example <xref linkend="exa:listdef"/> yield the
+ same list of elements of a phylum <classname>expression</classname>.
+ </para>
+ <example id="exa:listdef">
+ <title>Alternative Definitions of one List</title>
+ <programlisting>
+ <![CDATA[ expression_list:
+ Nilexpression_list ( )
+ | Consexpression_list ( expression expression_list )
+ ;
+
+ expression_list: list expression;]]>
+ </programlisting>
+ </example>
+ <indexterm class="endofrange" startref="idx:list_man"/>
+ </sect1>
+ <sect1><title>Attributes of Phyla<indexterm significance="preferred" class="startofrange" id="idx:attributes"><primary>attributes</primary></indexterm></title>
+ <para>A phylum definition may have an attribute part attached which is
+ enclosed in braces. It contains declarations of attributes of phylum types
+ or other &cpp; types and optionally their initial value assignment. After
+ that arbitrary &cpp; code can follow again enclosed in braces. This is the
+ general form of the attribute part:</para>
+ <informalexample>
+ <programlisting role="none">
+ <![CDATA[ attributes := "{" {attr_type " " attr_name [ "=" init_value ] ";"} [ cpp_part ] "}"
+ cpp_part := "{" arbitrary_cpp_code "}"]]>
+ </programlisting>
+ </informalexample>
+ <para>In particular, the initialization of attributes can be done in the
+ &cpp; part too; though technically then it is not initialization, but
+ assignment. Attributes may also be defined outside the phylum
+ definition according to the general form beneath.</para>
+ <informalexample>
+ <programlisting role="none">
+ <![CDATA[ attributes := "%attr " attr_type phylum_name "::" attr_name ";"
+ members := "%member " attr_type phylum_name "::" attr_name ";"]]>
+ </programlisting>
+ </informalexample>
+ <para>Only attributes of phylum types can be defined with
+ <constant>%attr</constant><indexterm><primary>%attr</primary></indexterm>.
+ This is because they are considered part of the enclosing phylum by &kpp;.
+ When a term is written to a file using the CSGIO functions (see <xref
+ linkend="sec:csgiofuncs"/>), its
+ attributes are saved and can thus be restored.</para>
+ <para>Using the keyword
+ <constant>%member</constant><indexterm><primary>%member</primary></indexterm>
+ instead allows also &cpp; types to be used. The values of attributes
+ defined in this way will get lost when their term is written to a
+ file. Restoring a saved term will assign the initial values to all
+ <constant>%member</constant> attributes.</para>
+ <para>The &cpp; code is executed after the term creation and the attribute
+ initializations. Inside that code the newly created term can be referred
+ to as
+ <varname>$0</varname><indexterm><primary>$0</primary></indexterm>.
+ Attributes are accessed via the operator
+ <constant><![CDATA[->]]></constant>. Each predefined phylum has an
+ attribute which holds its value, which is <varname>value</varname> for
+ <classname>integer</classname><indexterm><primary>integer</primary></indexterm>
+ and
+ <classname>real</classname><indexterm><primary>real</primary></indexterm>,
+ and <varname>name</varname> for
+ <classname>casestring</classname><indexterm><primary>casestring</primary></indexterm>
+ and
+ <classname>nocasestring</classname><indexterm><primary>nocasestring</primary></indexterm>.
+ Example <xref linkend="exa:alter"/> shows three alternative ways to define
+ and initialize one attribute (of &cpp; type). </para>
+ <example id="exa:alter">
+ <title>Alternative Definitions of one Attribute</title>
+ <programlisting>
+ <![CDATA[ expression: Div ( expression expression )
+ { bool is_valid = true; };
+
+ expression: Div ( expression expression )
+ { bool is_valid;
+ { $0 -> is_valid = true; } };
+
+ expression: Div ( expression expression );
+ %member bool expression::is_valid = true;]]>
+ </programlisting>
+ </example>
+ <indexterm class="endofrange" startref="idx:attributes"/>
+ </sect1>
+ <sect1><title>Supplemental Definitions</title>
+ <para>It is possible to supplement the classes which will be generated from
+ phylum definitions with additional methods. These are defined as usual but
+ have as qualifier the name of either a phylum or of an operator. Such a
+ method is known for all terms of the phylum or only for those constructed
+ by the specified operator. Predefined phyla can get additional methods
+ too. </para>
+ <example id="exa:methods">
+ <title>Additional Methods Definitions</title>
+ <programlisting>
+ <![CDATA[ bool aritherm::equals( aritherm a ) {...}
+
+ int Number::get_int( ) {...}
+
+ nocasestring casestring::convert_to_nocase( ) {...}]]>
+ </programlisting>
+ </example>
+ <para>It may appear desirable to initialize
+ attributes<indexterm> <primary>attributes</primary></indexterm> of a phylum
+ with non-default values immediately at term creation. This can be realized
+ by using the &kpp; keyword <constant>%ctor</constant><indexterm
+ significance="preferred"><primary>%ctor</primary></indexterm> to define
+ own constructors which will replace the default ones. Additional
+ constructors are possible for phyla as well as for operators, but not for
+ predefined phyla. </para>
+ <para>
+ If these constructors are defined to have arguments then of some points
+ are to take note. First, when used with operators the arguments will be
+ added to those in the operator definition. Second, since the default
+ constructors are replaced but relied on by some internal mechanism, the
+ user has to define new ones or alternatively just provide default values
+ for all new arguments. The latter may cause performance loss in the case
+ of many or non-simple arguments.</para>
+ <para>The keyword <constant>%dtor</constant><indexterm
+ significance="preferred"><primary>%dtor</primary></indexterm> allows
+ own destructor definitions for freeing memory of attributes or something
+ similar. It is applicable to phyla and operators but not to predefined
+ phyla.</para>
+ <example id="exa:cdtor">
+ <title>User provided Constructors and Destructors</title>
+ <programlisting>
+ <![CDATA[ %ctor simpleterm( int i ) {...}
+ %ctor simpleterm( ) {...}
+
+ %ctor Minus( bool neg = true ) {...}
+ // Minus now has 3 arguments, but the third is optional
+
+ %dtor virtual term( ) {...}]]>
+ </programlisting>
+ </example>
+ </sect1>
+ <sect1><title>Phylum Storage Options</title>
+ <indexterm><primary>storage options</primary><see>storage class</see></indexterm>
+ <indexterm id="idx:storage" class="startofrange"><primary>storage class</primary></indexterm>
+ <para>For every phylum a &cpp; class is generated, with one create-method for
+ every operator. A term is created by calling the appropriate method, which
+ returns a pointer to the object representing the term. As a default for
+ every such object a new cell is allocated in memory. But the user may
+ influence the memory management for optimization purposes. At phylum
+ definition time the phylum can be declared to use a special storage class.
+ There is one predefined storage class: <constant>uniq</constant><indexterm
+ significance="preferred" class="startofrange" id="uniq"><primary>uniq</primary></indexterm>.
+ It is allowed to specify <constant>!uniq</constant> what is the same as
+ specifying nothing and results in usage of the default storage.
+ Subphyla of a phylum with storage class can not use the default storage,
+ but
+ must be defined with a storage class too. The completed
+ general form of a phylum definition is the following one.</para>
+ <informalexample>
+ <programlisting role='none'>
+ <![CDATA[ phylum := phylum_name [ "{" storage_class "}" ] ":" operator
+ { "|" operator } [ attributes ] ";"]]>
+ </programlisting>
+ </informalexample>
+ <example id="exa:storage">
+ <title>Phylum with Storage Class</title>
+ <programlisting>
+ <![CDATA[ aritherm {!uniq} : Plus ( aritherm aritherm );
+
+ simpleterm {uniq} : Number ( integer );]]>
+ </programlisting>
+ </example>
+ <para>The first phylum in example <xref linkend="exa:storage"/> declares
+ explicitly to use the default storage. All other phyla defined until now
+ got that implicitly. Memory of such terms can be freed individually,
+ terms of the second phylum can not. They are kept under
+ <constant>uniq</constant> storage. What does this mean?
+ Each storage class has a <indexterm><primary>hashtables</primary>
+ </indexterm> hashtable assigned. All terms
+ of phyla with that class are stored there. If a term is to be created the
+ create routine does conditionally allocate new storage. It
+ checks first whether there is already stored an object created with the
+ same arguments. If found true, the routine will return a pointer to that
+ object in memory. Such every term is created only once. All predefined
+ phyla, such as <classname>integer</classname>, are declared
+ <constant>uniq</constant><indexterm
+ significance="preferred" class="endofrange" startref="uniq"/>. So the
+ example has the effect that if two &simpleterm;s are created from the
+ same <constant>int</constant> value they will both point to the same
+ memory cell.</para>
+ <para>It is possible to define additional storage classes, which each get
+ their own table. Tables also can be explicitly created and assigned to
+ storage classes, as well as cleared or freed (see <xref
+ linkend="sec:hashtable"/>).
+ Example <xref linkend="exa:ownstorage"/> declares two additional storage
+ classes and defines two phyla using them.
+ </para>
+ <example id="exa:ownstorage">
+ <title>Storage Class Definition and Application</title>
+ <programlisting>
+ <![CDATA[ %storageclass table1 table2;
+
+ intermediate {table1}: Div ( aritherm aritherm );
+
+ final {table2}: Ident ( casestring );]]>
+ </programlisting>
+ </example>
+ <!-- Always move to end of enclosing chapter -->
+ <para><indexterm class="endofrange" startref="idx:storage"/></para>
+ </sect1>
+ </chapter>
+
+ <chapter><title>Processing phyla</title>
+ <sect1>
+ <title>Pattern Matching<indexterm
+ significance="preferred"><primary>patterns</primary></indexterm></title>
+ <para>Patterns make it easier to select terms and subterms and to
+ distinguish cases. They appear in rules for rewriting and unparsing and in
+ &with;- and &foreach;-statements. Here there are explained common features
+ while the slight differences will be mentioned in the appropriate place.
+ </para>
+ <para>The term ‘pattern’ can be defined through induction.
+ Each of the following is a pattern in the context of &kpp;:
+ </para>
+ <orderedlist>
+ <listitem id="i:patternlit"><para>the literal of a predefined phylum or the
+ asterisk sign,</para></listitem>
+ <listitem><para>the phylum operator with zero or more patterns as arguments,</para>
+ </listitem>
+ <listitem><para>the assignment of a pattern to a variable, and</para>
+ </listitem>
+ <listitem id="i:patternenum"><para>the enumeration of patterns delimited by
+ commas.</para></listitem>
+ </orderedlist>
+ <para>Additionally some restrictions hold regarding the use of patterns. The
+ patterns of item <xref linkend="i:patternlit"/> are not allowed as the
+ outermost pattern, while these of item <xref linkend="i:patternenum"/>
+ are allowed only as the outermost pattern. The assignment of an asterisk
+ to a variable can be abbreviated by stating only the variable.</para>
+ <para>If more than one pattern matches a term, the most specific pattern is
+ chosen. If there is no most specific one, the first of the matches is
+ chosen. The matched term can be accessed
+ as <varname>$0</varname><indexterm><primary>$0</primary></indexterm>,
+ its first subterm<indexterm><primary>subterm</primary></indexterm> as
+ <varname>$1</varname>, the second as <varname>$2</varname> etc. (not in
+ rewrite rules). Table <xref linkend="tab:patterns"/> lists pattern
+ examples, which are in each group equally specific. &kpp; is
+ not yet able to decide between more
+ complex patterns (maybe partly overlapping each other) which to be most
+ specific, but chooses the first found.</para>
+ <table id="tab:patterns"><title>Pattern groups increasingly specific</title>
+ <tgroup cols='2' align='left' colsep='1' rowsep='1'>
+ <?latex-table-type tabularx?>
+ <?latex-table-option {\textwidth}?>
+ <?latex-table-head p{0.33\textwidth}X?>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <thead>
+ <row>
+ <entry>pattern</entry>
+ <entry>matches</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><constant>*</constant></entry>
+ <entry>any term; not allowed as the outermost pattern.</entry>
+ </row>
+ <row>
+ <entry>—</entry>
+ <entry>—</entry>
+ </row>
+ <row>
+ <entry><constant>SimpleTerm</constant></entry>
+ <entry>term <constant>SimpleTerm</constant> with an unspecified
+ number of subterms; only allowed as the outermost pattern.</entry>
+ </row>
+ <row>
+ <entry><constant>SimpleTerm(*)</constant></entry>
+ <entry>term <constant>SimpleTerm</constant> with a subterm.</entry>
+ </row>
+ <row>
+ <entry><constant>a=SimpleTerm(b)</constant></entry>
+ <entry>term <constant>SimpleTerm</constant> with a subterm; the term
+ is assigned to a variable <varname>a</varname>, the subterm, to
+ <varname>b</varname>.</entry>
+ </row>
+ <row>
+ <entry><constant>Number(7)</constant></entry>
+ <entry>term <constant>Number</constant> with an
+ <classname>integer</classname> subterm of value the
+ <literal>7</literal>.</entry>
+ </row>
+ <row>
+ <entry><constant>SimpleTerm(*),Mul(b,b)</constant></entry>
+ <entry>either term <constant>SimpleTerm</constant> with a subterm or
+ term <constant>Mul</constant> with two subterms which are
+ structurally equal (the first of the two is assigned to
+ <varname>b</varname>).</entry>
+ </row>
+ <row>
+ <entry>—</entry>
+ <entry>—</entry>
+ </row>
+ <row>
+ <entry><constant>SimpleTerm(Number(*))</constant></entry>
+ <entry>term <constant>SimpleTerm</constant> with a subterm being a
+ <constant>Number</constant>.</entry>
+ </row>
+ <row>
+ <entry><constant>a=SimpleTerm(Number(b))</constant></entry>
+ <entry>term <constant>SimpleTerm</constant> with a subterm being a
+ <constant>Number</constant>; the term is
+ assigned to <varname>a</varname> and the sub-subterm to
+ <varname>b</varname>.</entry>
+ </row>
+ <row>
+ <entry>—</entry>
+ <entry>—</entry>
+ </row>
+ <row>
+ <entry><constant><![CDATA[SimpleTerm(Number(b))
+ provided (b->value!=0)]]></constant></entry>
+ <entry>term <constant>SimpleTerm</constant> with a subterm
+ being a <constant>Number</constant>, which is
+ assigned to <varname>b</varname>, but matches only if the
+ <classname>integer</classname> <varname>b</varname> is not zero.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="sec:statements"><title>&kpp; Control Structures</title>
+ <para>&kpp; provides two control structures which help dealing with
+ terms: the
+ &with;<indexterm significance="preferred"><primary>&with;</primary></indexterm>-statement and the
+ &foreach;<indexterm significance="preferred"><primary>&foreach;</primary></indexterm>-statement. They appear in
+ different variants, fitting slightly different purposes. </para>
+ <sect2><title>Explicit
+ &with;<indexterm><primary>&with;</primary><secondary>explicit</secondary></indexterm></title>
+ <para>The &with;-statement is similar to a &cpp;
+ <constant>switch</constant>
+ and decides for a given term which alternative branch to choose. The
+ alternatives are patterns describing &kind;s of one phylum and have
+ assigned a &cpp; block, maybe an empty one.</para>
+ <para>The example <xref linkend="exa:withex"/> lists a code piece
+ containing an explicitly stated &with;. It decides whether the term
+ <varname>a</varname> is an identifier or a number and executes its code.
+ That term is accessable throughout the whole &with; body unless
+ an other term is assigned to the variable <varname>a</varname>, as it is
+ done in the second case. There, variable <varname>a</varname> gets
+ assigned the subterm of the <constant>Number</constant>.
+ The special pattern <constant>default</constant> matches when the
+ preceding patterns do not. Here this would never occur, because a
+ &simpleterm; is defined to be one of the two specified.
+ If no default case is specified and none of the patterns matches the
+ term a runtime exception is released (program execution aborted).
+ The pattern <constant>default</constant> is allowed in all
+ &with;-variants (implicit-, explicit-, and &foreach;-&with;).</para>
+ <example id="exa:withex">
+ <title>Explicit &with;</title>
+ <programlisting>
+ <![CDATA[ simpleterm a;
+ ...
+ with( a ){
+ Ident( * ) : { $0 -> computable = false; }
+ c=Number( a ) : { c -> computable = true; c -> result = a -> value; }
+ default : { // never reached, because simpleterm has only
+ // the above two ]]>&kind;<![CDATA[s
+ }
+ }
+ ]]>
+ </programlisting>
+ </example>
+ </sect2>
+ <sect2><title>Implicit
+ &with;<indexterm><primary>&with;</primary><secondary>implicit</secondary></indexterm></title>
+ <para>If a function is defined to have a phylum argument whose variable
+ name begins with a dollar sign, the function body is assumed to be
+ the body of an implicitly given &with;-statement. Example <xref
+ linkend="exa:withim"/> presents a function which returns
+ <literal>true</literal> if the given &aritherm;
+ matches one of
+ the specified patterns, that is represents an arithmetic term. If the
+ term has the &kind; <constant>SimpleTerm</constant>, the default case
+ would catch.</para>
+ <example id="exa:withim">
+ <title>Implicit &with;</title>
+ <programlisting>
+ <![CDATA[ bool is_arithmetic_term( aritherm $a ) {
+ Plus, Minus, Mul, Div: { return true; }
+ default: { return false; }
+ }
+ ]]>
+ </programlisting>
+ </example>
+ </sect2>
+ <sect2><title>Simple &foreach;</title>
+ <para>The &foreach;-statement is a loop which runs over all elements of a
+ term which is a list phylum and executes at every run the code which is
+ specified in the statement body.</para>
+ <para>The &foreach; in example <xref linkend="exa:simpleforeach"/> counts
+ the appearances of arithmetic terms by calling the function
+ <function>is_arithmetic_term</function> for <varname>a</varname>
+ during each run. This variable holds the current list element.</para>
+ <example id="exa:simpleforeach">
+ <title>Simple foreach</title>
+ <programlisting>
+ <![CDATA[ int count = 0;
+ foreach( a; arithermlist A ) {
+ if( is_arithmetic_term( a ) ) count++;
+ }
+ ]]>
+ </programlisting>
+ </example>
+ </sect2>
+ <sect2><title>&foreach;-&with;<indexterm><primary>&foreach;-&with;</primary></indexterm></title>
+ <para>This foreach variant also steps through a list, but performs a
+ &with; for every element. A dollar prefixed list variable is used
+ instead of a simple variable. The statement body contains patterns with
+ a &cpp; block assigned to each.
+ Example <xref linkend="exa:foreachwith"/>
+ demonstrates the usage. It counts the number of sums and differences
+ within the term list.</para>
+ <example id="exa:foreachwith">
+ <title>&foreach;-&with;</title>
+ <programlisting>
+ <![CDATA[ int num_plus = 0;
+ int num_minus = 0;
+ foreach( $a; arithermlist A ) {
+ Plus: { num_plus++; }
+ Minus: { num_minus++; }
+ }
+ ]]>
+ </programlisting>
+ </example>
+ </sect2>
+ <sect2><title>&foreach; with Pattern</title>
+ <para>This third variant of &foreach; allows to specify a pattern instead
+ of
+ a list variable. The action is executed only for those list elements
+ which match the pattern. Thus it combines &foreach; and an implicit
+ &with; containing only one pattern of interest. Example <xref
+ linkend="exa:foreachpat"/> is similar to example <xref
+ linkend="exa:foreachwith"/> but it counts only the number of sums in the
+ list.</para>
+ <example id="exa:foreachpat">
+ <title>&foreach; with Pattern</title>
+ <programlisting>
+ <![CDATA[ int num_plus = 0;
+ foreach( Plus( *, * ); arithermlist A ) {
+ num_plus++;
+ }
+ ]]>
+ </programlisting>
+ </example>
+ </sect2>
+ <sect2><title>Multiple Patterns<indexterm><primary>multiple
+ patterns</primary></indexterm></title>
+ <para>For every one of the preceding statements it is possible to specify
+ not only one but multiple variables or patterns respectively. Used with
+ &foreach;, multiple lists can be iterated over at one time. The
+ variables or patterns are separated by ampersand signs (&), the list
+ specifications by commas. Used with &with;, multiple terms can be
+ checked at one time whether matching complex patterns. Here, the
+ variables are separated by commas.</para>
+ <para>The complex patterns are made up by concatenating
+ single patterns by ampersand signs
+ (&)<indexterm><primary>&</primary></indexterm>, where the first
+ pattern has to match the first term, the second the second term (and so
+ on) to have the complex pattern to match. A complex pattern can also be
+ a grouping of patterns, but then it must be enclosed in
+ parentheses.</para>
+ <para>Example <xref linkend="exa:multipat"/> shows a &with; over two
+ variables. The statement simply prints out whether the two terms have
+ the same &kind;.</para>
+
+ <example id="exa:multipat">
+ <title>Multiple Patterns in &with;</title>
+ <programlisting>
+ <![CDATA[ simpleterm a, b;
+ ...
+ with ( a, b ) {
+ Number & Number: { std::cout << "numbers" << std::endl; }
+ Ident & Ident: { std::cout << "identifiers" << std::endl; }
+ Number & (Number, Ident): { std::cout << "first num" << std::endl; }
+ default: { std::cout << "first ident" << std::endl; }
+ }
+ ]]>
+ </programlisting>
+ </example>
+ </sect2>
+ <sect2><title><constant>afterforeach</constant><indexterm><primary>afterforeach</primary></indexterm></title>
+ <para>When a &foreach; iterates over more than one list at one time, the
+ execution will stop if one of the lists reaches its end, while the others
+ may still contain elements. The
+ <constant>afterforeach</constant>-statement is useful
+ if it is desired to iterate further over the remainders of the lists. The
+ variables of the <constant>afterforeach</constant> refer to the list
+ remainders. Their phyla are already known
+ from the preceding &foreach;. The
+ code fragment in example <xref linkend="exa:afterfor"/> uses
+ &foreach;-&with; and
+ <constant>afterforeach</constant> to decide whether list
+ <varname>A</varname> is longer than list <varname>B</varname>, returning
+ <literal>true</literal> if it is.</para>
+ <example id="exa:afterfor">
+ <title><constant>afterforeach</constant> in Length Test</title>
+ <programlisting>
+ <![CDATA[ foreach( $a & $b; arithermlist A, arithermlist B ) {
+ default: { /* do nothing */ }
+ }
+ // at least one list ran out of elements
+ afterforeach( $a & $b ) {
+ Consarithermlist & Nilarithermlist: { return true;
+ /* A has elements, B doesn't */ }
+ default: { return false; }
+ }
+ ]]>
+ </programlisting>
+ </example>
+ </sect2>
+ </sect1>
+ <sect1>
+ <title>Rewriting<indexterm
+ significance="preferred" id="idx:rewriting"
+ class="startofrange"><primary>rewriting</primary></indexterm></title>
+ <para>The process of rewriting transforms a term tree. The left-hand side of
+ each rewrite rule is a pattern specifying which term to substitute. The
+ right-hand side denotes the term to substitute by, which has to be of the
+ same phylum as the original one. This is done by calls of operators and
+ term returning functions. Variables from the left-hand side may be used.
+ Example <xref linkend="exa:rewrite2"/> simplifies terms by replacing every
+ sum of numbers by its evaluated result. A helper function is necessary
+ since it is not possible directly to use &cpp; operators in a
+ rewrite rule (except method calls, see <xref linkend="sec:restriction"/>). </para>
+ <example id="exa:rewrite2">
+ <title>Rewriting</title>
+ <programlisting>
+ <![CDATA[ Plus( SimpleTerm( Number( a ) ), SimpleTerm( Number( b ) ) ) ->
+ <: SimpleTerm( Number( plus( a, b ) ) ) >;
+
+ %{ KC_REWRITE /* code redirection */
+ integer plus( integer a, integer b ){
+ return mkinteger( a -> value + b -> value );
+ }
+ %}]]>
+ </programlisting>
+ </example>
+ <para>To allow rewriting to end, each rule has to replace the
+ term in question by one which is really simpler, reduced, or closer to a
+ normal form. Since rewriting searches depth first, the
+ subterms<indexterm><primary>subterm</primary></indexterm> are usually
+ already the result of a transformation.
+ Calling the
+ <function>rewrite</function><indexterm><primary>rewrite()</primary></indexterm> method of the root term
+ starts the transforming process for the tree. Choosing an arbitrary term
+ instead rewrites the subtree beneath. </para>
+ <indexterm class="endofrange" startref="idx:rewriting"/>
+ </sect1>
+ <sect1>
+ <title>Unparsing<indexterm class="startofrange" significance="preferred"
+ id="idx:unparsing"><primary>unparsing</primary></indexterm></title>
+ <para>The process of unparsing traverses a term tree and executes the
+ instructions for every term matching a pattern as specified in the unparse
+ rules. The left-hand side of a rule denotes a term pattern, the right-hand
+ side a list of unparse items which are evaluated for matching terms. The
+ various items allowed are listed below and appear all in example <xref
+ linkend="exa:unparseitems"/>, which is completely nonsensically.
+ </para>
+ <variablelist>
+ <varlistentry><term>string</term>
+ <listitem><para>Text strings in double quotes are delivered to the
+ printer unchanged.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term>variable</term>
+ <listitem><para>The term denoted by this term variable will be
+ unparsed by calling its <function>unparse</function>-method.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term>attribute</term>
+ <listitem><para>The
+ attribute<indexterm><primary>attributes</primary></indexterm> of
+ a term will be unparsed by calling
+ its
+ <function>unparse</function><indexterm><primary>unparse()</primary></indexterm>-method. If it is of non-phylum
+ type the user has to provide such a method.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term>&cpp; code</term>
+ <listitem><para>Inside a pair of braces arbitrary &cpp; code may be
+ placed. </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term>escaped braces</term>
+ <listitem><para><indexterm><primary>${</primary></indexterm>
+ <indexterm><primary>$}</primary></indexterm>
+ If a non-matching brace is needed it has to be escaped by a dollar sign.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term>variable with view</term>
+ <listitem><para>A view can be specified if a variable should be
+ unparsed under other than the current view (see <xref linkend="sec:viewclass"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term>unparse view variable definition</term>
+ <listitem><para>Variables of user defined unparse view classes can be
+ defined inside a rule (see <xref linkend="sec:viewclass"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <example id="exa:unparseitems">
+ <title>Unparse Items</title>
+ <programlisting>
+ <![CDATA[ Mul( a, b ) -> [: "zero"
+ a
+ b->result
+ { if (a->value == 0) } ${
+ a:infix
+ $}
+ %uviewvar prefix p1;
+ a:p1
+ ];]]>
+ </programlisting>
+ </example>
+ <para>For every operator, there is a default pattern which matches if
+ no other pattern does. Its associated rule unparses all subterms<indexterm><primary>subterm</primary></indexterm>.
+ The <function>unparse</function>-method
+ generated for every phylum can also be called explicitly. It has 3
+ arguments: the term to be unparsed, a printer and an
+ unparse view. The names <varname>kc_printer</varname><indexterm><primary>kc_printer</primary></indexterm> and
+ <varname>kc_current_view</varname><indexterm><primary>kc_current_view</primary></indexterm>
+ respectively refer to the printer and the view
+ which are currently in use.</para>
+ <sect2><title>Printer</title>
+ <indexterm id="idx:printer"
+ class="startofrange"><primary>printer</primary></indexterm>
+ <para>The user himself has to provide a printer function which satisfies
+ his needs. Usually it prints to the standard output or into some file,
+ and may take actions dependent on the view.
+ </para>
+ <informalexample>
+ <programlisting>
+ void printer( const char* the_string, uview the_view ) { ... };
+ </programlisting>
+ </informalexample>
+ <para>
+ Since several printer instances may be needed also a printer functor
+ can be
+ specified as the printer. The printer functor class must be derived
+ <constant>public</constant> from the class
+ <classname>printer_functor_class</classname>.</para>
+ <informalexample>
+ <programlisting>
+ %{ HEADER /* redirection since no class definitions allowed in .k */
+ class example_printer : public printer_functor_class {
+ public:
+ void operator( ) ( const char* the_string, uview the_view ) { ... };
+ }
+ %}
+ </programlisting>
+ </informalexample>
+ <!-- Always move to end of enclosing sect2 -->
+ <para><indexterm class="endofrange" startref="idx:printer"/></para>
+ </sect2>
+ <sect2><title>Language Options</title>
+ <indexterm><primary>language options</primary></indexterm>
+ <para>Often a term tree has to be pretty printed into different but
+ similar destination languages, which sometimes require only slightly
+ different output to be generated. To avoid whole rule sets to be
+ multiplied and to allow a more flexible choice concerning the
+ destination language, the concept of language options has been
+ introduced.
+ Every unparse item can be preceded by a language option, which is a
+ language name in angle brackets followed by a colon. That item will be
+ unparsed only if the language specified is active. Languages are
+ declared using the keyword
+ <constant>%language</constant><indexterm><primary>%language</primary></indexterm>
+ and they are set by
+ calling
+ <function>set_language(...)</function><indexterm><primary>set_language()</primary></indexterm>. The active language can
+ be checked by calling
+ <function>is_language(...)</function><indexterm><primary>is_language()</primary></indexterm>. The
+ language names must satisfy the requirements for &cpp; identifiers.
+ Example
+ <xref linkend="exa:langopt"/> demonstrates the application of language
+ options. </para>
+ <example id="exa:langopt"><title>Language Options</title>
+ <programlisting>
+ <![CDATA[ %language CPP, JAVA;
+
+ ClassDefinition( name, base_name, class_body ) ->
+ [: <JAVA>: "public " "class " name
+ <JAVA>: " extends " <CPP>: " : "
+ base_name " {\n" class_body "}"
+ <CPP>: ";"
+ "\n"
+ ];
+ ]]>
+ </programlisting>
+ </example>
+ <!-- Always move to end of enclosing sect1 -->
+ <para><indexterm class="endofrange" startref="idx:unparsing"/></para>
+ </sect2>
+ </sect1>
+ <sect1 id="sec:viewclass"><title>View
+ Classes<indexterm significance="preferred" class="startofrange"
+ id="idx:view_man"><primary>view</primary></indexterm></title>
+ <para>Rewriting and unparsing of each term is done under a certain view. The
+ view serves as a means to further differentiate between rules when
+ choosing one to apply. To be a match a rule must have the current view
+ to appear in its view list, which is the left part of the right-hand side
+ between the bracket and the colon. If no rule matches the rules with
+ empty list are considered. Below is shown the general form of rules with
+ views. </para>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ rewrite_rule := pattern "->" "<" rview_list ":" {operator|function} ">;"
+ unparse_rule := pattern "->" "[" uview_list ":" unparse_items "];"]]>
+ </programlisting>
+ </informalexample>
+ <para>Views are declared by enumerating them after the keyword
+ <constant>%rview</constant><indexterm
+ significance="preferred"><primary>%rview</primary></indexterm> and
+ <constant>%uview</constant><indexterm
+ significance="preferred"><primary>%uview</primary></indexterm> for
+ rewriting and unparsing respectively, separated by a space or
+ a comma. These declarations enable &kpp; to check for view consistency,
+ although it is possible to leave them out entirely. But that
+ should be avoided, because then even simple misspellings in a view list
+ cause the implicit introduction of new views. One view is predefined for
+ rewriting and unparsing respectively,
+ <varname>base_rview</varname><indexterm
+ significance="preferred"><primary>base_rview</primary></indexterm> and
+ <varname>base_uview</varname><indexterm
+ significance="preferred"><primary>base_uview</primary></indexterm>,
+ which is implicitly included in the empty view list.</para>
+ <para>The view can be changed for a term by calling its
+ <function>rewrite/unparse</function><indexterm><primary>rewrite()</primary></indexterm>-method
+ with a new view argument. In unparse rules there the same can also
+ be achieved by appending a colon and a new view name to a variable unparse
+ item. Thus a whole subtree can be rewritten/unparsed under a different
+ view, or even multiple times under changing views. Changing views allows
+ to interlock several tasks on a certain subtree. </para>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ %rview demo1 ;
+
+ Plus( a, SimpleTerm( Number( 0 ) ) ) -> <: a -> rewrite( demo1 ) >;
+
+ %uview demo2 ;
+
+ Plus( a, b ) -> [: a:demo2 { b->unparse( kc_printer, demo2 ); } ];
+ // both subterms of Plus are further unparsed under view demo2;]]>
+ </programlisting>
+ </informalexample>
+ <para><indexterm id="idx:viewclass"
+ class="startofrange"><primary>view</primary><secondary>class</secondary></indexterm>Every
+ view introduced by the user actually causes the generation of a view
+ class and one view variable of the same name. Since the user cannot
+ distinguish them, the generalizing term ‘view’ is used.
+ For unparse views that may matter since the user can define his own
+ unparse view classes. These are declared by
+ enclosing the view name in parentheses. The user has
+ to provide a class <varname>view</varname><classname>_class</classname>
+ derived from a generated class
+ <varname>view</varname><classname>_baseclass</classname>. In particular,
+ that class may contain member variables to hold information persistent
+ over several rules. The base class provides an equality
+ operator (<function>==</function>) deciding whether two view variables
+ are of the same class and a
+ <function>name</function>-method returning the name of the view.</para>
+ <para>No global view variable of the same name is generated for a user
+ defined unparse view class. Variables of such a view are instantiated
+ inside of unparse rules by <constant>%uviewvar</constant><indexterm
+ significance="preferred"><primary>%uviewvar</primary></indexterm>
+ and may bear the same name as their class. They can be used
+ like the implicitly created view variables, but
+ additionally provide all features of their class. Example <xref
+ linkend="exa:uviewvar"/> shows the definition of an unparse view class and
+ demonstrates its usage.</para>
+ <example id="exa:uviewvar">
+ <title>User defined Unparse View Class</title>
+ <programlisting>
+ <![CDATA[ %uview ( number_count ) ;
+
+ %{ KC_UNPARSE /* code redirection to where it is needed */
+ class number_count_class : public number_count_baseclass {
+ public:
+ number_count_class() : counter( 0 ) { };
+ int counter;
+ };
+ %}
+
+ c=Plus, c=Minus, c=Mul, c=Div, c=SimpleTerm -> [:
+ %uviewvar number_count nc; // instantiate view variable
+ c:nc // and unparse c with it
+ { std::cout << "Numbers counted: " << nc.counter << std::endl; }
+ ];
+ Plus( a, b ), Minus( a, b ), Mul( a, b ), Div( a, b )
+ -> [ number_count: a b ];
+ SimpleTerm( a ) -> [ number_count: a ];
+ Number -> [ number_count: { kc_current_view.counter++; } ];
+ Ident -> [ number_count: ];]]>
+ </programlisting>
+ </example>
+ <para>View lists contain names of view classes, all other occurrences of
+ views actually are view variables. The scope of an unparse view variable
+ ends with its defining rule. Since its
+ name is not known inside other rules there it can be accessed only by
+ means of the name <varname>kc_current_view</varname><indexterm><primary>kc_current_view</primary></indexterm>, which always
+ refers to the view variable currently used. </para>
+ <indexterm class="endofrange" startref="idx:viewclass"/>
+ <indexterm class="endofrange" startref="idx:view_man"/>
+ </sect1>
+ <sect1 id="sec:restriction"><title>Restrictions on &cpp; in &kpp;</title>
+ <para>There are many places
+ in a <filename>.k</filename>-file where &cpp; code can be used. But for
+ some of them, the &kpp; processor allows only restricted use of &cpp;
+ constructs. These places are listed in the following along with the
+ restrictions they impose.</para>
+ <variablelist>
+ <varlistentry><term><filename>.k</filename>-file</term>
+ <listitem><para>Only function definitions are allowed. These
+ must have no types as arguments which have compound names
+ (for example no <constant>long int</constant>). &cpp;
+ comments<indexterm><primary>comments</primary></indexterm> are
+ allowed everywhere in <filename>.k</filename>-files.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term>&cpp; unparse item</term>
+ <listitem><para>Almost arbitrary &cpp; code is allowed, that is,
+ everything which is allowed inside a local &cpp; block. </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term>rewrite rule</term>
+ <listitem><para>Only simple function calls are allowed, that is, calls
+ which have as arguments only term variables and term literals,
+ phylum operators and other simple function calls; in particular no
+ &cpp; operators, except access of member functions.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term>code redirection</term>
+ <listitem><para>Arbitrary &cpp; code is allowed, but it has to be pure
+ &cpp; since redirection code is not evaluated by &kpp;.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>There is a way to get around the restrictions of the &kpp; processor
+ using macros. A macro is defined inside a code redirection, which the
+ processor does not evaluate. Therefore it can
+ be as complex as necessary, while the macro call inside the rewrite rule
+ looks as simple as &kpp; wishes. Example
+ <xref linkend="exa:rewrite2"/> defines a function for addition, which can be
+ avoided when using a macro as in example <xref linkend="exa:macro"/>.
+ </para>
+ <example id="exa:macro">
+ <title>Macro Application in Rewriting</title>
+ <programlisting>
+ <![CDATA[ Plus( SimpleTerm( Number( a ) ), SimpleTerm( Number( b ) ) ) ->
+ <: SimpleTerm( Number( PLUS( a, b ) ) ) >;
+
+ %{ KC_REWRITE /* code redirection */
+ #define PLUS( a, b ) mkinteger( ( a ) -> value + ( b ) -> value )
+ %}]]>
+ </programlisting>
+ </example>
+ <para>Some generated functions return terms of the phylum
+ <classname>abstract_phylum</classname> which have to be cast to the
+ actual phylum. The &cpp; cast operators may be used also for phylum
+ conversion<indexterm><primary>phylum</primary><secondary>conversion</secondary></indexterm>
+ but &kpp; provides
+ <function>phylum_cast</function><indexterm><primary>phylum_cast</primary></indexterm>,
+ a cast operator for phyla, which is better to use. </para>
+ </sect1>
+ </chapter>
+
+ <chapter><title>Generated Code</title>
+ <para>From the &kpp; definitions, rules and &cpp; code pieces, several classes
+ and functions in pure &cpp; are generated and distributed over multiple
+ files. Compiled, they will perform the desired tree handling.
+ Additional code is needed to create the trees, probably created by scanner
+ and parser generators, for instance <application>Flex</application> and
+ &bison;.</para>
+ <sect1><title>Generated Classes and Types</title>
+ <para>The definition of phyla and operators result in generated &cpp;
+ classes.
+ But these should be of no further interest for the user since the phylum
+ names can be used in &cpp; code as if being pointer types of these
+ classes, the operators as if being &cpp; constructors.
+ Every phylum has a <constant>const</constant> counterpart of the same name
+ prefixed by <constant>c_</constant>, which is the only means to get a
+ <constant>const</constant> phylum variable. </para>
+ <para>Just for the sake of completeness, be it mentioned that every
+ phylum corresponds to a class
+ <classname>impl_</classname><varname>phylum</varname> and every
+ operator to a subclass
+ <classname>impl_</classname><varname>phylum</varname>_<varname>operator</varname>.
+ All the classes are derived from a common base class which can be referred
+ to as
+ <classname>abstract_phylum</classname>. By adding constructors, methods
+ or attributes to it, all phyla will be changed in that way.
+ </para>
+ <para>The interworking with &yacc;/&bison; requires a type
+ <classname>YYSTYPE</classname> which will be generated by &kpp; when the
+ option <constant>yystype</constant> is specified (see <xref linkend="sec:options"/>)</para>
+ <sect2><title>Smart-pointer<indexterm><primary>smart
+ pointer</primary></indexterm></title>
+ <para>Memory often leaks when phylum operators are used in expressions,
+ and that is sometimes hard to detect.
+ The option <constant>smart-pointer</constant> enables a smart memory
+ management which avoids unnecessary copying of terms and automatically
+ frees memory of unused terms. This is achieved
+ by using so called smart-pointers which do reference counting and
+ allow to free a term if it is no longer referenced.</para>
+ <para>An additional type is generated for every phylum with the suffix
+ <classname>_ptr</classname>. Variables of such types are unnecessary
+ ever to be freed. Avoid mixing them with variables of the usual types,
+ especially never assign between them, because that is likely to cause
+ memory access errors.
+ <!--(detailed description of implementation? TODO)--></para>
+ </sect2>
+ <sect2><title>Weak-pointer<indexterm><primary>weak
+ pointer</primary></indexterm></title>
+ <para>The option <constant>weak-pointer</constant> extends the
+ smart-pointer technique and supports a third
+ type for every phylum. It gets prefix <constant>weak_</constant> and
+ suffix <constant>_ptr</constant>. Weak-pointer variables of a term will
+ not contribute to the reference counting, such that the term already is
+ freed if merely weak-pointers reference it yet. That is why they are
+ only usefully employed in conjunction with smart-pointers.
+ In contrast to usual variables, weak-pointers have their own
+ reference counting, which allows to determine whether such a pointer
+ dangles, that is points to a term already freed and thus is no longer
+ valid.</para>
+ </sect2>
+ </sect1>
+ <sect1 id="sec:genfunc"><title>Generated Functions</title>
+ <para>&kpp; generates a number of functions which are available wherever
+ &cpp; code is allowed in <filename>.k</filename>-files. The table <xref
+ linkend="tab:functions"/> lists all these functions and the sections
+ which contain a more detailed description.</para>
+ <table id="tab:functions"><title>Generated Functions</title>
+ <?latex \hfill?>
+ <tgroup cols='2' align='left' colsep='1' rowsep='1'>
+ <?latex-table-option [t]?>
+ <thead>
+ <row>
+ <entry>function</entry>
+ <entry>see section</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>append</entry>
+ <entry><xref linkend="sec:listfuncs"/></entry>
+ </row>
+ <row>
+ <entry>concat</entry>
+ <entry><xref linkend="sec:listfuncs"/></entry>
+ </row>
+ <row>
+ <entry>eq</entry>
+ <entry><xref linkend="sec:commonfuncs"/></entry>
+ </row>
+ <row>
+ <entry>CSGIOread</entry>
+ <entry><xref linkend="sec:csgiofuncs"/></entry>
+ </row>
+ <row>
+ <entry>CSGIOwrite</entry>
+ <entry><xref linkend="sec:csgiofuncs"/></entry>
+ </row>
+ <row>
+ <entry>filter</entry>
+ <entry><xref linkend="sec:listfuncs"/></entry>
+ </row>
+ <row>
+ <entry>fprint</entry>
+ <entry><xref linkend="sec:commonfuncs"/></entry>
+ </row>
+ <row>
+ <entry>fprintdot</entry>
+ <entry><xref linkend="sec:commonfuncs"/></entry>
+ </row>
+ <row>
+ <entry>fprintdotepilogue</entry>
+ <entry><xref linkend="sec:commonfuncs"/></entry>
+ </row>
+ <row>
+ <entry>fprintdotprologue</entry>
+ <entry><xref linkend="sec:commonfuncs"/></entry>
+ </row>
+ <row>
+ <entry>free</entry>
+ <entry><xref linkend="sec:memfuncs"/></entry>
+ </row>
+ <row>
+ <entry>freelist</entry>
+ <entry><xref linkend="sec:memfuncs"/></entry>
+ </row>
+ <row>
+ <entry>ht_create_simple</entry>
+ <entry><xref linkend="sec:memfuncs"/></entry>
+ </row>
+ <row>
+ <entry>ht_assign</entry>
+ <entry><xref linkend="sec:memfuncs"/></entry>
+ </row>
+ <row>
+ <entry>ht_assigned</entry>
+ <entry><xref linkend="sec:memfuncs"/></entry>
+ </row>
+ <row>
+ <entry>ht_clear</entry>
+ <entry><xref linkend="sec:memfuncs"/></entry>
+ </row>
+ <row>
+ <entry>ht_delete</entry>
+ <entry><xref linkend="sec:memfuncs"/></entry>
+ </row>
+ <row>
+ <entry>is_nil</entry>
+ <entry><xref linkend="sec:listfuncs"/></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ <?latex \hfill?>
+ <tgroup cols='2' align='left' colsep='1' rowsep='1'>
+ <?latex-table-option [t]?>
+ <thead>
+ <row>
+ <entry>function</entry>
+ <entry>see section</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>last</entry>
+ <entry><xref linkend="sec:listfuncs"/></entry>
+ </row>
+ <row>
+ <entry>length</entry>
+ <entry><xref linkend="sec:listfuncs"/></entry>
+ </row>
+ <row>
+ <entry>map</entry>
+ <entry><xref linkend="sec:listfuncs"/></entry>
+ </row>
+ <row>
+ <entry>merge</entry>
+ <entry><xref linkend="sec:listfuncs"/></entry>
+ </row>
+ <row>
+ <entry>mkcasestring</entry>
+ <entry><xref linkend="sec:creationfuncs"/></entry>
+ </row>
+ <row>
+ <entry>mkinteger</entry>
+ <entry><xref linkend="sec:creationfuncs"/></entry>
+ </row>
+ <row>
+ <entry>mknocasestring</entry>
+ <entry><xref linkend="sec:creationfuncs"/></entry>
+ </row>
+ <row>
+ <entry>mkreal</entry>
+ <entry><xref linkend="sec:creationfuncs"/></entry>
+ </row>
+ <row>
+ <entry>op_name</entry>
+ <entry><xref linkend="sec:commonfuncs"/></entry>
+ </row>
+ <row>
+ <entry>phylum_name</entry>
+ <entry><xref linkend="sec:commonfuncs"/></entry>
+ </row>
+ <row>
+ <entry>print</entry>
+ <entry><xref linkend="sec:commonfuncs"/></entry>
+ </row>
+ <row>
+ <entry>reduce</entry>
+ <entry><xref linkend="sec:listfuncs"/></entry>
+ </row>
+ <row>
+ <entry>reverse</entry>
+ <entry><xref linkend="sec:listfuncs"/></entry>
+ </row>
+ <row>
+ <entry>rewrite</entry>
+ <entry><xref linkend="sec:commonfuncs"/></entry>
+ </row>
+ <row>
+ <entry>set_subphylum</entry>
+ <entry><xref linkend="sec:commonfuncs"/></entry>
+ </row>
+ <row>
+ <entry>subphylum</entry>
+ <entry><xref linkend="sec:commonfuncs"/></entry>
+ </row>
+ <row>
+ <entry>unparse</entry>
+ <entry><xref linkend="sec:commonfuncs"/></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ <?latex \hspace*{\fill}?>
+ </table>
+ <sect2 id="sec:commonfuncs"><title>Common Functions</title>
+ <para>Since <classname>abstract_phylum</classname> has an
+ <function>unparse</function>-method defined and all phyla are derived
+ from <classname>abstract_phylum</classname> all phyla have it. The same
+ is true for some other methods.</para>
+ <sect3><title>copy<indexterm><primary>copy()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ abstract_phylum copy( bool copy_attributes ) const;
+ </programlisting>
+ </informalexample>
+ <para>The method copies this term completely, including its subterms.
+ Since the result is always <classname>abstract_phylum</classname> it
+ has to be casted to the phylum of this term. If
+ <literal>true</literal> is specified as argument, the attributes are
+ copied too. But beware! Merely the addresses are copied if the
+ attributes are phyla or &cpp; pointers, that is, the new term
+ references the attributes of the old one. </para>
+ </sect3>
+ <sect3><title>eq<indexterm><primary>eq()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ bool eq( c_abstract_phylum c_p ) const;
+ </programlisting>
+ </informalexample>
+ <para>The method returns <literal>true</literal> if this term is
+ structurally equal to the argument, that is, both terms have
+ equal subtrees.</para>
+ </sect3>
+ <sect3><title>fprint<indexterm><primary>fprint()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ void fprint( FILE* file );
+ </programlisting>
+ </informalexample>
+ <para>The method prints a textual presentation of this term to
+ the specified file. This simple example produces the output
+ underneath. </para>
+ <programlisting>
+ simpleterm a_number = SimpleTerm( mkinteger( 23 ) );
+ a_number -> print( );
+
+ SimpleTerm(
+ Number(
+ 23
+ )
+ )
+ </programlisting>
+ </sect3>
+ <sect3><title>fprintdot<indexterm><primary>fprintdot()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ void fprintdot( FILE *f,
+ const char *root_label_prefix,
+ const char *edge_label_prefix,
+ const char *edge_attributes,
+ bool print_node_labels,
+ bool use_context_when_sharing_leaves,
+ bool print_prologue_and_epilogue
+ ) const;
+ </programlisting>
+ </informalexample>
+ <para>This function creates a representation of the term in a format
+ understood by the program <application>dot</application>, which is part
+ of the graphics package <application>graphviz</application> and draws
+ directed acyclic graphs in various output formats like PostScript or
+ GIF. The target of the operation is the file <varname>f</varname>, while
+ the other arguments control the details of the graphs appearence.
+ </para>
+ <variablelist>
+ <varlistentry><term>root_label_prefix</term>
+ <listitem><para>Adds a label to the graph denoting the root term.
+ The label has the name of the phylum of that term prefixed by
+ this string argument. </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term>edge_label_prefix</term>
+ <listitem><para>Every edge in the graph is labelled with a number.
+ This string argument appears as the prefix of these labels.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term>edge_attributes</term>
+ <listitem><para>For <application>dot</application>, the edges can
+ have attributes which specify additional features like font name
+ or edge colour (see <application>dot</application> manual for
+ attribute names and values). This string argument is a list of
+ attribute/value pairs
+ (<varname>attribute</varname>=<varname>value</varname>),
+ separated by commas.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term>print_node_labels</term>
+ <listitem><para>If this argument is set to <literal>true</literal>,
+ the names of the subterms phyla appear in the graph. Otherwise
+ they are suppressed and only the term names (operator names) are
+ printed.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term>use_context_when_sharing_leaves</term>
+ <listitem><para>Terms which are shared in the tree usually appear
+ only once in the graph (terms of <constant>uniq</constant>
+ phyla). In particular, terms of predefined phyla are shared if
+ they are equal. They are always leaves since they have no
+ subphyla. If this argument is set to <literal>true</literal>,
+ the leaves appear shared in the graph only if they are subterms
+ of shared (<constant>uniq</constant>) terms.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term>print_prologue_and_epilogue</term>
+ <listitem><para>This argument is usually set to
+ <literal>true</literal> since a certain prologue and epilogue
+ are necessary to frame the graph. This is set to
+ <literal>false</literal> if multiple graphs are to be grouped
+ into one figure. In that case the prologue function has to be
+ called explicitly, then some <function>fprintdot</function>
+ calls follow, and finally the epilogue call finishes the figure
+ creation. </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>The following call of <function>fprintdot</function> writes a
+ a presentation of the term <varname>t</varname> to a file
+ <varname>exa</varname>. From that file <application>dot</application>
+ creates a graph like that in figure <xref linkend="fig:fprintdot"/>.</para>
+ <programlisting>
+ aterm t = Plus( SimpleTerm( Number( mkinteger( 7 ) ) ),
+ SimpleTerm( Number( mkinteger( 7 ) ) ) );
+ t -> fprintdot(exa, "root_", "edge", "style=dashed", true, false, true);
+ </programlisting>
+ <figure id="fig:fprintdot">
+ <title>Dot Created Graph of an Example Term</title>
+ <mediaobject><imageobject><imagedata
+ align="center" fileref="imagesgen/fprintdot.png" format="PNG"/>
+ </imageobject>
+ <imageobject><imagedata
+ align="center" fileref="imagesgen/fprintdot" format="TEX"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ </sect3>
+ <sect3><title>fprintdotprologue<indexterm><primary>fprintdotprologue()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ void fprintdotprologue ( FILE *f );
+ </programlisting>
+ </informalexample>
+ <para>This function writes the prologue to <varname>f</varname>, which
+ is needed to set up <application>graphviz</application>.
+ Usually, when the figure contains only one graph, this function will
+ be called implicitly by <function>fprintdot</function>; call this
+ function when you set <varname>print_prologue_and_epilogue</varname>
+ to <literal>false</literal> in the function call above.
+ </para>
+ </sect3>
+ <sect3><title>fprintdotepilogue<indexterm><primary>fprintdotepilogue()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ void fprintdotepilogue ( FILE *f );
+ </programlisting>
+ </informalexample>
+ <para>This function writes the epilogue to <varname>f</varname>, which
+ is needed to finish the graph for <application>graphviz</application>.
+ Usually, when the figure contains only one graph, this function will
+ be called implicitly by <function>fprintdot</function>; call this
+ function when you set <varname>print_prologue_and_epilogue</varname>
+ to <literal>false</literal> in the function call above.
+ </para>
+ </sect3>
+ <sect3><title>op_name<indexterm><primary>op_name()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ const char* op_name( ) const;
+ </programlisting>
+ </informalexample>
+ <para>This function returns the name of the phylum operator which has
+ been used to create this term. </para>
+ </sect3>
+ <sect3><title>phylum_name<indexterm><primary>phylum_name()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ const char* phylum_name( ) const;
+ </programlisting>
+ </informalexample>
+ <para>This function returns the name of the phylum of this term. </para>
+ </sect3>
+ <sect3><title>print<indexterm><primary>print()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ void print( );
+ </programlisting>
+ </informalexample>
+ <para>This function prints a textual presentation of this term to the
+ standard output. It is similar to the output of
+ <function>fprint</function>.</para>
+ </sect3>
+ <sect3><title>set_subphylum<indexterm><primary>set_subphylum()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ void set_subphylum( int n, abstract_phylum p, bool=false );
+ </programlisting>
+ </informalexample>
+ <para>This function replaces the <varname>n</varname>th subterm of this term by term
+ <varname>p</varname>, which must be of a phylum castable to the phylum
+ of the appropriate subterm. Numbering starts with <literal>0</literal>.
+ </para>
+ </sect3>
+ <sect3><title>subphylum<indexterm><primary>subphylum()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ abstract_phylum subphylum( int n, bool=false ) const;
+ </programlisting>
+ </informalexample>
+ <para>This function returns the <varname>n</varname>th subterm of this
+ term. Numbering starts with <literal>0</literal>. </para>
+ </sect3>
+ <sect3><title>unparse<indexterm significance=
+ "preferred"><primary>unparse()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ void unparse( printer_functor pf, uview uv);
+ void unparse( printer_function opf, uview uv );
+ </programlisting>
+ </informalexample>
+ <para>This function starts unparsing for this term. It is recursively
+ called for every subterm. Unparsing is processed under the specified
+ unparse view, and the strings to output are delivered to the printer
+ functor or function respectively. </para>
+ </sect3>
+ <sect3><title>rewrite<indexterm><primary>rewrite()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ <actual phylum> rewrite( rview rv );
+ ]]>
+ </programlisting>
+ </informalexample>
+ <para>This functions starts rewriting for this term. It returns a new term
+ of the actual phylum. Usually it is called at the root term whereupon
+ the entire tree is searched under the specified view. </para>
+ </sect3>
+ </sect2>
+ <sect2 id="sec:csgiofuncs"><title>CSGIO Functions</title>
+ <para>The generated files <filename>csgiok.h</filename> and
+ <filename>csgiok.cc</filename><indexterm><primary>csgiok.cc,h</primary></indexterm>
+ provide means to write terms to files and
+ to reconstruct terms from such files. Whole term trees thus can be saved
+ and exchanged between different applications. Reading and writing
+ is performed by two functions.</para>
+ <para>The format of the files has once been designed to be compatible to
+ the structure files of the commercial tool <application>Synthesizer
+ Generator</application>. The format written now by &kpp; is somewhat
+ extended so that they are not compatible any more, but old structure
+ files are expected to be still understood.</para>
+ <sect3><title>CSGIOwrite<indexterm><primary>CSGIOwrite()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ void CSGIOwrite( FILE *f ) const;
+ ]]>
+ </programlisting>
+ </informalexample>
+ <para>The methods writes this term to <varname>f</varname>, that is, the
+ entire subterm tree. The
+ attributes are ignored except they are phyla which have been defined
+ using the keyword <constant>%member</constant>. </para>
+ </sect3>
+ <sect3><title>CSGIOread<indexterm><primary>CSGIOread()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ template<typename P> void
+ CSGIOread( FILE *f, P &p )
+ ]]>
+ </programlisting>
+ </informalexample>
+ <para>The function reads from <varname>f</varname> the presentation of a
+ term. The term is constructed by successively calling the appropriate
+ operators of the subterms. The operators initialize the attributes
+ according to the phylum definition; except the
+ <constant>%member</constant>-attributes which get their values from
+ the saved term. The created term is assigned to <varname>p</varname>
+ which has to be a variable of the correct phylum.
+ </para>
+ </sect3>
+ </sect2>
+ <sect2 id="sec:creationfuncs"><title>Creation Functions</title>
+ <para>Terms of predefined phyla are created by functions.</para>
+ <sect3><title>mkcasestring<indexterm significance=
+ "preferred"><primary>mkcasestring()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ casestring mkcasestring( const char *str );
+ casestring mkcasestring( const char *str, unsigned int length );
+ </programlisting>
+ </informalexample>
+ <para>The function creates a term of the phylum
+ <classname>casestring</classname>
+ from the specified string. Upper and lower case characters are
+ distinguished. The second variant uses only the first
+ <varname>length</varname> characters of the specified string.
+ </para>
+ </sect3>
+ <sect3><title>mkinteger<indexterm significance=
+ "preferred"><primary>mkinteger()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ integer mkinteger( const INTEGER i );
+ </programlisting>
+ </informalexample>
+ <para>The function creates a term of the phylum
+ <classname>integer</classname>
+ from the specified value. <classname>INTEGER</classname> is a macro
+ which can be defined by the user as needed but defaults to
+ <classname>int</classname>. </para>
+ </sect3>
+ <sect3><title>mknocasestring<indexterm significance=
+ "preferred"><primary>mknocasestring()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ nocasestring mknocasestring( const char *str );
+ nocasestring mknocasestring( const char *str, unsigned int length );
+ </programlisting>
+ </informalexample>
+ <para>The function creates a term of the phylum
+ <classname>nocasestring</classname>
+ from the specified string. Upper and lower case characters are not
+ distinguished. The second variant uses only the first
+ <varname>length</varname> characters of the specified string. </para>
+ </sect3>
+ <sect3><title>mkreal<indexterm significance=
+ "preferred"><primary>mkreal()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ real mkreal( const REAL r );
+ </programlisting>
+ </informalexample>
+ <para>The function creates a term of the phylum
+ <classname>real</classname>
+ from the specified value. <classname>REAL</classname> is a macro
+ which can be defined by the user as needed but defaults to
+ <classname>double</classname>. </para>
+ </sect3>
+ </sect2>
+ <sect2 id="sec:memfuncs"><title>Memory Management Functions</title>
+ <para>When terms, once constructed, are no longer needed it is usually
+ reasonable to free the memory they allocate,
+ especially when dealing with large numbers of
+ terms.</para>
+ <para>The same does not hold not for the use of smart-pointers, because
+ these keep track of allocated memory by their own. Never apply
+ <function>free</function> or <function>freelist</function> to
+ smart-pointers. The
+ &cpp; <constant>delete</constant> should never be applied to
+ any term, since that would get around some &kpp; mechanisms. </para>
+ <sect3><title>free<indexterm><primary>free()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ void free( bool recursive=true );
+ </programlisting>
+ </informalexample>
+ <para>The method frees the memory allocated by this term and by
+ default it frees also the subterms recursively. When it is applied to
+ a list term, the whole list and all its elements are freed. The
+ non-recursive form only separates the list into its first element and
+ the remainder of the list. Terms of phyla under non-default storage
+ management can not be freed individually, calling
+ <function>free</function> on them has no effect.</para>
+ </sect3>
+ <sect3><title>freelist<indexterm><primary>freelist()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ void freelist( );
+ </programlisting>
+ </informalexample>
+ <para>The method frees the spine of this list term and leaves the list
+ elements untouched. </para>
+ </sect3>
+
+ <sect3 id="sec:hashtable">
+ <title>Hashtable Functions</title>
+ <indexterm significance="preferred"><primary>hashtables</primary></indexterm>
+ <para>The memory management of terms of storage class
+ <constant>uniq</constant><indexterm><primary>uniq</primary></indexterm>
+ or a user defined one can only be influenced by hashtable operations.
+ </para>
+ </sect3>
+ <sect3><title>ht_create_simple<indexterm><primary>ht_create_simple()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ hashtable_t ht_create_simple ( int size );
+ </programlisting>
+ </informalexample>
+ <para>The function creates a new hashtable and returns it. The current
+ implementation ignores the <varname>size</varname> argument.
+ </para>
+ </sect3>
+ <sect3><title>ht_assign<indexterm><primary>ht_assign()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ hashtable_t ht_assign ( hashtable_t ht, storageclass_t sc,
+ bool still_unique=false );
+ </programlisting>
+ </informalexample>
+ <para>The function assigns the hashtable <varname>ht</varname> to the
+ storage class <varname>sc</varname> and returns the hashtable which
+ has previously been assigned to <varname>sc</varname>. </para>
+ </sect3>
+ <sect3><title>ht_assigned<indexterm><primary>ht_assigned()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ hashtable_t ht_assigned ( storageclass_t sc );
+ </programlisting>
+ </informalexample>
+ <para>The function returns the hashtable which is assigned to the
+ storageclass <varname>sc</varname>. </para>
+ </sect3>
+ <sect3><title>ht_clear<indexterm><primary>ht_clear()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ void ht_clear ( hashtable_t ht );
+ </programlisting>
+ </informalexample>
+ <para>The function removes all entries from the hashtable
+ <varname>ht</varname>. </para>
+ </sect3>
+ <sect3><title>ht_delete<indexterm><primary>ht_delete()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ void ht_delete ( hashtable_t ht );
+ </programlisting>
+ </informalexample>
+ <para>The function deletes the hashtable <varname>ht</varname> entirely.
+ </para>
+ </sect3>
+ </sect2>
+ <sect2 id="sec:listfuncs"><title>List Functions<indexterm id="idx:listfunc"
+ class="startofrange"><primary>list</primary></indexterm></title>
+ <para>List phyla which have been defined using the
+ <constant>list</constant> keyword get some methods performing convenient
+ tasks. In the function signatures, the name
+ <classname><![CDATA[<phylum list>]]></classname> denotes the actual
+ list phylum, <constant><![CDATA[<phylum>]]></constant> denotes the
+ phylum of the list elements. </para>
+ <sect3><title>append<indexterm><primary>append()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ <phylum list> append( <phylum> p );]]>
+ </programlisting>
+ </informalexample>
+ <para>The method appends the specified term to this list and returns
+ the tail of the new list, <abbrev>ie.</abbrev> the sublist that has
+ <varname>p</varname> as its only element. This make appending several
+ elements in a row more efficient.
+ </para>
+ </sect3>
+ <sect3><title>concat<indexterm><primary>concat()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ friend <phylum list> concat( c_<phylum list> l1, c_<phylum list> l2 );]]>
+ </programlisting>
+ </informalexample>
+ <para>The function constructs a new list from the terms of
+ <varname>l1</varname> followed by the terms of <varname>l2</varname>
+ and returns that list.
+ </para>
+ </sect3>
+ <sect3><title>filter<indexterm><primary>filter()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ <phylum list> filter( bool (*fp) (<phylum>) );]]>
+ </programlisting>
+ </informalexample>
+ <para>The method constructs a new list from the terms of this
+ list for which the function <function>fp</function> yields
+ <literal>true</literal>.
+ </para>
+ </sect3>
+ <sect3><title>is_nil<indexterm><primary>is_nil()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ bool is_nil( ) const;]]>
+ </programlisting>
+ </informalexample>
+ <para>The method returns <literal>true</literal> if this list is empty.
+ </para>
+ </sect3>
+ <sect3><title>last<indexterm><primary>last()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ <phylum list> last( ) const;]]>
+ </programlisting>
+ </informalexample>
+ <para>The method returns the remainder of this list which contains only
+ one, the last, element. If this list is empty the empty list is
+ returned.
+ </para>
+ </sect3>
+ <sect3><title>length<indexterm><primary>length()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ int length( ) const;]]>
+ </programlisting>
+ </informalexample>
+ <para>The method returns the number of elements in this list.
+ </para>
+ </sect3>
+ <sect3><title>map<indexterm><primary>map()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ <phylum list> map( <phylum> (*fp) (<phylum>) );]]>
+ </programlisting>
+ </informalexample>
+ <para>The method constructs a new list containing the terms which are
+ returned by the <function>fp</function> which is called for every
+ element of this list. The new list is returned.
+ </para>
+ </sect3>
+ <sect3><title>merge<indexterm><primary>merge()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ <phylum list> merge( <phylum list> l, <phylum> (*fp) (<phylum>, <phylum>) );]]>
+ </programlisting>
+ </informalexample>
+ <para>The method constructs a new list containing the terms which are
+ returned by the <function>fp</function> which is called for every
+ element of this list taking the second argument from the specified
+ list. The new list is returned.
+ </para>
+ </sect3>
+ <sect3><title>reduce<indexterm><primary>reduce()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ <phylum> reduce( <phylum> p, <phylum> (*fp) (<phylum>, <phylum>) );]]>
+ </programlisting>
+ </informalexample>
+ <para>The method successively applies the function
+ <function>fp</function> to each element of this list and
+ <function>fp</function>s last result which initially is the term
+ <varname>p</varname>. The final result is returned.
+ </para>
+ </sect3>
+ <sect3><title>reverse<indexterm><primary>reverse()</primary></indexterm></title>
+ <informalexample>
+ <programlisting>
+ <![CDATA[ <phylum list> reverse( ) const;]]>
+ </programlisting>
+ </informalexample>
+ <para>The method constructs a new list which contains the elements of
+ this list in reverse order. The new list is returned.
+ <!-- Always move to end of enclosing sect2 -->
+ <indexterm class="endofrange" startref="idx:listfunc"/>
+ </para>
+ </sect3>
+ </sect2>
+ </sect1>
+ <sect1><title>Generated Files</title>
+ <para>The generated code is spread over several files. The table <xref
+ linkend="tab:filenames"/> lists these files and a description of their
+ contents.
+ Every file defines a macro symbol which can be used in preprocessor
+ instructions and in code redirections<indexterm><primary>redirection</primary></indexterm>.
+ These symbols are listed as well. From every &kpp; file
+ a &cpp; file and a header file are generated. The name
+ <varname>file</varname> in the table refers to such files.</para>
+ <table id="tab:filenames"><title>Generated files</title>
+ <tgroup cols='3' align='left' colsep='1' rowsep='1'>
+ <?latex-table-type tabularx?>
+ <?latex-table-option {\textwidth}?>
+ <?latex-table-head lp{0.4\textwidth}X?>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <colspec colname='c3'/>
+ <thead>
+ <row>
+ <entry>file</entry>
+ <entry>symbol</entry>
+ <entry>contents</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><filename>csgiok.cc</filename><indexterm><primary>csgiok.cc,h</primary></indexterm></entry>
+ <entry>KC_CSGIO</entry>
+ <entry>functions for saving and restoring of terms</entry>
+ </row>
+ <row>
+ <entry><filename>csgiok.h</filename></entry>
+ <entry>KC_CSGIO_HEADER</entry>
+ <entry>some definitions for saving and restoring of terms</entry>
+ </row>
+ <row>
+ <entry><filename>k.cc</filename><indexterm><primary>k.cc,h</primary></indexterm></entry>
+ <entry>KC_TYPES</entry>
+ <entry>implementation of all classes generated from phylum definitions</entry>
+ </row>
+ <row>
+ <entry><filename>k.h</filename></entry>
+ <entry>KC_TYPES_HEADER</entry>
+ <entry>all class declarations generated from phylum definitions;
+ included by all implicitly generated files</entry>
+ </row>
+ <row>
+ <entry><filename>rk.cc</filename><indexterm><primary>rk.cc,h</primary></indexterm></entry>
+ <entry>KC_REWRITE</entry>
+ <entry>rewrite methods for all phyla</entry>
+ </row>
+ <row>
+ <entry><filename>rk.h</filename></entry>
+ <entry>KC_REWRITE_HEADER</entry>
+ <entry>rewrite view class definitions</entry>
+ </row>
+ <row>
+ <entry><filename>unpk.cc</filename><indexterm><primary>unpk.cc,h</primary></indexterm></entry>
+ <entry>KC_UNPARSE</entry>
+ <entry>unparse methods for all phyla</entry>
+ </row>
+ <row>
+ <entry><filename>unpk.h</filename></entry>
+ <entry>KC_UNPARSE_HEADER</entry>
+ <entry>unparse view class definitions</entry>
+ </row>
+ <row>
+ <entry><varname>file</varname><filename>.cc</filename></entry>
+ <entry>KC_FUNCTIONS_<varname>file</varname> or CODE</entry>
+ <entry>function definitions from <varname>file</varname><filename>.k</filename>-file</entry>
+ </row>
+ <row>
+ <entry><varname>file</varname><filename>.h</filename></entry>
+ <entry>KC_FUNCTIONS_<varname>file</varname>_HEADER or HEADER</entry>
+ <entry>declarations of functions from <varname>file</varname><filename>.k</filename>-file</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <sect2 id="sec:redirection"><title>Code Redirection<indexterm significance="preferred"><primary>redirection</primary></indexterm></title>
+ <para>A <filename>.k</filename>-file can contain pieces of arbitrary &cpp;
+ enclosed between a line
+ starting with
+ <constant>%{</constant><indexterm><primary>%{</primary></indexterm> and
+ one starting with
+ <constant>%}</constant><indexterm><primary>%}</primary></indexterm>.
+ Since it will not be
+ parsed by &kpp; but copied directly into generated code, it can not
+ contain special &kpp; constructs, but merely pure &cpp;. It will go to
+ the matching <filename>.cc</filename>-file, if no redirection is
+ specified. Giving a list of
+ file symbols after <constant>%{</constant> will copy the code each
+ of the specified files instead. The available redirection symbols
+ are listed in table <xref linkend="tab:filenames"/>.</para>
+ <informalexample>
+ <programlisting>
+ // this be a file example.k
+
+ %{
+ // everything between the brace lines will be copied to example.cc
+ %}
+
+ %{ HEADER KC_UNPARSE /* beware of //-comments here */
+ // everything between the brace lines will be copied to example.h and unpk.cc
+ %}
+ </programlisting>
+ </informalexample>
+ </sect2>
+ </sect1>
+ </chapter>
+
+ <chapter><title>Running &kpp;</title>
+ <para>The &kpp; processor is invoked with the command
+ <userinput>kc++</userinput>. It can be invoked on any number of
+ <filename>.k</filename>-files and will create a number of output files
+ as outlined above. A typical call looks like this:
+ </para>
+ <informalexample>
+ <userinput>kc++ abstr.k rpn.k main.k</userinput>
+ </informalexample>
+ <para>When used together with other tools (see
+ <xref linkend="sec:yacc"/>) a makefile is helpful.
+ Be aware, though, that every source file may influence every
+ generated file (because of the code redirections). Thus multiple destination
+ files depend on multiple source files. That means the makefile becomes more
+ complicated in order to handle these dependencies. That is why an example makefile
+ is provided in appendix (see <xref linkend="app:make"/>). It is sufficient
+ for the <acronym>RPN</acronym> example and
+ may easily be adapted for many more.</para>
+ <sect1
+ id="sec:options"><title>Options<indexterm id="idx:options"
+ class="startofrange"><primary>options</primary></indexterm></title>
+ <para>&kpp; recognizes a number of command line options which affect the
+ process of parsing and code generation, some rather drastically. Table
+ <xref linkend="tab:options"/> presents, in alphabetical order,
+ all available options and their explanation. In most environments, two
+ forms are provided, short and <acronym>GNU</acronym> style long options.
+ </para>
+ <para>Suppose you do not need CSGIO input/output, but want to interface with
+ your favourite compiler compiler, you might use:</para>
+ <informalexample>
+ <userinput>kc++ --no-csgio --yystype abstr.k rpn.k main.k</userinput>
+ </informalexample>
+ <para>Some vital options can be specified directly in &kpp; using the
+ keyword <constant>%option</constant>. Such specified options take higher
+ priority than command line options and thus override them.
+ Table <xref linkend="tab:vitaloptions"/> lists them in alphabetical order.
+ They behave like their command line counterparts.
+ A line like this could be specified in a &kpp; file:</para>
+ <informalexample>
+ <programlisting>
+ %option yystype smart-pointer
+ </programlisting>
+ </informalexample>
+ <table id="tab:options"><title>Command line options</title>
+ <tgroup cols='3' align='left' colsep='1' rowsep='1'>
+ <?latex-table-type tabularx?>
+ <?latex-table-option {\textwidth}?>
+ <?latex-table-head llX?>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <colspec colname='c3'/>
+ <thead>
+ <row>
+ <entry></entry>
+ <entry>option</entry>
+ <entry>explanation</entry>
+ </row>
+ </thead>
+ <tbody>
+ <!-- Kimwitu++ Features -->
+ <row>
+ <entry>–c</entry>
+ <entry>––no–csgio</entry>
+ <entry>do not generate phylum read/write functions
+ (<filename>csgiok.{h,cc}</filename>)
+ </entry>
+ </row>
+ <row>
+ <entry>–r</entry>
+ <entry>––no–rewrite</entry>
+ <entry>do not generate code for rewrite rules
+ (<filename>rk.{h,cc}</filename>)</entry>
+ </row>
+ <row>
+ <entry>–u</entry>
+ <entry>––no–unparse</entry>
+ <entry>do not generate code for unparse rules
+ (<filename>unpk.{h,cc}</filename>)</entry>
+ </row>
+ <row>
+ <entry>–d</entry>
+ <entry>––no–printdot</entry>
+ <entry>no fprintdot functions are generated</entry>
+ </row>
+ <row>
+ <entry>–t</entry>
+ <entry>––no–hashtables</entry>
+ <entry>do not generate code for hashtable operations
+ </entry>
+ </row>
+ <!-- C++ Compiler Options -->
+ <row>
+ <entry>–n</entry>
+ <entry>––covariant=C</entry>
+ <entry>use covariant return types: y|n|p (yes, no or generate both
+ and decide per preprocessor macro
+ <constant>NO_COVARIANT_RETURN</constant>)</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>––stdafx[=FILE]</entry>
+ <entry>generate include for Microsoft precompiled header files
+ (default <filename>stdafx.h</filename>)</entry>
+ </row>
+ <row>
+ <entry>–e</entry>
+ <entry>––dllexport=STRING</entry>
+ <entry>generates string between keyword class and the
+ class name of all operators and phyla</entry>
+ </row>
+ <row>
+ <entry>–m</entry>
+ <entry>––smart–pointer</entry>
+ <entry>generates code for smart pointers (reference counting)</entry>
+ </row>
+ <row>
+ <entry>–w</entry>
+ <entry>––weak–pointer</entry>
+ <entry>generates code for weak pointers (implies smart pointers)</entry>
+ </row>
+ <!-- Files -->
+ <row>
+ <entry>–s</entry>
+ <entry>––suffix=EXT</entry>
+ <entry>extension for generated source files (default
+ <filename>.cc</filename>)</entry>
+ </row>
+ <row>
+ <entry>–f</entry>
+ <entry>––file–prefix=PREF</entry>
+ <entry>prefix all generated files</entry>
+ </row>
+ <row>
+ <entry>–o</entry>
+ <entry>––overwrite</entry>
+ <entry>always write generated files even if not changed</entry>
+ </row>
+ <row>
+ <entry>–b</entry>
+ <entry>––yystype[=FILE]</entry>
+ <entry>generate file (default <filename>yystype.h</filename>)
+ containing <classname>YYSTYPE</classname>, for &yacc; and &bison;
+ </entry>
+ </row>
+ <row>
+ <entry>–y</entry>
+ <entry>––yxxunion</entry>
+ <entry>generate file <filename>yxx_union.h</filename>)
+ for use with for <application>Yacc++</application>.
+ </entry>
+ </row>
+ <!-- Advanced -->
+ <row>
+ <entry>–l</entry>
+ <entry>––no–linedirec</entry>
+ <entry>omit the line directives (<constant>#line</constant>)
+ altogether</entry>
+ </row>
+ <row>
+ <entry />
+ <entry>––comment–line</entry>
+ <entry>change line directives to mere comments</entry>
+ </row>
+ <row>
+ <entry />
+ <entry>––dir–line</entry>
+ <entry>prepends the current working directory to the file name
+ in line directives</entry>
+ </row>
+ <row>
+ <entry>–p</entry>
+ <entry>––pipe=CMD</entry>
+ <entry>process all files while piping them through CMD</entry>
+ </row>
+ <!-- Other -->
+ <row>
+ <entry>–M</entry>
+ <entry>––msg–format=PAT</entry>
+ <entry><?latex \raggedright ?>specifies format of (error) messages, PAT can contain:
+ <?latex \linebreak ?>
+ <userinput>%p</userinput> (program name),
+ <userinput>%s</userinput> (severity),
+ <userinput>%f</userinput> (file name),
+ <?latex \linebreak ?>
+ <userinput>%d</userinput> (current working directory),
+ <userinput>%l</userinput> (line number),
+ <userinput>%c</userinput> (column);
+ <?latex \linebreak ?>
+ the actual message is appended</entry>
+ </row>
+ <row>
+ <entry>–q</entry>
+ <entry>––quiet</entry>
+ <entry>quiet operation (is default)</entry>
+ </row>
+ <row>
+ <entry>–v</entry>
+ <entry>––verbose</entry>
+ <entry>print additional status information while processing</entry>
+ </row>
+ <row>
+ <entry>–h</entry>
+ <entry>––help</entry>
+ <entry>display the help and exit</entry>
+ </row>
+ <row>
+ <entry>–V</entry>
+ <entry>––version</entry>
+ <entry>output version information and exit</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <table id="tab:vitaloptions"><title>Built-in options</title>
+ <tgroup cols='1' align='left' colsep='1' rowsep='1'>
+ <?latex-table-type tabularx?>
+ <?latex-table-option {\textwidth}?>
+ <?latex-table-head X?>
+ <colspec colname='c1'/>
+ <tbody>
+ <row><entry>no–csgio</entry></row>
+ <row><entry>no–hashtables</entry></row>
+ <row><entry>no–printdot</entry></row>
+ <row><entry>no–rewrite</entry></row>
+ <row><entry>no–unparse</entry></row>
+ <row><entry>smart–pointer</entry></row>
+ <row><entry>weak–pointer</entry></row>
+ <row><entry>yystype</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+ <indexterm class="endofrange" startref="idx:options"/>
+ </sect1>
+ <sect1 id="sec:yacc"><title>&yacc;/&bison;</title>
+ <para>Interfacing with a compiler generator is useful when a tree should be
+ build from some kind of input. &kpp; provides the
+ <constant>yystype</constant>-option (see <xref linkend="sec:options"/>)
+ which causes the generation of a header file needed by &yacc; to
+ cooperate. For
+ every token found, the desired &kpp; operator is called to create a term.
+ If <application>lex/flex</application> is used too, &yacc; has to be
+ run with the option which causes the generation of an other header file
+ needed
+ by <application>lex/flex</application> (<userinput>–d</userinput>
+ for &bison;). Appropriate files for the example can be found in appendix
+ <xref linkend="app:rpn"/>. The makefile uses implicit rules for
+ <application>flex</application> and &bison;.</para>
+ </sect1>
+ </chapter>
+
+ <!-- vim:set sw=2 ts=8 tw=80: -->
Index: llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kpp-rpn.xml
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kpp-rpn.xml:1.1
*** /dev/null Tue Apr 6 15:25:33 2004
--- llvm/test/Programs/MultiSource/Applications/kimwitu++/doc/kpp-rpn.xml Tue Apr 6 15:25:22 2004
***************
*** 0 ****
--- 1,332 ----
+ <appendix id="app:rpn">
+ <title>Complete code of RPN example</title>
+ <sect1><title>main.k</title>
+ <programlisting>
+ <![CDATA[
+ %{
+ #include <iostream>
+ #include "k.h"
+ #include "rk.h"
+ #include "unpk.h"
+ #include "csgiok.h"
+
+ int yyparse( );
+ aritherm root_term;
+ %}
+
+ %{ KC_TYPES_HEADER
+ extern aritherm root_term;
+ %}
+
+ %option yystype
+
+ void
+ printer( const char *s, uview v ) {
+ std::cout << s;
+ }
+
+ int
+ main( int argc, char** argv ) {
+ std::cout << "rpn calculator" << std::endl;
+ yyparse( );
+ aritherm canon_term = root_term -> rewrite( canonify );
+ aritherm simpl_term = canon_term -> rewrite( simplify );
+ std::cout << "simplified term in infix notation" << endl;
+ simpl_term -> unparse( printer, infix );
+ std::cout << std::endl;
+ }
+ ]]>
+ </programlisting>
+ </sect1>
+ <sect1><title>abstr.k</title>
+ <programlisting>
+ <![CDATA[
+ aritherm: SimpleTerm ( simpleterm )
+ | Plus ( aritherm aritherm )
+ | Minus ( aritherm aritherm )
+ | Mul ( aritherm aritherm )
+ | Div ( aritherm aritherm );
+
+ simpleterm: Number ( integer )
+ | Ident ( casestring );
+ ]]>
+ </programlisting>
+ </sect1>
+ <sect1><title>rpn.k</title>
+ <programlisting>
+ <![CDATA[
+ %rview simplify, canonify;
+
+ // 1 + 2 -> 3
+ Plus(SimpleTerm(Number(a)),SimpleTerm(Number(b)))->
+ <simplify:SimpleTerm(Number(plus(a,b)))>;
+ // 1 + 3 + b -> 4 + b
+ Plus(SimpleTerm(Number(a)),Plus(SimpleTerm(Number(b)),rem))->
+ <simplify:Plus(SimpleTerm(Number(plus(a,b))),rem)>;
+ // 1 + 3 - b -> 4 - b
+ Plus(SimpleTerm(Number(a)),Minus(SimpleTerm(Number(b)),rem))->
+ <simplify:Minus(SimpleTerm(Number(plus(a,b))),rem)>;
+ // 6 - 2 -> 4
+ Minus(SimpleTerm(Number(a)),SimpleTerm(Number(b)))->
+ <simplify:SimpleTerm(Number(minus(a,b)))>;
+ // 6 - 4 - b -> 2 - b
+ Minus(SimpleTerm(Number(a)),Minus(SimpleTerm(Number(b)),rem))->
+ <simplify:Minus(SimpleTerm(Number(minus(a,b))),rem)>;
+ // 6 - 4 + b -> 2 + b
+ Minus(SimpleTerm(Number(a)),Plus(SimpleTerm(Number(b)),rem))->
+ <simplify:Plus(SimpleTerm(Number(minus(a,b))),rem)>;
+ // 3 * 2 * b -> 6 * b
+ Mul(SimpleTerm(Number(a)),Mul(SimpleTerm(Number(b)),rem))->
+ <simplify:Mul(SimpleTerm(Number(mul(a,b))),rem)>;
+ // 3 * 2 / b -> 6 / b
+ Mul(SimpleTerm(Number(a)),Div(SimpleTerm(Number(b)),rem))->
+ <simplify:Div(SimpleTerm(Number(mul(a,b))),rem)>;
+ // 3 * 2 -> 6
+ Mul(SimpleTerm(Number(a)),SimpleTerm(Number(b)))->
+ <simplify:SimpleTerm(Number(mul(a,b)))>;
+ // 6 / 2 -> 3
+ Div(SimpleTerm(Number(a)),SimpleTerm(Number(b)))->
+ <simplify:SimpleTerm(Number(div(a,b)))>;
+ // 6 / 2 / b -> 3 / b
+ Div(SimpleTerm(Number(a)),Div(SimpleTerm(Number(b)),rem))->
+ <simplify:Div(SimpleTerm(Number(div(a,b))),rem)>;
+ // 6 / 2 * b -> 3 * b
+ Div(SimpleTerm(Number(a)),Mul(SimpleTerm(Number(b)),rem))->
+ <simplify:Mul(SimpleTerm(Number(div(a,b))),rem)>;
+
+ // a + a -> 2 * a
+ Plus(b=SimpleTerm(Ident(a)),SimpleTerm(Ident(a)))->
+ <simplify:Mul(SimpleTerm(Number(mkinteger(2))),b)>;
+ // a - a -> 0
+ Minus(SimpleTerm(Ident(a)),SimpleTerm(Ident(a)))->
+ <simplify: SimpleTerm(Number(mkinteger(0)))>;
+ // a / a -> 1
+ Div(SimpleTerm(Ident(a)),SimpleTerm(Ident(a)))->
+ <simplify: SimpleTerm(Number(mkinteger(1)))>;
+ // 6 * a + a -> 7 * a
+ Plus(Mul(SimpleTerm(Number(a)),SimpleTerm(Ident(b))),c=SimpleTerm(Ident(b)))->
+ <simplify: Mul(SimpleTerm(Number(plus(a,mkinteger(1)))),c)>;
+ // 6 * a -a -> 5 * a
+ Minus(Mul(SimpleTerm(Number(a)),SimpleTerm(Ident(b))),c=SimpleTerm(Ident(b)))->
+ <simplify: Mul(SimpleTerm(Number(minus(a,mkinteger(1)))),c)>;
+ // 6 * a + 3 * a -> 9 * a
+ Plus(Mul(SimpleTerm(Number(a)),SimpleTerm(Ident(b))),
+ Mul(SimpleTerm(Number(d)),c=SimpleTerm(Ident(b))))->
+ <simplify: Mul(SimpleTerm(Number(plus(a,d))),c)>;
+ // 6 * a - 2 * a -> 4 * a
+ Minus(Mul(SimpleTerm(Number(a)),SimpleTerm(Ident(b))),
+ Mul(SimpleTerm(Number(d)),c=SimpleTerm(Ident(b))))->
+ <simplify: Mul(SimpleTerm(Number(minus(a,d))),c)>;
+ // a + (a + 2 * b) -> 2 * a + 2 * b
+ Plus(b=SimpleTerm(Ident(a)),Plus(SimpleTerm(Ident(a)),rem))->
+ <simplify: Plus(Mul(SimpleTerm(Number(mkinteger(2))),b),rem)>;
+ // a - (a +- 2 * b) -> 2 * b
+ Minus(SimpleTerm(Ident(a)),Plus(SimpleTerm(Ident(a)),rem)),
+ Minus(SimpleTerm(Ident(a)),Minus(SimpleTerm(Ident(a)),rem))->
+ <simplify: rem>;
+ // a + (a - 2 * b) -> 2 * a - 2 * b
+ Plus(b=SimpleTerm(Ident(a)),Minus(SimpleTerm(Ident(a)),rem))->
+ <simplify: Minus(Mul(SimpleTerm(Number(mkinteger(2))),b),rem)>;
+
+ // (a + b) + c -> a + (b + c)
+ Plus( Plus(a, b), c)
+ -> < canonify: Plus(a, Plus(b, c))>;
+ // (a - b) + c -> c + (a - b)
+ Plus( Minus(a, b), c)
+ -> < canonify: Plus(c, Minus(a, b))>;
+ // (a + b) - c -> a + (b - c)
+ Minus( Plus(a, b), c)
+ -> < canonify: Plus(a, Minus(b, c))>;
+ // (a * b) * c -> a * (b * c)
+ Mul( Mul(a, b), c)
+ -> < canonify: Mul(a, Mul(b, c))>;
+ // a + 5 -> 5 + a
+ Plus( a=SimpleTerm(Ident(*)), b=SimpleTerm(Number(*)) )
+ -> < canonify: Plus(b, a)>;
+ // a * 5 -> 5 * a
+ Mul( a=SimpleTerm(Ident(*)), b=SimpleTerm(Number(*)) )
+ -> < canonify: Mul(b, a)>;
+ // a + (6 + b) -> 6 + (a + b)
+ Plus( a=SimpleTerm(Ident(*)), Plus(b=SimpleTerm(Number(*)), rest) )
+ -> < canonify: Plus(b, Plus(a,rest))>;
+ // a * (6 * b) -> 6 * (a * b)
+ Mul( a=SimpleTerm(Ident(*)), Mul(b=SimpleTerm(Number(*)), rest) )
+ -> < canonify: Mul(b, Mul(a,rest))>;
+
+ %{ KC_REWRITE
+ inline integer plus(integer a, integer b){
+ return mkinteger(a->value+b->value);
+ }
+ inline integer minus(integer a, integer b){
+ return mkinteger(a->value-b->value);
+ }
+ inline integer mul(integer a, integer b){
+ return mkinteger(a->value*b->value);
+ }
+ inline integer div(integer a, integer b){
+ return mkinteger(b->value==0 ? 0 : a->value / b->value);
+ }
+ %}
+
+ %uview infix,postfix;
+
+ Plus(a,b)->[infix: "(" a "+" b ")"];
+ Minus(a,b)->[infix: "(" a "-" b ")"];
+ Mul(a,b)->[infix: "(" a "*" b ")"];
+ Div(a,b)->[infix: "(" a "/" b ")"];
+ ]]>
+ </programlisting>
+ </sect1>
+ <sect1><title>lexic.l</title>
+ <programlisting>
+ <![CDATA[
+ %{
+ #include <iostream>
+ #include "k.h"
+ #include "yystype.h"
+ #include "syntax.h"
+ #include "rpn.h"
+ %}
+
+ %option noyywrap
+
+ %%
+
+ -?[0-9]+ { yylval.yt_integer = mkinteger(atoi(yytext)); return NUMBER;}
+ [a-z]+ { yylval.yt_casestring = mkcasestring(yytext); return IDENT; }
+ [+*-/] { return yytext[0]; }
+ [\t ]+ { /*empty*/ }
+ \n { return EOF; }
+ . { std::cerr << "Unkown character: " << yytext[0] << std::endl; }
+
+ %%
+
+ extern void yyerror(const char *s) {
+ std::cerr << "Syntax error: " << s << std::endl;
+ }
+
+ ]]>
+ </programlisting>
+ </sect1>
+ <sect1><title>syntax.y</title>
+ <programlisting>
+ <![CDATA[
+ %{
+ #include "k.h"
+ #include "yystype.h"
+
+ extern void yyerror(const char*);
+ extern int yylex();
+ %}
+
+ %token <yt_integer> NUMBER
+ %token <yt_casestring> IDENT
+ %token NEWLINE
+
+ %type <yt_aritherm> aritherm
+ %type <yt_simpleterm> simpleterm
+
+ %%
+
+
+ aritherm:
+ simpleterm
+ { root_term = $$ = SimpleTerm($1); }
+ | aritherm aritherm '+'
+ { root_term = $$ = Plus($1,$2); }
+ | aritherm aritherm '*'
+ { root_term = $$ = Mul($1,$2); }
+ | aritherm aritherm '-'
+ { root_term = $$ = Minus($1,$2); }
+ | aritherm aritherm '/'
+ { root_term = $$ = Div($1,$2); }
+ ;
+
+ simpleterm:
+ NUMBER
+ { $$ = Number($1); }
+ | IDENT
+ { $$ = Ident($1); }
+ ;
+ ]]>
+ </programlisting>
+ </sect1>
+ <sect1 id="app:make"><title>Makefile</title>
+ <programlisting>
+ <![CDATA[
+ # Reverse Polish Notation, Makefile
+ # c 2001, Michael Piefel <piefel at informatik.hu-berlin.de>
+
+ .PRECIOUS: lexic.c y.output
+
+ # Tools
+ SHELL = /bin/sh
+ YACC = bison
+ LEX = flex
+ CC = ${CXX}
+ KC = kc++
+
+ #Flages
+ YFLAGS = -d -y
+ LFLAGS = -t
+ CXXFLAGS = -g -Wall -Wno-unused -DYYDEBUG -DYYERROR_VERBOSE
+ CFLAGS = ${CXXFLAGS}
+
+ # Sources
+ KFILES = rpn.k main.k abstr.k
+ YFILES = syntax.y
+ LFILES = lexic.l
+
+
+ # Goals
+ PARSER = rpn-parser
+
+ # Help files
+
+ KC_TIME = .kc_time_stamp
+
+ KC_OGEN = k.o csgiok.o unpk.o rk.o
+ KC_OSRC = $(KFILES:.k=.o)
+ OBJS = $(KC_OGEN) $(KC_OSRC) $(YFILES:.y=.o) $(LFILES:.l=.o) $(CFILES:.cc=.o)
+
+
+ # default rule
+ $(PARSER)::
+
+ # include or make autodependencies
+ ifeq (.depend,$(wildcard .depend))
+ include .depend
+ else
+ $(PARSER):: depend
+ endif
+
+ # Rules
+ $(KC_TIME): $(KFILES)
+ $(KC) $(KFILES)
+ touch $(KC_TIME)
+
+ $(PARSER):: $(KC_TIME) $(OBJS)
+ $(CXX) $(CFLAGS) $(OBJS) ${LIBS} -o $@
+
+
+ syntax.h : y.tab.h
+ -cmp -s syntax.h y.tab.h || cp y.tab.h syntax.h
+
+ y.tab.h : syntax.c
+
+ depend dep:
+ @echo Make dependencies first
+ $(MAKE) $(KC_TIME)
+ $(MAKE) $(YFILES:.y=.c)
+ $(MAKE) $(LFILES:.l=.c)
+ $(MAKE) syntax.h
+ $(CC) -M *.cc > .depend
+
+ clean:
+ -rm -f $(OBJS) core *~ *.bak $(KFILES:.k=.cc) $(KC_OGEN:.o=.cc) $(KC_TIME) .kc* \
+ $(YFILES:.y=.c) $(LFILES:.l=.c) $(KC_OGEN:.o=.h) $(KFILES:.k=.h) out.* \
+ y.tab.h syntax.h syntax.output syntax.tab.c yystype.h
+ ]]>
+ </programlisting>
+ </sect1>
+ </appendix>
More information about the llvm-commits
mailing list