flexml-1.9.6/ 0000755 0001750 0001750 00000000000 12101762535 013324 5 ustar mquinson mquinson flexml-1.9.6/flexml-act-bootstrap.c 0000644 0001750 0001750 00000004474 12101762535 017550 0 ustar mquinson mquinson /* Flex(1) XML processor action language application.
* Copyright (c) 1999 Kristoffer Rose. All rights reserved.
*
* This file is part of the FleXML XML processor generator system.
* Copyright (c) 1999 Kristoffer Rose. All rights reserved.
*
* This program 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 License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
#include
#include
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__TOS_WIN__)
# ifndef __STRICT_ANSI__
# include
# include
# endif
#else
# include
#endif
#include "flexml-act.h"
extern char *bufferstack;
extern FILE* yyin;
extern int yylineno;
extern int yylex(void);
char* filename;
void STag_top(void)
{
printf("\n#line %d \"%s\"\n", yylineno, filename);
}
void ETag_top(void)
{
printf("%s\n", pcdata);
}
const char* tag;
void STag_start(void)
{
printf("void STag_%s(void)\n{", tag = A_start_tag);
printf("\n#line %d \"%s\"\n", yylineno, filename);
}
void ETag_start(void)
{
printf("%s\n} /* STag_%s */\n\n", pcdata, tag);
}
void STag_end(void)
{
printf("void ETag_%s(void)\n{", tag = A_end_tag);
printf("\n#line %d \"%s\"\n", yylineno, filename);
}
void ETag_end(void)
{
printf("%s\n} /* ETag_%s */\n\n", pcdata, tag);
}
char mainmissing = 1;
void STag_main(void) {}
void ETag_main(void)
{
printf("\n#line %d \"%s\"\n", yylineno, filename);
printf("%s\n", pcdata);
mainmissing = 0;
}
void STag_actions(void) {}
void ETag_actions(void) {
if (mainmissing) {
printf("/* Dummy main: filter XML from stdin. */\n");
printf("int main() { exit(yylex()); }\n");
}
}
int main(int argc, char** argv)
{
filename = argv[1];
yyin = fopen(filename,"r");
return yylex();
}
flexml-1.9.6/Makefile 0000644 0001750 0001750 00000010257 12101762535 014771 0 ustar mquinson mquinson # Make(1) rules for FleXML XML processor generator system.
# Copyright (c) 1999 Kristoffer Rose. All rights reserved.
#
# This file is part of the FleXML XML processor generator system.
# Copyright (c) 1999 Kristoffer Rose. All rights reserved.
#
# This program 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 License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA.
# $Id: Makefile,v 1.47 2013/01/29 14:35:24 mquinson Exp $
# SUFF (defined in Makefile.defs) is the versioning suffix added to binaries and
# resource files. To get rid of it (and do a non-versioned install,
# for example), do:
# make whatever SUFF=
# FILES.
include Makefile.defs
STUFF = GPL Makefile Makefile.defs flexml.pl
BINS = $(FLEXML)
LIBS = $(FLEXML_ACT)
DATA = skel
MANS = flexml.1
DOCS = README ChangeLog NEWS NOTES TODO flexml-act.dtd
HTMLS = FleXML.html paper.html
SRC = $(STUFF) $(DATA) $(DOCS) $(HTMLS)
ALL = $(PROGS) $(LIBS) $(DATA) $(MANS) $(DOCS) $(HTMLS)
.PHONY: all install dist test clean
# PRIMARY TARGETS.
all: $(ALL)
install: $(ALL)
mkdir -p $(DESTDIR)$(BINDIR) $(DESTDIR)$(LIBDIR) \
$(DESTDIR)$(MAN1DIR) $(DESTDIR)$(DOCDIR) \
$(DESTDIR)$(DATADIR) \
$(DESTDIR)$(DOCDIR)/html \
$(DESTDIR)$(DOCDIR)/examples
$(INSTALL) -m555 $(BINS) $(DESTDIR)$(BINDIR)/
$(INSTALL) -m555 $(LIBS) $(DESTDIR)$(LIBDIR)/
$(INSTALL) -m444 $(DATA) $(DESTDIR)$(DATADIR)/
$(INSTALL) -m444 $(MANS) $(DESTDIR)$(MAN1DIR)/
$(INSTALL) -m444 $(DOCS) $(DESTDIR)$(DOCDIR)/
$(INSTALL) -m444 $(HTMLS) $(DESTDIR)$(DOCDIR)/html/
if test "x$(SUFF)" != "x" ; then \
rm -f $(DESTDIR)$(BINDIR)/flexml; \
ln -s $(DESTDIR)$(BINDIR)/$(FLEXML) $(DESTDIR)$(BINDIR)/flexml;\
fi
$(MAKE) -C examples install
FLEXML_DISTDIR = $(FLEXML)-$(VER)
dist: test clean
@echo "Building distribution..."
mkdir $(FLEXML_DISTDIR)
cp $(STUFF) $(DATA) $(DOCS) $(HTMLS) flexml-act-bootstrap.c \
$(FLEXML_DISTDIR)
cp -r examples testbed $(FLEXML_DISTDIR)
find $(FLEXML_DISTDIR) -name CVS | xargs rm -rf
find $(FLEXML_DISTDIR) -name .cvsignore | xargs rm -rf
tar cvfz $(FLEXML_DISTDIR).tar.gz $(FLEXML_DISTDIR)
rm -rf $(FLEXML_DISTDIR)
#rsync -v FleXML.html $(WEBHOME)/FleXML.html
#rsync -va --cvs-exclude --delete-excluded ./ $(FTPHOME)/
clean::; @echo "Cleaning..."
$(RM) -rf $(FLEXML_DIR).tar.gz $(FLEXML_DIR)
$(RM) *.[olh1] *-dummy.? lex.* *~ ./#*
find -name '*~' | xargs $(RM)
test:: all
@echo "Testing..."
clean::; $(RM) $(FLEXML) $(FLEXML_ACT) flexml-act flexml-act.c
$(FLEXML): flexml.pl
sed \
-e "s;FLEXMLVERSION;$(VER);g" \
-e "s;[.][/]flexml-act;$(ACT);g" \
-e "s;[.][/]skel;$(SKEL);g" \
-e "s;/var/tmp;$(TMPDIR);g" \
-e "s;/usr/share/doc/;$(DOCDIR)/;g" flexml.pl > $@
chmod +x $@
ifneq ($(SUFF),)
$(FLEXML_ACT): flexml-act
cp flexml-act $@
endif
# Action language...
flexml-act.l: flexml-act.dtd skel
$(PERL) ./flexml.pl $(FLEXDEBUG) -Lv -ractions -s skel $<
flexml-act.c: flexml-act.l
$(FLEX) -B -s -v -oflexml-act.c flexml-act.l
flexml-act.o: flexml-act.c flexml-act.h
flexml-act-bootstrap.o: flexml-act-bootstrap.c flexml-act.h
flexml-act: flexml-act.o flexml-act-bootstrap.o
clean::; $(RM) TAGS
TAGS: $(SRC); etags $(SRC)
ci: $(SRC); ci -u $(SRC)
# DOCUMENTS.
clean::; $(RM) flexml.html index.html pod2html-*
flexml.1: $(FLEXML)
$(POD2MAN) $(FLEXML) > $@
flexml.html: $(FLEXML)
$(POD2HTML) < $(FLEXML) > $@
index.html: FleXML.html
sed 's.ftp/FleXML/..g' FleXML.html > $@
# TESTS.
clean::; $(MAKE) -C examples $@; $(MAKE) -C testbed $@
test::; $(MAKE) -C examples $@; \
$(MAKE) -C testbed $@ > test.out 2>&1; ! grep '^fail' test.out && \
echo "Tests succeeded."
# END.
clean::; @echo "Done cleaning."
test::; @echo "Done testing."
flexml-1.9.6/paper.html 0000644 0001750 0001750 00000043306 12101762535 015327 0 ustar mquinson mquinson
Generating Fast Validating XML Processors
Generating Fast Validating XML Processors
(Extended Abstract)
Abstract
We present FleXML, a program that generates fast
validating XML processors from `self-contained' XML DTDs. It uses
the flex (lexical analyser generator) program to
translate the DTD into a finite automaton enriched with a
stack with the `element context'. This means that the XML
processor will act directly on each character received. The
program is freely redistributable and modifyable (under GNU
`copyleft').
Keywords
Validating XML, DTD, lexical analysis, finite automata.
Overview
The `X' of XML stands for Extensible [XML]. This signifies that each and every
XML document specifies in its header the details of the format
that it will use and may change its format a bit relative
to the used base format.
This has influenced the tools available to write validating XML
processors: they use a call-back model where the XML
processor passes strings with the tags and attributes names and
values to the application. These call-backs must be generic
because one cannot know whether a document will start by
extending its own notation with more tags and attributes. For
well-formed but non-validated XML documents this makes
a lot of sense, of course, but we would in general like to
exploit the information in the DTD for optimizations.
In particular, for many applications a fixed format
suffices in the sense that a single DTD is used without
individual extensions for a large number of documents. In that
case we can do much better because the possible tags and
attributes are static.
We have implemented an XML processor generator using
the Flex scanner generator that
produces deterministic finite automata [ASU]. Which means that there is almost
no overhead for XML processing: the generated XML processors
read the XML document character by character and can immediately
dispatch the actions associated with each element (or reject the
document as invalid).
Furthermore we have devised a simple extension of the C
programming language that facilitates the writing of `element
actions' in C, making it easy to write really fast XML
applications. In particular we represent XML attribute values
efficiently in C when this is possible, thus avoiding the
otherwise ubiquitous conversions between strings and data
values.
FleXML is available for free
(from SourceForge).
In this paper we present FleXML through an
elaborated example and discuss some of the
technical issues.
Assume that we have an XML document my-joke.xml
containing the classical joke
<!DOCTYPE joke SYSTEM "my.dtd">
<joke><line>My appartment is so small</line> <suspense/>
<line type='punch-line'>the mice are round-shouldered</line></joke>
(and many others like it, of course). We wish to create an XML
processor to validate it with respect to the DTD in the file
my.dtd
containing
<!-- my.dtd: Small DTD for jokes (just for fun). -->
<!ELEMENT joke (line,(line|suspense)*)>
<!ELEMENT line (#PCDATA)>
<!ATTLIST line type (normal|question|punch-line) 'normal'>
<!ELEMENT suspense EMPTY>
and, furthermore, we wish to write an XML application for
displaying such messages in an amusing way.
With FleXML this can be done by creating an `actions file'
my-show.act
which implements the desired actions
for each element. The remainder of this section explains the
contents of such an actions file.
An actions file is itself an XML document which must begin with
<!DOCTYPE actions SYSTEM "flexml-act.dtd">
<actions>
(the flexml-act.dtd
DTD is part of the FleXML
system and is reproduced in the manual page.
We decide that our application should react to a
line
element by printing the text inside it, and
that it should differentiate between the three possible `type'
attribute values by printing corresponding trailing punctuation.
This introduces a slight complication, because the attribute
values are available when parsing the start tag whereas the
element text is not available until we parse the end tag (where
it has been read).
This means that we must declare a top-level variable.
<top><![CDATA[
char* terminator = ".";
]]></top>
Notice how we use CDATA
sections to make sure that
all characters (including white-space) are passed unmodified to
the C compiler.
With this we can write the action to set it when reading the
line
start tag as
<start tag='line'><![CDATA[
switch ( {type} ) {
case {!type}: terminator = "..."; break;
case {type=normal}: terminator = "."; break;
case {type=question}: terminator = "??"; break;
case {type=punch-line}: terminator = "!!"; break;
}
]]></start>
The idea is that the enumeration attribute type
is
implemented in C as if it had been declared by
enum { {!type}, {type=normal}, {type=question}, {type=punch-line} } {type};
(understanding the {...}
units as C identifiers),
hence the possibility of using the fast C switch
statement to pick the right choice directly. Note that the
first choice, {!type}
, corresponds to not
setting the attribute; in this example the attribute has a
default value so this can never happen, however, we include the
choice anyway to prevent the C compiler from issuing warnings
about missing choices in switch
statements.
With this in place we can write the action for
</line>
. Since it prints something, however,
we first need to add the appropriate header inclusion.
<top><![CDATA[
#include <stdio.h>
]]></top>
<end tag='line'><![CDATA[
printf("%s%s\n", pcdata, terminator);
]]></end>
Finally, we will make the application amusing by `displaying'
the <suspense/>
empty tag as a short delay;
this also involves a header inclusion.
<top><![CDATA[
#include <unistd.h>
]]></top>
<start tag='suspense'><![CDATA[
sleep(2);
]]></start>
That is all; the only remaining thing is to terminate the action
file properly.
</actions>
We can now run FleXML with the DTD and the actions file as input
and will get an XML application as output that, when run (after
processing by flex and a C compiler), will indeed print
My appartment is so small.
the mice are round-shouldered!!
as expected, pausing duly for two seconds between the lines. On
the authors system the above output was achieved with the
command sequence
flexml -A -a my-show.act my.dtd
flex -omy-show.c my-show.l
cc -omy-show my-show.c
./my-show <./my-joke.xml
(see the manual page for the exact meaning of the FleXML options).
An important aspect of the design of FleXML is that the only
thing that should matter to the programmer should be the
complexity of the application, not of the used DTD. As
an example the following action file prints the
href
attribute of all hyperlinks in an XHTML
document:
<!DOCTYPE actions SYSTEM "flexml-act.dtd">
<actions>
<top><![CDATA[
#include <stdio.h>
]]></top>
<start tag='a'><![CDATA[
if ({href}) printf("%s\n", {href});
]]></start>
</actions>
which was compiled into a running application on the author's
system with the commands
flexml $(FLEXDEBUG) -rhtml -p'-//IETF//DTD XHTML 1.0 Transitional//EN' \
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'
gcc -Wall -ansi -pedantic -O2 -g -c xhtml-href.c -o xhtml-href.o
flex -Bsv -Ca -oxhtml1-transitional.c xhtml1-transitional.l
gcc -Wall -ansi -pedantic -O2 -g -c xhtml1-transitional.c -o xhtml1-transitional.o
gcc -Wall -ansi -pedantic xhtml-href.o xhtml1-transitional.o -o xhtml-href
generating the XML processor directly from the official DTD on
the web (which in fact required a patch to flex to enlarge the
possible table size).
FleXML is a perl script [Perl]
which reads and interprets a DTD and subsequently produces an
XML processor source file for the flex scanner
and optionally an XML application with the C source of
the element actions from an actions file. The DTD is used to
construct the rules used by flex to match the individual XML
components in such a way that only valid documents match.
For example, the flex code for scanning an attribute declaration
of the line
tag is the following:
<AL_line>{
"type"{Eq}"'normal'" |
"type"{Eq}"\"normal\"" A_line_type = A_line_type_normal;
"type"{Eq}"'question'" |
"type"{Eq}"\"question\"" A_line_type = A_line_type_question;
"type"{Eq}"'punch-line'" |
"type"{Eq}"\"punch-line\"" A_line_type = A_line_type_punch_d_line;
">" {
LEAVE; STag_line(); pcdata = BUFFERSET(pcdata); ENTER(IN_line);
}
"/>" {
LEAVE; STag_line(); pcdata = ""; ETag_line();
switch (YY_START) {
case ROOT_line: SET(EPILOG); break;
case S_joke: SET(S_joke_1); break;
case S_joke_1: case S_joke_2: case S_joke_3: SET(S_joke_3); break;
}}}
(with {Eq}
an alias for the regular expression
matching an equal sign (corresponding to production `[25] Eq' of
the XML specification).
This reads as follows: when the XML processor is reading the
attribute list of the line
tag, i.e., when it is in
the <AL_line>
state, a `t
' will
enter an internal state where a `y
' proceeds to
another internal state but other characters makes the document
invalid (because no rule permits it). Once the equal sign has
been scanned, the next characters determine the attribute value,
and at the end one of the flex actions is performed, setting the
attribute value (A_line_type
is the real C for what
we wrote as {type}
, etc.). The important thing is
that one can ensure by careful tuning of the flex rules that a
valid document will proceed only by looking each character up in
a table and determining the subsequent `state' and `action'.
One must avoid pairs of rules such as
"-->" LEAVE(COMMENT);
. SKIP;
(a single `.
' matches any character) because they
mean that the scanner will not be sure after having read a
`-
' character whether it is part of a comment
terminator or `just' a dash. In such cases an extra rule must be
inserted because for the set
"-->" LEAVE(COMMENT);
"--" |
. SKIP;
the problem goes away.
After the actual attribute rules, two rules handle termination
of the attribute list. There are two cases corresponding to
whether we just read a start tag or an empty element. In case
it was a start tag then we must enter the `inner' mode of the
element called IN_line
for the line
element. The switch
handles the state changes
needed for the line element resulting from the fact that the
element can appear in different contexts. This is always
possible to construct because of the requirement that an XML DTD
must be deterministic: we just need an element content
stack (this is what the LEAVE
and
ENTER
macros are for).
In comparison with the forthcoming XML Style-sheet Language
[XSL] our approach is much more
primitive for better and worse: only a limited range of
applications can be produced with FleXML but those will be very
fast.
This is useful for XML applications that are meant to process a
large number of documents in a fixed format. One such
application is the NTSys u-payment transaction server which is
implemented as an Apache module where performance is of premium
importance. Using FleXML permits a highly modular development
of modules for the various transaction types based on a common
DTD and a collection of applications that are generated
separately and all linked together with the common processor.
FleXML is still under development: please try it out (either
from SourceForge
or from the Debian
GNU/Linux distribution where FleXML is include from release
2.2. The author would welcome comments as to how the system can
best evolve. Two things that are definitely on the agenda is a
limited `context condition' language for expressing constraints
on the position of an element in a document (corresponding to
the Xpath subset of XSL), and an efficient way to combine
several DTDs into one large t facilitate general XML servers
(that can even dispatch to a generic XML interface in cases
where the FleXML restrictions are not respected by a document).
Acknowledgements
I am grateful to NTSys for
supporting the development of FleXML. Finally extend my sincere
thanks to Jef Poskanzer, Vern Paxson, and the rest of the
flex maintainers for a great tool.
References
- ASU
-
Alfred Aho, Ravi Sethi and Jeffrey Ullman: Compilers:
Principles, Techniques and Tools, Addison-Wesley
(1986).
- Flex
-
Jef Poskanzer, Vern Paxson, et. al.: Flex - fast
lexical analyzer generator.
- Perl
-
Larry Wall, Perl - Practical Extraction and Report
Language.
- XML
-
Extensible Markup Language (XML) 1.0 (W3C
Recommendation REC-xml-1998-0210).
- XSL
-
Extensible Stylesheet Language (XSL) (W3C Working Draft).
Copyright (c)
Kristoffer Rose.
Last modified: Tue Feb 11 13:56:40 EST 2003
flexml-1.9.6/GPL 0000644 0001750 0001750 00000043127 12101762535 013700 0 ustar mquinson mquinson GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 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.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program 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.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public 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.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C) 19yy
This program 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 License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
flexml-1.9.6/NOTES 0000644 0001750 0001750 00000004614 12101762535 014144 0 ustar mquinson mquinson # FleXML fast XML scanner framework
# Copyright (c) 1999 Kristoffer Rose. All rights reserved.
#
# Description: Notes for FleXML scanner generator
# Author: Kristoffer Rose
# Created: August 1999
# License: NTSys proprietary
#
# This program 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 License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# $Id: NOTES,v 1.3 2006/07/18 18:21:13 mquinson Exp $
GUIDELINES FOR WRITING A flex(1) SCANNER FOR SIMPLE XML FORMATS.
We know how to handle the following DTD element declarations.
1. "Leaf" elements with the declarations
Start conditions:
%x AL_tag
Rules:
"" STag(tag), ETag(tag);
"" STag(tag), ENTER(PCDATA);
""/>" LEAVE, Etag(tag);
">" LEAVE, ENTER(PCDATA);
"" Etag(tag), LEAVE;
Handlers:
STag_tag(void) {...}
ETag_tag(char* pcdata) {...}
2. "Logical" elements with unordered element contents using the declaration
Start conditions:
%x AL_tag
%x IN_tag
Rules:
"" STag(tag), ETag(tag);
"" STag(tag), ENTER(IN_tag);
""/>" LEAVE, Etag(tag);
">" BEGIN(IN_tag);
"" Etag(tag);
Handlers:
STag_tag(void) {...}
ETag_tag(char* pcdata) {...}
3. "Attribute" declarations of the form
Rule:
"attribute"{Eq}{Q} Attribute(tag,attribute);
Handler:
Attribute_tag_attribute(char* value) {...}
That's all, for the moment.
Note: the scanner can be made (more) validating by using the
condition in front of all the rules in tag1...tagn and give the
top-level rules the start condition INITIAL.
flexml-1.9.6/testbed/ 0000755 0001750 0001750 00000000000 12101762535 014756 5 ustar mquinson mquinson flexml-1.9.6/testbed/mixed-stratt.dtd 0000644 0001750 0001750 00000000227 12101762535 020101 0 ustar mquinson mquinson
flexml-1.9.6/testbed/biparser-two.in 0000644 0001750 0001750 00000000134 12101762535 017722 0 ustar mquinson mquinson
012456789abcdefghijklmn
flexml-1.9.6/testbed/CompareOut.pl 0000755 0001750 0001750 00000004414 12101762535 017377 0 ustar mquinson mquinson #!/usr/bin/env perl
# Assume ARGV is ($basename @REST). Print "passed" or "failed" based on the
# following comparisons:
# Compare $basename.stderr with $basename.stderr.expected
# pass if no difference or
# $basename.stderr is empty and $basename.stderr.expected doesn't exist;
# Compare $basename.stdout with $basename.stdout.expected
# pass if no difference or
# $basename.stdout is empty and $basename.stdout.expected doesn't exist;
# For each file $foo in @REST
# Compare $foo with $foo.expected
# pass if no difference;
# Print "passed" if all tests pass, otherwise print
# "failed "
# NOTES
# In order to compare directories, GNU diff must be used. There
# should probably be a test to ensure this.
# $Id: CompareOut.pl,v 1.2 2006/08/21 17:33:13 wdowling Exp $
# $Source: /cvsroot/flexml/flexml/testbed/CompareOut.pl,v $
use strict;
use Getopt::Std;
my %args;
getopts('p:', \%args);
my $diff_prog = $args{'p'} || 'diff';
my $diff_opt = "";
if ($ARGV[0] =~ /^-/) {
$diff_opt = shift;
}
my $basename = shift;
my $diff_cmd = "$diff_prog $diff_opt";
my $retcode;
my $fail_file;
my $made_stdout = 0;
my $made_stderr = 0;
# Compare basename.stderr to basename.stderr.expected
if (! -f "$basename.stderr.expected") {
system("touch $basename.stderr.expected");
$made_stderr = 1;
}
$retcode =
system("$diff_cmd $basename.stderr $basename.stderr.expected " .
"> $basename.stderr.diff 2>/dev/null");
system("rm -f $basename.stderr.expected") if $made_stderr;
$fail_file = "$basename.stderr" if $retcode;
# Compare basename.stdout to basename.stdout.expected
if ($retcode == 0) {
if (! -f "$basename.stdout.expected") {
system("touch $basename.stdout.expected");
$made_stdout = 1;
}
$retcode =
system("$diff_cmd $basename.stdout $basename.stdout.expected " .
"> $basename.stdout.diff 2>/dev/null");
system("rm -f $basename.stdout.expected") if $made_stdout;
$fail_file = "$basename.stdout" if $retcode;
}
while (($retcode == 0) && @ARGV) {
my $file = shift;
# compare file with file.expected
$retcode = system("$diff_cmd $file $file.expected >$file.diff 2>/dev/null");
$fail_file = $file if $retcode;
}
print ($retcode ? "failed $fail_file\n" : "passed $basename\n");
flexml-1.9.6/testbed/Makefile 0000644 0001750 0001750 00000014765 12101762535 016433 0 ustar mquinson mquinson # $Source: /cvsroot/flexml/flexml/testbed/Makefile,v $
# regression testbed Makefile
#####################################################
# Fixed definitions -- do not modify for new tests
#####################################################
include ../Makefile.defs
MAKEUTILS_DIR = .
# If UNIT_TESTS is test_foo
# and test_foo_out is bar baz
# Then the created files (that need to be deleted by 'make clean'
# will be
# test_foo foo.std{err,out} foo.std{err,out}.diff bar baz bar.diff baz.diff
TEST_INTERMEDIATES = \
$(UNIT_TESTS) \
$(UNIT_TESTS:test_%=%.stdout) $(UNIT_TESTS:test_%=%.stdout.diff) \
$(UNIT_TESTS:test_%=.test_%.stdout.expected) \
$(UNIT_TESTS:test_%=%.stderr) $(UNIT_TESTS:test_%=%.stderr.diff) \
$(UNIT_TESTS:test_%=.test_%.stderr.expected) \
$(foreach var,$(UNIT_TESTS:%=%_out),$(foreach o,$($(var)),$o $(o).diff))
# Compares test.out.std[out,err] with expected values
COMPARE_OUT = $(MAKEUTILS_DIR)/CompareOut.pl
#CC = /usr/bin/gcc-3.3 -Wall
#CFLAGS = -O2 -g
#FLEXDEBUG = -d
FLEXML = ../flexml -s ../skel -T../flexml-act
.PHONY : test
.PHONY : clean
#####################################################
# test definitions -- add new tests here
#####################################################
EXES = \
biparser \
init_header \
missing-att \
multiple-att \
mixed-enumatt \
mixed-enumatt2 \
mixed-stratt \
mixed-stratt-def \
mixed1 \
multi-parser-run
INTERMEDIATES = $(EXES) $(EXES:%=%.c) $(EXES:%=%.l)
# leave this alphabetically sorted for easy scanning
UNIT_TESTS = \
test_biparser \
test_init_header \
test_missing-att \
test_multiple-att \
test_mixed-enumatt \
test_mixed-enumatt2 \
test_mixed-stratt \
test_mixed-stratt-def \
test_mixed1 \
test_multi-parser-run
test : $(UNIT_TESTS)
# Test init_header
test_init_header_cmd = ./init_header < init_header.in
test_init_header_deps = init_header init_header.in
# Test missing REQUIRED attribute
test_missing-att_cmd = ./missing-att < missing-att.in
test_missing-att_deps = missing-att missing-att.in
# Test multiply defined attribute
test_multiple-att_cmd = ./multiple-att < multiple-att.in
test_multiple-att_deps = multiple-att multiple-att.in
# Test mixed1
test_mixed1_cmd = ./mixed1 < mixed1.in
test_mixed1_deps = mixed1 mixed1.in
# Test mixed-enumatt (mixed content + enumerated attribute)
test_mixed-enumatt_cmd = ./mixed-enumatt < mixed-enumatt.in
test_mixed-enumatt_deps = mixed-enumatt mixed-enumatt.in
# Test mixed-enumatt2 (mixed content + enumerated attribute, eval'ed in end tag)
test_mixed-enumatt2_cmd = ./mixed-enumatt2 < mixed-enumatt2.in
test_mixed-enumatt2_deps = mixed-enumatt2 mixed-enumatt2.in
# Test mixed-stratt (mixed content + string attribute)
test_mixed-stratt_cmd = ./mixed-stratt < mixed-stratt.in
test_mixed-stratt_deps = mixed-stratt mixed-stratt.in
# Test mixed-stratt (mixed content + default string attribute)
test_mixed-stratt-def_cmd = ./mixed-stratt-def < mixed-stratt-def.in
test_mixed-stratt-def_deps = mixed-stratt-def mixed-stratt-def.in
# Test multi-parser-run (Run the parser several times on "different" files)
test_multi-parser-run_cmd = ./multi-parser-run multi-parser-run.in
test_multi-parser-run_deps = multi-parser-run multi-parser-run.in
# Test biparser (Have two parsers in the same code)
test_biparser_cmd = ./biparser biparser-one.in biparser-two.in
test_biparser_deps = biparser biparser-one.in biparser-two.in
biparser: biparser-one.dtd biparser-two.dtd biparser.precious.c
for n in one two ; do \
$(FLEXML) -P$$n -H biparser-$$n.h -L biparser-$$n.dtd; \
$(FLEXML) -P$$n -S biparser-$$n.l -L biparser-$$n.dtd; \
$(FLEX) -s -L -P$${n}_ -obiparser-$$n.c biparser-$$n.l; \
done
$(CC) $(CFLAGS) -o biparser \
biparser-one.c biparser-two.c \
biparser.precious.c
CLEANFILES+= biparser-one.h biparser-one.l biparser-one.c \
biparser-two.h biparser-two.l biparser-two.c
init_header : init_header.act init_header.dtd init_header.h
$(FLEXML) -b 1000 -A -i$@.h -a$@.act $@.dtd
$(FLEX) -s -L -o$@.c $@.l
$(CC) $(CFLAGS) -o $@ $@.c
% : %.dtd %.act
$(FLEXML) -b 1000 -A -a$@.act $@.dtd
$(FLEX) -s -L -o$@.c $@.l
$(CC) $(CFLAGS) -o $@ $@.c
##############################################################
# test build rules -- add override build rules here if needed
##############################################################
#mixed1: mixed1.dtd mixed1.act
# $(FLEXML) -b 500 -A -amixed1.act mixed1.dtd
# $(FLEX) -s -L -o mixed1.c mixed1.l > mixed1.c
# $(CC) $(CFLAGS) -o $@ mixed1.c
#####################################################
# test infrastructure -- do not modify for new tests
#####################################################
clean :
rm -f $(TEST_INTERMEDIATES) $(INTERMEDIATES) $(CLEANFILES)
# When we are building test_foo, the variable $(TEST_BASE) is "foo"
test_% : TEST_BASE = $(@:test_%=%)
ifndef distribute_deps
# This will take a target and dependency list, and evaluate each dependency
# individually. This only needs to be used on dependency lists that are to
# be in an $(eval ...) function. This is a work-around for a bug in GNU Make
# 3.80, which fails when $(eval)'ing dependency lists longer than about 160
# characters.
# 1. target
# 2. dependency list
define distribute_deps
$(foreach dep,$(2),$(eval $(1) : $(dep)))
endef
endif
define unit_test_deps_t
$(1) : .$(1).stdout.expected
$(1) : .$(1).stderr.expected
$$(call distribute_deps,$(1),$($(1)_deps))
endef
$(foreach test,$(UNIT_TESTS),$(eval $(call unit_test_deps_t,$(test))))
# To build .test_foo.std{err,out}.expected --
# If foo.std{err,out}.expected exists, symlink to it
# Else, .test_foo.std{err,out}.expected is a new empty file
# These rules are invoked from rules in the Extradeps section.
# They must be two separate rules (else 'make test' not idempotent
# -- see bug #105)
.test_%.stderr.expected:
@if [ -f $(@:.test_%=%) ]; \
then $(SYMLINK) $(@:.test_%=%) $@; \
else touch $@; \
fi
.test_%.stdout.expected:
@if [ -f $(@:.test_%=%) ]; \
then $(SYMLINK) $(@:.test_%=%) $@; \
else touch $@; \
fi
# Unit test rule. Expects:
# UNIT_TESTS = test_foo test_bar (test_ prefix is necessary)
# test_foo_cmd = command to run
# test_foo_deps = dependencies (i.e. inputs to the test, and the executable)
# test_foo_out = files and directories created by running the command
# with corresponding .expected files for comparison
$(UNIT_TESTS) :
@$(test_$(@:test_%=%)_cmd) > $(@:test_%=%).stdout \
2>$(@:test_%=%).stderr || true
@$(PERL) $(COMPARE_OUT) -p '$($(@)_diff_prog)' -- \
$($(@)_diff_opts) $(@:test_%=%) $($(@)_out) | tee $@
flexml-1.9.6/testbed/mixed-enumatt2.in 0000644 0001750 0001750 00000000431 12101762535 020147 0 ustar mquinson mquinson
foo start data
reqatt data
defatt data
defatt data
optatt data
optatt data
foo end data.
flexml-1.9.6/testbed/mixed-stratt.act 0000644 0001750 0001750 00000000761 12101762535 020100 0 ustar mquinson mquinson
]]>
flexml-1.9.6/testbed/init_header.in 0000644 0001750 0001750 00000000126 12101762535 017560 0 ustar mquinson mquinson
012456789abcdefghijklmn
flexml-1.9.6/testbed/biparser.precious.c 0000644 0001750 0001750 00000004146 12101762535 020566 0 ustar mquinson mquinson #include
#include "biparser-one.h"
#include "biparser-two.h"
/* XML application entry points.
Should be generated from two action files, but I wasn't succesfull in that area yet [Mt] */
void STag_one_foo(void) {}
void ETag_one_foo(void) {printf("foo pcdata: %s\n", one_pcdata);}
void STag_one_bar(void) {}
void ETag_one_bar(void) {printf("bar pcdata: %s\n", one_pcdata);}
void STag_two_toto(void) {}
void ETag_two_toto(void) {printf("toto pcdata: %s\n", two_pcdata);}
void STag_two_tutu(void) {}
void ETag_two_tutu(void) {printf("tutu pcdata: %s\n", two_pcdata);}
/* Parsers control.
Should probably be added to the .h */
#ifndef YY_TYPEDEF_YY_BUFFER_STATE
#define YY_TYPEDEF_YY_BUFFER_STATE
typedef struct yy_buffer_state *YY_BUFFER_STATE;
#endif
extern int one_lex (void);
extern void one_restart (FILE *input_file );
extern void one__switch_to_buffer (YY_BUFFER_STATE new_buffer );
YY_BUFFER_STATE one__create_buffer (FILE *file,int size );
extern void one__delete_buffer (YY_BUFFER_STATE b );
extern void one__flush_buffer (YY_BUFFER_STATE b );
extern void one_push_buffer_state (YY_BUFFER_STATE new_buffer );
extern void one_pop_buffer_state (void );
extern int two_lex (void);
extern void two_restart (FILE *input_file );
extern void two__switch_to_buffer (YY_BUFFER_STATE new_buffer );
extern YY_BUFFER_STATE two__create_buffer (FILE *file,int size );
extern void two__delete_buffer (YY_BUFFER_STATE b );
extern void two__flush_buffer (YY_BUFFER_STATE b );
extern void two_push_buffer_state (YY_BUFFER_STATE new_buffer );
extern void two_pop_buffer_state (void );
int main(int argc, char **argv) {
FILE *infile;
YY_BUFFER_STATE buff;
int retval;
printf("Parse biparser-one.in\n");
infile=fopen("biparser-one.in","r");
buff=one__create_buffer(infile,10);
one__switch_to_buffer(buff);
retval = one_lex();
one__delete_buffer(buff);
fclose(infile);
printf("Parse biparser-two.in\n");
infile=fopen("biparser-two.in","r");
buff=two__create_buffer(infile,10);
two__switch_to_buffer(buff);
retval = two_lex() || retval;
two__delete_buffer(buff);
fclose(infile);
return retval;
}
flexml-1.9.6/testbed/mixed1.act 0000644 0001750 0001750 00000000646 12101762535 016644 0 ustar mquinson mquinson
]]>
flexml-1.9.6/testbed/multiple-att.in 0000644 0001750 0001750 00000000151 12101762535 017724 0 ustar mquinson mquinson
012456789abcdefghijklmn
flexml-1.9.6/testbed/multiple-att.stdout.expected 0000644 0001750 0001750 00000000013 12101762535 022435 0 ustar mquinson mquinson retval = 1
flexml-1.9.6/testbed/init_header.dtd 0000644 0001750 0001750 00000000145 12101762535 017726 0 ustar mquinson mquinson
flexml-1.9.6/testbed/missing-att.dtd 0000644 0001750 0001750 00000000227 12101762535 017713 0 ustar mquinson mquinson
flexml-1.9.6/testbed/mixed-enumatt.dtd 0000644 0001750 0001750 00000000415 12101762535 020234 0 ustar mquinson mquinson
flexml-1.9.6/testbed/multi-parser-run.stdout.expected 0000644 0001750 0001750 00000000360 12101762535 023247 0 ustar mquinson mquinson Run 0
foo attributes name='toto' toz='0.0' gaz='0.0'
bar attributes name='tutu'
Run 1
foo attributes name='toto' toz='0.0' gaz='0.0'
bar attributes name='tutu'
Run 2
foo attributes name='toto' toz='0.0' gaz='0.0'
bar attributes name='tutu'
flexml-1.9.6/testbed/mixed-stratt-def.act 0000644 0001750 0001750 00000001046 12101762535 020631 0 ustar mquinson mquinson
]]>
flexml-1.9.6/testbed/biparser-two.dtd 0000644 0001750 0001750 00000000073 12101762535 020071 0 ustar mquinson mquinson
flexml-1.9.6/testbed/missing-att.stdout.expected 0000644 0001750 0001750 00000000013 12101762535 022253 0 ustar mquinson mquinson retval = 1
flexml-1.9.6/testbed/mixed-stratt.in 0000644 0001750 0001750 00000000144 12101762535 017732 0 ustar mquinson mquinson
012456789abcdefghijklmn
flexml-1.9.6/testbed/multiple-att.act 0000644 0001750 0001750 00000000761 12101762535 020074 0 ustar mquinson mquinson
]]>
flexml-1.9.6/testbed/init_header.h 0000644 0001750 0001750 00000000310 12101762535 017374 0 ustar mquinson mquinson /* header file to be included at end of generated %{ ... %} section */
#define YY_DECL static int static_lexer_param; int lexer(int lexer_param)
#define YY_USER_INIT static_lexer_param = lexer_param;
flexml-1.9.6/testbed/mixed-enumatt2.stdout.expected 0000644 0001750 0001750 00000000473 12101762535 022671 0 ustar mquinson mquinson reqatt pcdata: reqatt data
reqatt att: (val1)
defatt pcdata: defatt data
defatt att: (val1)
defatt pcdata: defatt data
defatt att: (val2)
optatt pcdata: optatt data
optatt att: (val1)
optatt pcdata: optatt data
optatt att: (no att given)
foo pcdata: foo start data
foo end data.
retval = 0
flexml-1.9.6/testbed/mixed-enumatt2.dtd 0000644 0001750 0001750 00000000415 12101762535 020316 0 ustar mquinson mquinson
flexml-1.9.6/testbed/multiple-att.dtd 0000644 0001750 0001750 00000000227 12101762535 020075 0 ustar mquinson mquinson
flexml-1.9.6/testbed/biparser.stdout.expected 0000644 0001750 0001750 00000000220 12101762535 021623 0 ustar mquinson mquinson Parse biparser-one.in
bar pcdata: 456789ab
foo pcdata: 012cdefghijklmn
Parse biparser-two.in
tutu pcdata: 456789ab
toto pcdata: 012cdefghijklmn
flexml-1.9.6/testbed/biparser-one.dtd 0000644 0001750 0001750 00000000067 12101762535 020044 0 ustar mquinson mquinson
flexml-1.9.6/testbed/mixed1.in 0000644 0001750 0001750 00000000121 12101762535 016467 0 ustar mquinson mquinson
012456789abcdefghijklmn
flexml-1.9.6/testbed/biparser-one.in 0000644 0001750 0001750 00000000127 12101762535 017674 0 ustar mquinson mquinson
012456789abcdefghijklmn
flexml-1.9.6/testbed/mixed-stratt-def.in 0000644 0001750 0001750 00000000333 12101762535 020466 0 ustar mquinson mquinson
012
bar data 1
bar data 2
bar data 3
cdefghijklmn
flexml-1.9.6/testbed/multi-parser-run.act 0000644 0001750 0001750 00000001262 12101762535 020676 0 ustar mquinson mquinson
]]>
flexml-1.9.6/testbed/mixed-enumatt.in 0000644 0001750 0001750 00000000430 12101762535 020064 0 ustar mquinson mquinson
foo start data
reqatt data
defatt data
defatt data
optatt data
optatt data
foo end data.
flexml-1.9.6/testbed/mixed1.dtd 0000644 0001750 0001750 00000000145 12101762535 016642 0 ustar mquinson mquinson
flexml-1.9.6/testbed/multiple-att.stderr.expected 0000644 0001750 0001750 00000000107 12101762535 022422 0 ustar mquinson mquinson Invalid XML (state 13): Multiple definition of attribute batt in
flexml-1.9.6/testbed/mixed-stratt.stdout.expected 0000644 0001750 0001750 00000000113 12101762535 022442 0 ustar mquinson mquinson bar att: batt1
bar pcdata: 456789ab
foo pcdata: 012cdefghijklmn
retval = 0
flexml-1.9.6/testbed/mixed-enumatt2.act 0000644 0001750 0001750 00000002104 12101762535 020307 0 ustar mquinson mquinson
]]>
flexml-1.9.6/testbed/mixed-stratt-def.dtd 0000644 0001750 0001750 00000000407 12101762535 020635 0 ustar mquinson mquinson
flexml-1.9.6/testbed/init_header.stdout.expected 0000644 0001750 0001750 00000000110 12101762535 022265 0 ustar mquinson mquinson bar pcdata: 456789ab
foo pcdata: 012cdefghijklmn
param was 7
retval = 0
flexml-1.9.6/testbed/multi-parser-run.in 0000644 0001750 0001750 00000000130 12101762535 020526 0 ustar mquinson mquinson
flexml-1.9.6/testbed/mixed-stratt-def.stdout.expected 0000644 0001750 0001750 00000000606 12101762535 023205 0 ustar mquinson mquinson bar batt: (default value) batt2: (second default value) batt3: (third default value)
bar pcdata: bar data 1
bar batt: (default value) batt2: ( non-default 2) batt3: (third default value)
bar pcdata: bar data 2
bar batt: (default value) batt2: (second default value) batt3: (non-default with single-quote('))
bar pcdata: bar data 3
foo pcdata: 012
cdefghijklmn
retval = 0
flexml-1.9.6/testbed/multi-parser-run.dtd 0000644 0001750 0001750 00000000262 12101762535 020701 0 ustar mquinson mquinson
flexml-1.9.6/testbed/init_header.act 0000644 0001750 0001750 00000000711 12101762535 017721 0 ustar mquinson mquinson
]]>
flexml-1.9.6/testbed/mixed-enumatt.act 0000644 0001750 0001750 00000002302 12101762535 020225 0 ustar mquinson mquinson
]]>
flexml-1.9.6/testbed/mixed1.stdout.expected 0000644 0001750 0001750 00000000074 12101762535 021212 0 ustar mquinson mquinson bar pcdata: 456789ab
foo pcdata: 012cdefghijklmn
retval = 0
flexml-1.9.6/testbed/missing-att.in 0000644 0001750 0001750 00000000126 12101762535 017544 0 ustar mquinson mquinson
012456789abcdefghijklmn
flexml-1.9.6/testbed/missing-att.stderr.expected 0000644 0001750 0001750 00000000115 12101762535 022237 0 ustar mquinson mquinson Invalid XML (state 13): Required attribute `batt' not set for `bar' element.
flexml-1.9.6/testbed/missing-att.act 0000644 0001750 0001750 00000000761 12101762535 017712 0 ustar mquinson mquinson
]]>
flexml-1.9.6/testbed/mixed-enumatt.stdout.expected 0000644 0001750 0001750 00000000473 12101762535 022607 0 ustar mquinson mquinson reqatt att: (val1)
reqatt pcdata: reqatt data
defatt att: (val1)
defatt pcdata: defatt data
defatt att: (val2)
defatt pcdata: defatt data
optatt att: (val1)
optatt pcdata: optatt data
optatt att: (no att given)
optatt pcdata: optatt data
foo pcdata: foo start data
foo end data.
retval = 0
flexml-1.9.6/flexml-act.dtd 0000644 0001750 0001750 00000002434 12101762535 016060 0 ustar mquinson mquinson
flexml-1.9.6/FleXML.html 0000644 0001750 0001750 00000021117 12101762535 015303 0 ustar mquinson mquinson
FleXML - An XML Processor Generator

Visit our Sponsor
Project Summary
Forums
Tracker
Bugs
Support
Patches
Lists
Tasks
Docs
News
CVS
Files
|
FleXML - XML Processor Generator
See also the manual page
and a short white paper.
Or peek into the
master source archive.
FleXML reads a DTD (Document Type Definition)
describing the format of XML (Extensible Markup Language)
documents; it may be specified as a URI to the DTD on the
web. From this FleXML produces a validating XML
processor with an interface to support XML applications. Proper
applications can be generated optionally from special action
files, either for linking or textual combination with the
processor.
FleXML is specifically developed for XML applications
where a fixed data format suffices in the sense that a single
DTD is used without individual extensions for a large number of
documents. (Specifically it restricts XML rule [28] to
[28r] doctypedecl ::= '<!DOCTYPE ' S Name S ExternalID S? '> '
where the ExternalId denotes the used DTD - one might say, in
fact, that FleXML implements ``non-extensible'' markup. :)
With this restriction we can do much better because the possible
tags and attributes are static: FleXML-generated XML processors
read the XML document character by character and can immediately
dispatch the actions associated with each element (or reject the
document as invalid). Technically this is done by using the
Flex scanner generator to produce a deterministic finite
automaton with an element context stack for the DTD, which means
that there is almost no overhead for XML processing.
Furthermore we have devised a simple extension of the C
programming language that facilitates the writing of `element
actions' in C, making it easy to write really fast XML
applications. In particular we represent XML attribute values
efficiently in C when this is possible, thus avoiding the
otherwise ubiquitous conversions between strings and data
values.
Compared to SAX and its XSL-based friends, FleXML immediately
produces efficient code in that the interdiction of extension
makes it possible to encode efficiently, FleXML for example uses
native C `enum' types to implement enumeration attribute
types. However, the above limitation does prevent uses in more
complex settings.
As an example: the following is all that is needed to produce a
fast program that prints all href-attributes in
<a...> tags in XHTML documents (and rejects
invalid XHTML documents).
<!DOCTYPE actions SYSTEM "flexml-act.dtd">
<actions>
<top><![CDATA[ #include <stdio.h> ]]></top>
<start tag='a'><![CDATA[ if ({href}) printf("%s\n", {href}); ]]></start>
</actions>
In general, action files are themselves XML documents conforming
to the DTD
<!ELEMENT actions ((top|start|end)*,main?)>
<!ENTITY % C-code "(#PCDATA)">
<!ELEMENT top %C-code;>
<!ELEMENT start %C-code;> <!ATTLIST start tag NMTOKEN #REQUIRED>
<!ELEMENT end %C-code;> <!ATTLIST end tag NMTOKEN #REQUIRED>
<!ELEMENT main %C-code;>
with %C-code; segments being in C enriched as
described below. The elements are used as follows:
- top
Use for top-level C code such as global declarations, utility
functions, etc.
- start
-
Attaches the code as an action to the element with the name
of the required ``tag'' attribute. The ``%C-code;''
component should be C code suitable for inclusion in a C
block (i.e., within {...} so it may contain local
variables); furthermore the following extensions are
available: {attribute} Can be used to access the value of
the attribute as set with attribute=value in the start
tag. In C, {attribute} will be interpreted depending on the
declaration of the attribute. If the attribute is declared
as an enumerated type like
<!ATTLIST attrib (alt1 | alt2 |...) ...>
then the C attribute value is of an enumerated type with the
elements written {attrib=alt1} ,
{attrib=alt2} , etc.; furthermore an unset
attribute has the ``value'' {!attrib} . If the
attribute is not an enumeration then {attrib}
is a null-terminated C string (of type char* )
and {!attrib} is NULL .
- end
-
Similarly attaches the code as an action to the end tag with
the name of the required ``tag'' attribute; also here the
``%C-code;'' component should be C code suitable for
inclusion in a C block. In case the element has ``Mixed''
contents, i.e, was declared to permit #PCDATA ,
then the special variable {#PCDATA} contains
the text (#PCDATA ) of the element as a
null-terminated C string (of type char*). In case the Mixed
contents element actually mixed text and child elements then
{#PCDATA} contains the plain concatenation of
the text fragments as one string.
- main
-
Finally, an optional ``main'' element can contain the C main
function of the XML application. Normally the main function
should include (at least) one call of the XML processor
yylex .
The program is freely redistributable and modifiable (under GNU
`copyleft').
Copyright (C)
Kristoffer Rose.
Last modified: Tue Feb 11 18:06:44 EST 2003
|
$Id: FleXML.html,v 1.5 2005/04/06 10:05:15 mquinson Exp $
flexml-1.9.6/ChangeLog 0000644 0001750 0001750 00000003110 12101762535 015071 0 ustar mquinson mquinson 2013-01-29 Martin Quinson
* Don't install any file under examples/flexml/flexml/*
* Release v1.9.6 with these fixes.
2013-01-29 Martin Quinson
* "flexml --version" now reports the package version, not the
file version in CVS. Users often don't care about the
internal rcs numbering schema.
* Update the Copyright notices: we are in 2013 already.
* Release v1.9.5 with these cosmetics.
2012-12-20 Martin Quinson
* New patch from Arnaud Giersch, this time to ensure that
underscores in XML names don't mess the C identifiers.
* Release v1.9.4 with this fix.
2012-07-05 Martin Quinson
* Integrate another patch from Arnaud Giersch that avoids
undefined behaviors breaking clang's optimizations
* Release v1.9.3 with this fix.
2011-11-04 Martin Quinson
* Integrate a patch from Arnaud Giersch to ensure that the
variable defined to check multiply defined attributes are
correctly added to the header. Thanks Arnaud.
* Release v1.9.2 with this fix.
2011-10-28 Martin Quinson
* Ensure that the generated parsers are robust to multiply
defined attributes
2006-09-29 William F. Dowling
* Makefiles use INSTALL and MAKE variables, that play better with
automatic build systems.
2006-09-22 William F. Dowling
* Modified skel by adding '#include ' to fix sourceforge
bug #1563488.
* This change log starts with flexml rev 1.7.
flexml-1.9.6/skel 0000644 0001750 0001750 00000024400 12101762535 014205 0 ustar mquinson mquinson /* Flex(1) XML processor skeleton scanner (in -*-C-*-).
* Copyright (C) 1999 Kristoffer Rose. All rights reserved.
*
* This file is part of the FleXML XML processor generator system.
* Copyright (C) 1999 Kristoffer Rose. All rights reserved.
*
* This program 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 License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* Note: Files generated by the FleXML system have fewer restrictions on them
* as explained in the header of each generated file.
*/
%{
/* Version strings. */
FLEXML_VERSION
/* ANSI headers. */
#include /* for realloc() -- needed here when using flex 2.5.4 */
#include
#include
#include
#include
#include
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__TOS_WIN__)
# ifndef __STRICT_ANSI__
# include
# include
# endif
#else
# include
#endif
#ifndef FLEXML_INDEXSTACKSIZE
#define FLEXML_INDEXSTACKSIZE 1000
#endif
/* Generated definitions. */
FLEXML_DEFINITIONS
/* XML state. */
#ifdef FLEX_DEBUG
# define ENTER(state) debug_enter(state,#state)
# define LEAVE debug_leave()
# define SET(state) debug_set(state,#state)
static void debug_enter(int, const char*);
static void debug_leave(void);
static void debug_set(int, const char*);
#else
# define ENTER(state) (yy_push_state(state))
# define LEAVE (yy_pop_state())
# define SET(state) BEGIN(state)
#endif
/* Generic actions. */
#define SKIP /*skip*/
#define SUCCEED CLEANUP; return 0
#define FAIL return fail
static int fail(const char*, ...);
enum {flexml_max_err_msg_size = 512};
static char flexml_err_msg[flexml_max_err_msg_size];
const char * parse_err_msg()
{
return flexml_err_msg;
}
static void reset_parse_err_msg()
{
flexml_err_msg[0] = '\0';
}
/* Cleanup */
static void cleanup(void);
#define CLEANUP cleanup()
/* Text buffer stack handling. */
char *bufferstack = NULL;
static int blimit = FLEXML_BUFFERSTACKSIZE;
static int bnext = 1;
static int *indexstack = NULL;
static int ilimit = FLEXML_INDEXSTACKSIZE;
static int inext = 1;
#define BUFFERSET(P) (P = bnext)
#define BUFFERPUTC(C) (ck_blimit(), bufferstack[bnext++] = (C))
#define BUFFERDONE (BUFFERPUTC('\0'))
#define BUFFERLITERAL(C, P) bufferliteral(C, &(P), yytext)
/* after this is called, there are at least 2 slots left in the stack */
static int ck_blimit()
{
if (bnext >= blimit) {
blimit += FLEXML_BUFFERSTACKSIZE + 2;
{
char *temp = (char *) realloc(bufferstack, blimit);
assert(temp);
bufferstack = temp;
}
}
return 0;
}
/* after this is called, there are at least 2 slots left in the stack */
static int ck_ilimit()
{
if (inext >= ilimit) {
ilimit += FLEXML_INDEXSTACKSIZE + 2;
{
int *temp = (int *) realloc(indexstack, ilimit);
assert(temp);
indexstack = temp;
}
}
return 0;
}
#ifdef FLEXML_NEED_BUFFERLIT
static void bufferliteral(char c, int* pp, const char* text)
{
BUFFERSET(*pp);
if (c) {
const char *s = strchr(text, c), *e = strrchr(text, c);
assert(s && e && s <= e);
++s;
while (s < e) {
if (isspace(*s)) {
BUFFERPUTC(' ');
do ++s; while (s < e && isspace(*s));
} else
BUFFERPUTC(*s++);
}
} else {
const char *s = text;
while (*s)
BUFFERPUTC(*s++);
}
BUFFERDONE;
}
#endif
static void pushbuffer(int p)
{
ck_ilimit();
indexstack[inext++] = p;
indexstack[inext++] = bnext;
}
static int popbuffer(void)
{
assert(inext >= 2);
bnext = indexstack[--inext];
return indexstack[--inext];
}
/* General internal entities are `unput' back onto the input stream... */
#define ENTITYTEXT(T) \
{ char *s = (T), *e = s+strlen(s);\
while (--e >= s) { unput(*e); }}
FLEXML_INCLUDE_INIT_HEADER
%}
/* Flex standard options. */
%option stack
%option noyy_top_state
%option noinput
%option noreject
%option noyymore
%option noyywrap
/* Flex user-requested options. */
FLEXML_FLEX_OPTIONS
/* XML character classes (currently restricted to ASCII). */
/* "Common syntactic structures." */
S [ \t\n\r\f]+
s [ \t\n\r\f]*
/* "Names and Tokens." */
NameChar [A-Za-z0-9.:_-]
Name [A-Za-z_:]{NameChar}*
Names {Name}({S}{Name})*
Nmtoken ({NameChar})+
Nmtokens {Nmtoken}({S}{Nmtoken})*
/* Miscellaneous. */
VersionNum [a-zA-Z0-9_.:-]+
Eq {s}"="{s}
Literal \'[^'']*\'|\"[^""]*\"
/* Parser states (flex `exclusive start conditions'):
*
* PROLOG the XML prolog of the document before
* DOCTYPE the XML prolog of the document after
* EPILOG after the root element
* INCOMMENT inside an XML comment
* INPI inside an XML PI ...?>
* VALUE1 inside a '...'-delimited literal
* VALUE2 inside a "..."-delimited literal
* CDATA inside a section.
* ROOT_ expect root element
* AL_ inside the attribute list for
* IN_ inside a with element contents (ready for end tag)
* IMPOSSIBLE dummy to permit disabling rules; must be last
*/
%x PROLOG DOCTYPE EPILOG INCOMMENT INPI VALUE1 VALUE2 CDATA
FLEXML_START_CONDITIONS
%x IMPOSSIBLE
FLEXML_EXTRA_DEFINITIONS
%%
/* Bypass Flex's default INITIAL state and begin by parsing the XML prolog. */
SET(PROLOG);
reset_parse_err_msg();
bufferstack = (char *) malloc(FLEXML_BUFFERSTACKSIZE);
assert(bufferstack);
#ifdef FLEX_DEBUG
{
int i;
for (i = 0; i < blimit; i++) {
bufferstack[i] = '\377';
}
}
#endif
bufferstack[0] = '\0';
indexstack = (int *) malloc(FLEXML_INDEXSTACKSIZE * sizeof(int));
assert(indexstack);
indexstack[0] = 0;
FLEXML_EXTRA_DEFINITIONS_INIT
/* COMMENTS and PIs: handled uniformly for efficiency. */
{
"" LEAVE;
"--" |
. |
\n SKIP;
<> FAIL("EOF in comment.");
}
{
"?>" LEAVE;
. |
\n SKIP;
<> FAIL("EOF in PI (processing instruction).");
}
/* SPACES: skipped uniformly */
{S} SKIP;
/* PROLOG: determine root element and process it. */
{
"" SET(DOCTYPE);
"]*">" FAIL("Bad declaration %s.",yytext);
}
{
FLEXML_DOCTYPES
"-][^>]*">" FAIL("Bad declaration %s.",yytext);
. FAIL("Unexpected character `%c' in prolog.", yytext[0]);
<> FAIL("EOF in prolog.");
}
/* RULES DERIVED FROM DTD. */
FLEXML_RULES
/* EPILOG: after the root element. */
{
. {SET(PROLOG); yyless(0); CLEANUP; return -1;}
<> SUCCEED;
}
/* CHARACTER DATA. */
{
FLEXML_ENTITIES
/* Character entities. */
""[[:digit:]]+";" BUFFERPUTC((unsigned char)atoi(yytext+2));
""[[:xdigit:]]+";" BUFFERPUTC((unsigned char)strtol(yytext+3,NULL,16));
}
{
"\n" |
"\r" |
"\r\n" |
"\n\r" BUFFERPUTC('\n');
}
{
"" FAIL("Unexpected `]""]>' in character data.");
}
{
\' BUFFERDONE; LEAVE;
<> FAIL("EOF in literal (\"'\" expected).");
}
{
\" BUFFERDONE; LEAVE;
<> FAIL("EOF in literal (`\"' expected).");
}
{
[^<&] BUFFERPUTC(yytext[0]);
[<&] FAIL("Spurious `%c' in character data.",yytext[0]);
}
{
"]""]>" LEAVE;
/* "]""]" BUFFERPUTC(yytext[0]); BUFFERPUTC(yytext[1]); */
. BUFFERPUTC(yytext[0]);
<> FAIL("EOF in CDATA section.");
}
/* Impossible rules to avoid warnings from flex(1). */
/* Ideally, this should be replaced by code in flexml.pl that
generates just the states not covered by other rules. */
<*>{
.|[\n] FAIL("Syntax error on character `%c'.", yytext[0]);
}
%%
/* Element context stack lookup. */
int element_context(int i)
{
return (0