summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2014-10-13 19:14:30 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2014-10-13 19:14:30 +0000
commiteafd7a3974e8605fd02794269db6114a3446e016 (patch)
tree064737b35dbe10f2995753ead92f95bac30ba048 /examples
downloadragel-tarball-eafd7a3974e8605fd02794269db6114a3446e016.tar.gz
ragel-6.9ragel-6.9
Diffstat (limited to 'examples')
-rw-r--r--examples/Makefile.am91
-rw-r--r--examples/Makefile.in728
-rw-r--r--examples/README40
-rw-r--r--examples/atoi.cpp120
-rw-r--r--examples/atoi.rl59
-rw-r--r--examples/awkemu.c217
-rw-r--r--examples/awkemu.rl116
-rw-r--r--examples/clang.c456
-rw-r--r--examples/clang.rl150
-rw-r--r--examples/concurrent.cpp986
-rw-r--r--examples/concurrent.rl126
-rw-r--r--examples/cppscan.cpp908
-rw-r--r--examples/cppscan.rl208
-rw-r--r--examples/format.c544
-rw-r--r--examples/format.rl191
-rw-r--r--examples/gotocallret.cpp282
-rw-r--r--examples/gotocallret.rl96
-rw-r--r--examples/mailbox.cpp1563
-rw-r--r--examples/mailbox.rl207
-rw-r--r--examples/params.c374
-rw-r--r--examples/params.rl102
-rw-r--r--examples/pullscan.c294
-rw-r--r--examples/pullscan.rl170
-rw-r--r--examples/rlscan.cpp1055
-rw-r--r--examples/rlscan.rl300
-rw-r--r--examples/statechart.cpp187
-rw-r--r--examples/statechart.rl116
27 files changed, 9686 insertions, 0 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am
new file mode 100644
index 0000000..b4c6a94
--- /dev/null
+++ b/examples/Makefile.am
@@ -0,0 +1,91 @@
+#
+# Copyright 2002-2009 Adrian Thurston <thurston@complang.org>
+#
+
+# This file is part of Ragel.
+#
+# Ragel 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.
+#
+# Ragel 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 Ragel; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+RAGEL = ../ragel/ragel
+FLEX = flex
+RE2C = re2c
+
+noinst_PROGRAMS = \
+ atoi awkemu clang concurrent cppscan format gotocallret mailbox params \
+ pullscan rlscan statechart
+
+EXTRA_DIST = \
+ gotocallret.rl pullscan.rl concurrent.rl rlscan.rl statechart.rl \
+ params.rl clang.rl cppscan.rl format.rl awkemu.rl mailbox.rl atoi.rl
+
+gotocallret_SOURCES = gotocallret.cpp
+pullscan_SOURCES = pullscan.c
+concurrent_SOURCES = concurrent.cpp
+rlscan_SOURCES = rlscan.cpp
+statechart_SOURCES = statechart.cpp
+params_SOURCES = params.c
+clang_SOURCES = clang.c
+cppscan_SOURCES = cppscan.cpp
+format_SOURCES = format.c
+awkemu_SOURCES = awkemu.c
+mailbox_SOURCES = mailbox.cpp
+atoi_SOURCES = atoi.cpp
+
+gotocallret.cpp: gotocallret.rl
+ $(RAGEL) -G2 -o gotocallret.cpp gotocallret.rl
+
+pullscan.c: pullscan.rl $(RAGEL)
+ $(RAGEL) -G2 -o $@ pullscan.rl
+
+concurrent.cpp: concurrent.rl $(RAGEL)
+ $(RAGEL) -G2 -o concurrent.cpp concurrent.rl
+
+rlscan.cpp: rlscan.rl
+ $(RAGEL) -G2 -o rlscan.cpp rlscan.rl
+
+statechart.cpp: statechart.rl
+ $(RAGEL) -G2 -o statechart.cpp statechart.rl
+
+params.c: params.rl
+ $(RAGEL) -G2 -o params.c params.rl
+
+clang.c: clang.rl
+ $(RAGEL) -G2 -o clang.c clang.rl
+
+cppscan.cpp: cppscan.rl
+ $(RAGEL) -G2 -o $@ cppscan.rl
+
+format.c: format.rl
+ $(RAGEL) -G2 -o format.c format.rl
+
+awkemu.c: awkemu.rl
+ $(RAGEL) -G2 -o awkemu.c awkemu.rl
+
+mailbox.cpp: mailbox.rl
+ $(RAGEL) -G2 -o mailbox.cpp mailbox.rl
+
+atoi.cpp: atoi.rl
+ $(RAGEL) -G2 -o atoi.cpp atoi.rl
+
+###
+
+lex-cppscan.cpp: cppscan.lex
+ $(FLEX) -f -o $@ $<
+
+re2c-cppscan.cpp: cppscan.rec
+ $(RE2C) -s $< > $@
+
+example.cpp: example.rec
+ $(RE2C) -s $< > $@
diff --git a/examples/Makefile.in b/examples/Makefile.in
new file mode 100644
index 0000000..957d7e7
--- /dev/null
+++ b/examples/Makefile.in
@@ -0,0 +1,728 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright 2002-2009 Adrian Thurston <thurston@complang.org>
+#
+
+# This file is part of Ragel.
+#
+# Ragel 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.
+#
+# Ragel 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 Ragel; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+noinst_PROGRAMS = atoi$(EXEEXT) awkemu$(EXEEXT) clang$(EXEEXT) \
+ concurrent$(EXEEXT) cppscan$(EXEEXT) format$(EXEEXT) \
+ gotocallret$(EXEEXT) mailbox$(EXEEXT) params$(EXEEXT) \
+ pullscan$(EXEEXT) rlscan$(EXEEXT) statechart$(EXEEXT)
+subdir = examples
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp README
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/ragel/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+am_atoi_OBJECTS = atoi.$(OBJEXT)
+atoi_OBJECTS = $(am_atoi_OBJECTS)
+atoi_LDADD = $(LDADD)
+am_awkemu_OBJECTS = awkemu.$(OBJEXT)
+awkemu_OBJECTS = $(am_awkemu_OBJECTS)
+awkemu_LDADD = $(LDADD)
+am_clang_OBJECTS = clang.$(OBJEXT)
+clang_OBJECTS = $(am_clang_OBJECTS)
+clang_LDADD = $(LDADD)
+am_concurrent_OBJECTS = concurrent.$(OBJEXT)
+concurrent_OBJECTS = $(am_concurrent_OBJECTS)
+concurrent_LDADD = $(LDADD)
+am_cppscan_OBJECTS = cppscan.$(OBJEXT)
+cppscan_OBJECTS = $(am_cppscan_OBJECTS)
+cppscan_LDADD = $(LDADD)
+am_format_OBJECTS = format.$(OBJEXT)
+format_OBJECTS = $(am_format_OBJECTS)
+format_LDADD = $(LDADD)
+am_gotocallret_OBJECTS = gotocallret.$(OBJEXT)
+gotocallret_OBJECTS = $(am_gotocallret_OBJECTS)
+gotocallret_LDADD = $(LDADD)
+am_mailbox_OBJECTS = mailbox.$(OBJEXT)
+mailbox_OBJECTS = $(am_mailbox_OBJECTS)
+mailbox_LDADD = $(LDADD)
+am_params_OBJECTS = params.$(OBJEXT)
+params_OBJECTS = $(am_params_OBJECTS)
+params_LDADD = $(LDADD)
+am_pullscan_OBJECTS = pullscan.$(OBJEXT)
+pullscan_OBJECTS = $(am_pullscan_OBJECTS)
+pullscan_LDADD = $(LDADD)
+am_rlscan_OBJECTS = rlscan.$(OBJEXT)
+rlscan_OBJECTS = $(am_rlscan_OBJECTS)
+rlscan_LDADD = $(LDADD)
+am_statechart_OBJECTS = statechart.$(OBJEXT)
+statechart_OBJECTS = $(am_statechart_OBJECTS)
+statechart_LDADD = $(LDADD)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ragel
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
+CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+ -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
+SOURCES = $(atoi_SOURCES) $(awkemu_SOURCES) $(clang_SOURCES) \
+ $(concurrent_SOURCES) $(cppscan_SOURCES) $(format_SOURCES) \
+ $(gotocallret_SOURCES) $(mailbox_SOURCES) $(params_SOURCES) \
+ $(pullscan_SOURCES) $(rlscan_SOURCES) $(statechart_SOURCES)
+DIST_SOURCES = $(atoi_SOURCES) $(awkemu_SOURCES) $(clang_SOURCES) \
+ $(concurrent_SOURCES) $(cppscan_SOURCES) $(format_SOURCES) \
+ $(gotocallret_SOURCES) $(mailbox_SOURCES) $(params_SOURCES) \
+ $(pullscan_SOURCES) $(rlscan_SOURCES) $(statechart_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EXEEXT = @EXEEXT@
+FIG2DEV = @FIG2DEV@
+GDC = @GDC@
+GMCS = @GMCS@
+GOBIN = @GOBIN@
+GOBJC = @GOBJC@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+JAVAC = @JAVAC@
+KELBT = @KELBT@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PDFLATEX = @PDFLATEX@
+PUBDATE = @PUBDATE@
+RAGEL = ../ragel/ragel
+RANLIB = @RANLIB@
+RUBY = @RUBY@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TXL = @TXL@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+FLEX = flex
+RE2C = re2c
+EXTRA_DIST = \
+ gotocallret.rl pullscan.rl concurrent.rl rlscan.rl statechart.rl \
+ params.rl clang.rl cppscan.rl format.rl awkemu.rl mailbox.rl atoi.rl
+
+gotocallret_SOURCES = gotocallret.cpp
+pullscan_SOURCES = pullscan.c
+concurrent_SOURCES = concurrent.cpp
+rlscan_SOURCES = rlscan.cpp
+statechart_SOURCES = statechart.cpp
+params_SOURCES = params.c
+clang_SOURCES = clang.c
+cppscan_SOURCES = cppscan.cpp
+format_SOURCES = format.c
+awkemu_SOURCES = awkemu.c
+mailbox_SOURCES = mailbox.cpp
+atoi_SOURCES = atoi.cpp
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cpp .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign examples/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+atoi$(EXEEXT): $(atoi_OBJECTS) $(atoi_DEPENDENCIES) $(EXTRA_atoi_DEPENDENCIES)
+ @rm -f atoi$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(atoi_OBJECTS) $(atoi_LDADD) $(LIBS)
+
+awkemu$(EXEEXT): $(awkemu_OBJECTS) $(awkemu_DEPENDENCIES) $(EXTRA_awkemu_DEPENDENCIES)
+ @rm -f awkemu$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(awkemu_OBJECTS) $(awkemu_LDADD) $(LIBS)
+
+clang$(EXEEXT): $(clang_OBJECTS) $(clang_DEPENDENCIES) $(EXTRA_clang_DEPENDENCIES)
+ @rm -f clang$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(clang_OBJECTS) $(clang_LDADD) $(LIBS)
+
+concurrent$(EXEEXT): $(concurrent_OBJECTS) $(concurrent_DEPENDENCIES) $(EXTRA_concurrent_DEPENDENCIES)
+ @rm -f concurrent$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(concurrent_OBJECTS) $(concurrent_LDADD) $(LIBS)
+
+cppscan$(EXEEXT): $(cppscan_OBJECTS) $(cppscan_DEPENDENCIES) $(EXTRA_cppscan_DEPENDENCIES)
+ @rm -f cppscan$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(cppscan_OBJECTS) $(cppscan_LDADD) $(LIBS)
+
+format$(EXEEXT): $(format_OBJECTS) $(format_DEPENDENCIES) $(EXTRA_format_DEPENDENCIES)
+ @rm -f format$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(format_OBJECTS) $(format_LDADD) $(LIBS)
+
+gotocallret$(EXEEXT): $(gotocallret_OBJECTS) $(gotocallret_DEPENDENCIES) $(EXTRA_gotocallret_DEPENDENCIES)
+ @rm -f gotocallret$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(gotocallret_OBJECTS) $(gotocallret_LDADD) $(LIBS)
+
+mailbox$(EXEEXT): $(mailbox_OBJECTS) $(mailbox_DEPENDENCIES) $(EXTRA_mailbox_DEPENDENCIES)
+ @rm -f mailbox$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(mailbox_OBJECTS) $(mailbox_LDADD) $(LIBS)
+
+params$(EXEEXT): $(params_OBJECTS) $(params_DEPENDENCIES) $(EXTRA_params_DEPENDENCIES)
+ @rm -f params$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(params_OBJECTS) $(params_LDADD) $(LIBS)
+
+pullscan$(EXEEXT): $(pullscan_OBJECTS) $(pullscan_DEPENDENCIES) $(EXTRA_pullscan_DEPENDENCIES)
+ @rm -f pullscan$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(pullscan_OBJECTS) $(pullscan_LDADD) $(LIBS)
+
+rlscan$(EXEEXT): $(rlscan_OBJECTS) $(rlscan_DEPENDENCIES) $(EXTRA_rlscan_DEPENDENCIES)
+ @rm -f rlscan$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(rlscan_OBJECTS) $(rlscan_LDADD) $(LIBS)
+
+statechart$(EXEEXT): $(statechart_OBJECTS) $(statechart_DEPENDENCIES) $(EXTRA_statechart_DEPENDENCIES)
+ @rm -f statechart$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(statechart_OBJECTS) $(statechart_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atoi.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awkemu.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clang.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/concurrent.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cppscan.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/format.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gotocallret.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mailbox.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/params.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pullscan.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rlscan.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/statechart.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \
+ distclean-compile distclean-generic distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
+ uninstall-am
+
+
+gotocallret.cpp: gotocallret.rl
+ $(RAGEL) -G2 -o gotocallret.cpp gotocallret.rl
+
+pullscan.c: pullscan.rl $(RAGEL)
+ $(RAGEL) -G2 -o $@ pullscan.rl
+
+concurrent.cpp: concurrent.rl $(RAGEL)
+ $(RAGEL) -G2 -o concurrent.cpp concurrent.rl
+
+rlscan.cpp: rlscan.rl
+ $(RAGEL) -G2 -o rlscan.cpp rlscan.rl
+
+statechart.cpp: statechart.rl
+ $(RAGEL) -G2 -o statechart.cpp statechart.rl
+
+params.c: params.rl
+ $(RAGEL) -G2 -o params.c params.rl
+
+clang.c: clang.rl
+ $(RAGEL) -G2 -o clang.c clang.rl
+
+cppscan.cpp: cppscan.rl
+ $(RAGEL) -G2 -o $@ cppscan.rl
+
+format.c: format.rl
+ $(RAGEL) -G2 -o format.c format.rl
+
+awkemu.c: awkemu.rl
+ $(RAGEL) -G2 -o awkemu.c awkemu.rl
+
+mailbox.cpp: mailbox.rl
+ $(RAGEL) -G2 -o mailbox.cpp mailbox.rl
+
+atoi.cpp: atoi.rl
+ $(RAGEL) -G2 -o atoi.cpp atoi.rl
+
+###
+
+lex-cppscan.cpp: cppscan.lex
+ $(FLEX) -f -o $@ $<
+
+re2c-cppscan.cpp: cppscan.rec
+ $(RE2C) -s $< > $@
+
+example.cpp: example.rec
+ $(RE2C) -s $< > $@
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/examples/README b/examples/README
new file mode 100644
index 0000000..12773cb
--- /dev/null
+++ b/examples/README
@@ -0,0 +1,40 @@
+
+ Ragel State Machine Compiler -- Examples
+ ========================================
+
+atoi -- Converts a string to an integer.
+
+awkemu -- Perfoms the basic parsing that the awk program perfoms on input.
+ The awk equivalent to awkemu is in awkemu/awkequiv.awk
+
+clang -- A scanner for a simple C like language. It breaks input up into
+ words, numbers, strings and symbols and strips out whitespace
+ and comments. It is a suitable template for writing a parser
+ that finds a sequence of tokens.
+
+concurrent -- Demonstrates the ability of ragel to produce parsers that
+ perform independent tasks concurrently.
+
+cppscan -- A C++ scanner that uses the longest match scanning method. This
+ example differs from other examples of scanning. Each run of the
+ state machine matches one token. This method results in a
+ smaller state machine since the final kleene star is omitted and
+ therefore every state does not need to get all the transitions
+ of the start state.
+
+format -- Partial printf implementation.
+
+gotocallret -- Demonstrate the use of fgoto, fcall and fret.
+
+mailbox -- Parses unix mailbox files. It breaks files into messages, and
+ messages into headers and body. It demonstrates Ragel's ability
+ to make parsers for structured file formats.
+
+params -- Parses command line arguements.
+
+rlscan -- Lexes Ragel input files.
+
+statechart -- Demonstrate the use of labels, the epsilon operator, and the
+ join operator for creating machines using the named state and
+ transition list paradigm. This implementes the same machine as
+ the atoi example.
diff --git a/examples/atoi.cpp b/examples/atoi.cpp
new file mode 100644
index 0000000..45677f3
--- /dev/null
+++ b/examples/atoi.cpp
@@ -0,0 +1,120 @@
+
+#line 1 "atoi.rl"
+/*
+ * Convert a string to an integer.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+
+#line 13 "atoi.cpp"
+static const int atoi_start = 1;
+static const int atoi_first_final = 4;
+static const int atoi_error = 0;
+
+static const int atoi_en_main = 1;
+
+
+#line 12 "atoi.rl"
+
+
+long long atoi( char *str )
+{
+ char *p = str, *pe = str + strlen( str );
+ int cs;
+ long long val = 0;
+ bool neg = false;
+
+
+#line 32 "atoi.cpp"
+ {
+ cs = atoi_start;
+ }
+
+#line 37 "atoi.cpp"
+ {
+ if ( p == pe )
+ goto _test_eof;
+ switch ( cs )
+ {
+case 1:
+ switch( (*p) ) {
+ case 43: goto st2;
+ case 45: goto tr2;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr3;
+ goto st0;
+st0:
+cs = 0;
+ goto _out;
+tr2:
+#line 22 "atoi.rl"
+ {
+ neg = true;
+ }
+ goto st2;
+st2:
+ if ( ++p == pe )
+ goto _test_eof2;
+case 2:
+#line 64 "atoi.cpp"
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr3;
+ goto st0;
+tr3:
+#line 26 "atoi.rl"
+ {
+ val = val * 10 + ((*p) - '0');
+ }
+ goto st3;
+st3:
+ if ( ++p == pe )
+ goto _test_eof3;
+case 3:
+#line 78 "atoi.cpp"
+ if ( (*p) == 10 )
+ goto st4;
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr3;
+ goto st0;
+st4:
+ if ( ++p == pe )
+ goto _test_eof4;
+case 4:
+ goto st0;
+ }
+ _test_eof2: cs = 2; goto _test_eof;
+ _test_eof3: cs = 3; goto _test_eof;
+ _test_eof4: cs = 4; goto _test_eof;
+
+ _test_eof: {}
+ _out: {}
+ }
+
+#line 37 "atoi.rl"
+
+
+ if ( neg )
+ val = -1 * val;
+
+ if ( cs < atoi_first_final )
+ fprintf( stderr, "atoi: there was an error\n" );
+
+ return val;
+};
+
+
+#define BUFSIZE 1024
+
+int main()
+{
+ char buf[BUFSIZE];
+ while ( fgets( buf, sizeof(buf), stdin ) != 0 ) {
+ long long value = atoi( buf );
+ printf( "%lld\n", value );
+ }
+ return 0;
+}
diff --git a/examples/atoi.rl b/examples/atoi.rl
new file mode 100644
index 0000000..7164b68
--- /dev/null
+++ b/examples/atoi.rl
@@ -0,0 +1,59 @@
+/*
+ * Convert a string to an integer.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+%%{
+ machine atoi;
+ write data;
+}%%
+
+long long atoi( char *str )
+{
+ char *p = str, *pe = str + strlen( str );
+ int cs;
+ long long val = 0;
+ bool neg = false;
+
+ %%{
+ action see_neg {
+ neg = true;
+ }
+
+ action add_digit {
+ val = val * 10 + (fc - '0');
+ }
+
+ main :=
+ ( '-'@see_neg | '+' )? ( digit @add_digit )+
+ '\n';
+
+ # Initialize and execute.
+ write init;
+ write exec;
+ }%%
+
+ if ( neg )
+ val = -1 * val;
+
+ if ( cs < atoi_first_final )
+ fprintf( stderr, "atoi: there was an error\n" );
+
+ return val;
+};
+
+
+#define BUFSIZE 1024
+
+int main()
+{
+ char buf[BUFSIZE];
+ while ( fgets( buf, sizeof(buf), stdin ) != 0 ) {
+ long long value = atoi( buf );
+ printf( "%lld\n", value );
+ }
+ return 0;
+}
diff --git a/examples/awkemu.c b/examples/awkemu.c
new file mode 100644
index 0000000..2fdcb01
--- /dev/null
+++ b/examples/awkemu.c
@@ -0,0 +1,217 @@
+
+#line 1 "awkemu.rl"
+/*
+ * Perform the basic line parsing of input performed by awk.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+#line 55 "awkemu.rl"
+
+
+
+#line 18 "awkemu.c"
+static const int awkemu_start = 2;
+
+static const int awkemu_en_main = 2;
+
+
+#line 58 "awkemu.rl"
+
+#define MAXWORDS 256
+#define BUFSIZE 4096
+char buf[BUFSIZE];
+
+int main()
+{
+ int i, nwords = 0;
+ char *ls = 0;
+ char *ws[MAXWORDS];
+ char *we[MAXWORDS];
+
+ int cs;
+ int have = 0;
+
+
+#line 41 "awkemu.c"
+ {
+ cs = awkemu_start;
+ }
+
+#line 74 "awkemu.rl"
+
+ while ( 1 ) {
+ char *p, *pe, *data = buf + have;
+ int len, space = BUFSIZE - have;
+ /* fprintf( stderr, "space: %i\n", space ); */
+
+ if ( space == 0 ) {
+ fprintf(stderr, "buffer out of space\n");
+ exit(1);
+ }
+
+ len = fread( data, 1, space, stdin );
+ /* fprintf( stderr, "len: %i\n", len ); */
+ if ( len == 0 )
+ break;
+
+ /* Find the last newline by searching backwards. This is where
+ * we will stop processing on this iteration. */
+ p = buf;
+ pe = buf + have + len - 1;
+ while ( *pe != '\n' && pe >= buf )
+ pe--;
+ pe += 1;
+
+ /* fprintf( stderr, "running on: %i\n", pe - p ); */
+
+
+#line 74 "awkemu.c"
+ {
+ if ( p == pe )
+ goto _test_eof;
+ switch ( cs )
+ {
+tr2:
+#line 17 "awkemu.rl"
+ {
+ we[nwords++] = p;
+ }
+#line 26 "awkemu.rl"
+ {
+ printf("endline(%i): ", nwords );
+ fwrite( ls, 1, p - ls, stdout );
+ printf("\n");
+
+ for ( i = 0; i < nwords; i++ ) {
+ printf(" word: ");
+ fwrite( ws[i], 1, we[i] - ws[i], stdout );
+ printf("\n");
+ }
+ }
+ goto st2;
+tr5:
+#line 26 "awkemu.rl"
+ {
+ printf("endline(%i): ", nwords );
+ fwrite( ls, 1, p - ls, stdout );
+ printf("\n");
+
+ for ( i = 0; i < nwords; i++ ) {
+ printf(" word: ");
+ fwrite( ws[i], 1, we[i] - ws[i], stdout );
+ printf("\n");
+ }
+ }
+ goto st2;
+tr8:
+#line 21 "awkemu.rl"
+ {
+ nwords = 0;
+ ls = p;
+ }
+#line 26 "awkemu.rl"
+ {
+ printf("endline(%i): ", nwords );
+ fwrite( ls, 1, p - ls, stdout );
+ printf("\n");
+
+ for ( i = 0; i < nwords; i++ ) {
+ printf(" word: ");
+ fwrite( ws[i], 1, we[i] - ws[i], stdout );
+ printf("\n");
+ }
+ }
+ goto st2;
+st2:
+ if ( ++p == pe )
+ goto _test_eof2;
+case 2:
+#line 135 "awkemu.c"
+ switch( (*p) ) {
+ case 9: goto tr7;
+ case 10: goto tr8;
+ case 32: goto tr7;
+ }
+ goto tr6;
+tr3:
+#line 13 "awkemu.rl"
+ {
+ ws[nwords] = p;
+ }
+ goto st0;
+tr6:
+#line 21 "awkemu.rl"
+ {
+ nwords = 0;
+ ls = p;
+ }
+#line 13 "awkemu.rl"
+ {
+ ws[nwords] = p;
+ }
+ goto st0;
+st0:
+ if ( ++p == pe )
+ goto _test_eof0;
+case 0:
+#line 163 "awkemu.c"
+ switch( (*p) ) {
+ case 9: goto tr1;
+ case 10: goto tr2;
+ case 32: goto tr1;
+ }
+ goto st0;
+tr1:
+#line 17 "awkemu.rl"
+ {
+ we[nwords++] = p;
+ }
+ goto st1;
+tr7:
+#line 21 "awkemu.rl"
+ {
+ nwords = 0;
+ ls = p;
+ }
+ goto st1;
+st1:
+ if ( ++p == pe )
+ goto _test_eof1;
+case 1:
+#line 187 "awkemu.c"
+ switch( (*p) ) {
+ case 9: goto st1;
+ case 10: goto tr5;
+ case 32: goto st1;
+ }
+ goto tr3;
+ }
+ _test_eof2: cs = 2; goto _test_eof;
+ _test_eof0: cs = 0; goto _test_eof;
+ _test_eof1: cs = 1; goto _test_eof;
+
+ _test_eof: {}
+ }
+
+#line 101 "awkemu.rl"
+
+ /* How much is still in the buffer. */
+ have = data + len - pe;
+ if ( have > 0 )
+ memmove( buf, pe, have );
+
+ /* fprintf(stderr, "have: %i\n", have ); */
+
+ if ( len < space )
+ break;
+ }
+
+ if ( have > 0 )
+ fprintf(stderr, "input not newline terminated\n");
+ return 0;
+}
diff --git a/examples/awkemu.rl b/examples/awkemu.rl
new file mode 100644
index 0000000..6615943
--- /dev/null
+++ b/examples/awkemu.rl
@@ -0,0 +1,116 @@
+/*
+ * Perform the basic line parsing of input performed by awk.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+%%{
+ machine awkemu;
+
+ action start_word {
+ ws[nwords] = fpc;
+ }
+
+ action end_word {
+ we[nwords++] = fpc;
+ }
+
+ action start_line {
+ nwords = 0;
+ ls = fpc;
+ }
+
+ action end_line {
+ printf("endline(%i): ", nwords );
+ fwrite( ls, 1, p - ls, stdout );
+ printf("\n");
+
+ for ( i = 0; i < nwords; i++ ) {
+ printf(" word: ");
+ fwrite( ws[i], 1, we[i] - ws[i], stdout );
+ printf("\n");
+ }
+ }
+
+ # Words in a line.
+ word = ^[ \t\n]+;
+
+ # The whitespace separating words in a line.
+ whitespace = [ \t];
+
+ # The components in a line to break up. Either a word or a single char of
+ # whitespace. On the word capture characters.
+ blineElements = word >start_word %end_word | whitespace;
+
+ # Star the break line elements. Just be careful to decrement the leaving
+ # priority as we don't want multiple character identifiers to be treated as
+ # multiple single char identifiers.
+ line = ( blineElements** '\n' ) >start_line @end_line;
+
+ # Any number of lines.
+ main := line*;
+}%%
+
+%% write data noerror nofinal;
+
+#define MAXWORDS 256
+#define BUFSIZE 4096
+char buf[BUFSIZE];
+
+int main()
+{
+ int i, nwords = 0;
+ char *ls = 0;
+ char *ws[MAXWORDS];
+ char *we[MAXWORDS];
+
+ int cs;
+ int have = 0;
+
+ %% write init;
+
+ while ( 1 ) {
+ char *p, *pe, *data = buf + have;
+ int len, space = BUFSIZE - have;
+ /* fprintf( stderr, "space: %i\n", space ); */
+
+ if ( space == 0 ) {
+ fprintf(stderr, "buffer out of space\n");
+ exit(1);
+ }
+
+ len = fread( data, 1, space, stdin );
+ /* fprintf( stderr, "len: %i\n", len ); */
+ if ( len == 0 )
+ break;
+
+ /* Find the last newline by searching backwards. This is where
+ * we will stop processing on this iteration. */
+ p = buf;
+ pe = buf + have + len - 1;
+ while ( *pe != '\n' && pe >= buf )
+ pe--;
+ pe += 1;
+
+ /* fprintf( stderr, "running on: %i\n", pe - p ); */
+
+ %% write exec;
+
+ /* How much is still in the buffer. */
+ have = data + len - pe;
+ if ( have > 0 )
+ memmove( buf, pe, have );
+
+ /* fprintf(stderr, "have: %i\n", have ); */
+
+ if ( len < space )
+ break;
+ }
+
+ if ( have > 0 )
+ fprintf(stderr, "input not newline terminated\n");
+ return 0;
+}
diff --git a/examples/clang.c b/examples/clang.c
new file mode 100644
index 0000000..c8fb683
--- /dev/null
+++ b/examples/clang.c
@@ -0,0 +1,456 @@
+
+#line 1 "clang.rl"
+/*
+ * A mini C-like language scanner.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+#line 91 "clang.rl"
+
+
+
+#line 17 "clang.c"
+static const int clang_start = 10;
+static const int clang_error = 0;
+
+static const int clang_en_c_comment = 8;
+static const int clang_en_main = 10;
+
+
+#line 94 "clang.rl"
+
+#define BUFSIZE 128
+
+void scanner()
+{
+ static char buf[BUFSIZE];
+ int cs, act, have = 0, curline = 1;
+ char *ts, *te = 0;
+ int done = 0;
+
+
+#line 37 "clang.c"
+ {
+ cs = clang_start;
+ ts = 0;
+ te = 0;
+ act = 0;
+ }
+
+#line 105 "clang.rl"
+
+ while ( !done ) {
+ char *p = buf + have, *pe, *eof = 0;
+ int len, space = BUFSIZE - have;
+
+ if ( space == 0 ) {
+ /* We've used up the entire buffer storing an already-parsed token
+ * prefix that must be preserved. */
+ fprintf(stderr, "OUT OF BUFFER SPACE\n" );
+ exit(1);
+ }
+
+ len = fread( p, 1, space, stdin );
+ pe = p + len;
+
+ /* Check if this is the end of file. */
+ if ( len < space ) {
+ eof = pe;
+ done = 1;
+ }
+
+
+#line 68 "clang.c"
+ {
+ if ( p == pe )
+ goto _test_eof;
+ switch ( cs )
+ {
+tr2:
+#line 50 "clang.rl"
+ {te = p+1;{
+ printf( "double_lit(%i): ", curline );
+ fwrite( ts, 1, te-ts, stdout );
+ printf("\n");
+ }}
+ goto st10;
+tr6:
+#line 42 "clang.rl"
+ {te = p+1;{
+ printf( "single_lit(%i): ", curline );
+ fwrite( ts, 1, te-ts, stdout );
+ printf("\n");
+ }}
+ goto st10;
+tr8:
+#line 28 "clang.rl"
+ {{p = ((te))-1;}{
+ printf( "symbol(%i): %c\n", curline, ts[0] );
+ }}
+ goto st10;
+tr10:
+#line 12 "clang.rl"
+ {curline += 1;}
+#line 62 "clang.rl"
+ {te = p+1;}
+ goto st10;
+tr11:
+#line 68 "clang.rl"
+ {{p = ((te))-1;}{
+ printf( "int(%i): ", curline );
+ fwrite( ts, 1, te-ts, stdout );
+ printf("\n");
+ }}
+ goto st10;
+tr18:
+#line 57 "clang.rl"
+ {te = p+1;}
+ goto st10;
+tr19:
+#line 12 "clang.rl"
+ {curline += 1;}
+#line 57 "clang.rl"
+ {te = p+1;}
+ goto st10;
+tr20:
+#line 28 "clang.rl"
+ {te = p+1;{
+ printf( "symbol(%i): %c\n", curline, ts[0] );
+ }}
+ goto st10;
+tr25:
+#line 28 "clang.rl"
+ {te = p;p--;{
+ printf( "symbol(%i): %c\n", curline, ts[0] );
+ }}
+ goto st10;
+tr26:
+#line 64 "clang.rl"
+ {te = p+1;{ {goto st8;} }}
+ goto st10;
+tr27:
+#line 68 "clang.rl"
+ {te = p;p--;{
+ printf( "int(%i): ", curline );
+ fwrite( ts, 1, te-ts, stdout );
+ printf("\n");
+ }}
+ goto st10;
+tr30:
+#line 76 "clang.rl"
+ {te = p;p--;{
+ printf( "float(%i): ", curline );
+ fwrite( ts, 1, te-ts, stdout );
+ printf("\n");
+ }}
+ goto st10;
+tr31:
+#line 84 "clang.rl"
+ {te = p;p--;{
+ printf( "hex(%i): ", curline );
+ fwrite( ts, 1, te-ts, stdout );
+ printf("\n");
+ }}
+ goto st10;
+tr32:
+#line 34 "clang.rl"
+ {te = p;p--;{
+ printf( "ident(%i): ", curline );
+ fwrite( ts, 1, te-ts, stdout );
+ printf("\n");
+ }}
+ goto st10;
+st10:
+#line 1 "NONE"
+ {ts = 0;}
+ if ( ++p == pe )
+ goto _test_eof10;
+case 10:
+#line 1 "NONE"
+ {ts = p;}
+#line 176 "clang.c"
+ switch( (*p) ) {
+ case 10: goto tr19;
+ case 34: goto st1;
+ case 39: goto st3;
+ case 47: goto tr21;
+ case 48: goto tr22;
+ case 95: goto st16;
+ }
+ if ( (*p) < 65 ) {
+ if ( (*p) < 49 ) {
+ if ( 33 <= (*p) && (*p) <= 46 )
+ goto tr20;
+ } else if ( (*p) > 57 ) {
+ if ( 58 <= (*p) && (*p) <= 64 )
+ goto tr20;
+ } else
+ goto tr23;
+ } else if ( (*p) > 90 ) {
+ if ( (*p) < 97 ) {
+ if ( 91 <= (*p) && (*p) <= 96 )
+ goto tr20;
+ } else if ( (*p) > 122 ) {
+ if ( 123 <= (*p) && (*p) <= 126 )
+ goto tr20;
+ } else
+ goto st16;
+ } else
+ goto st16;
+ goto tr18;
+tr1:
+#line 12 "clang.rl"
+ {curline += 1;}
+ goto st1;
+st1:
+ if ( ++p == pe )
+ goto _test_eof1;
+case 1:
+#line 214 "clang.c"
+ switch( (*p) ) {
+ case 10: goto tr1;
+ case 34: goto tr2;
+ case 92: goto st2;
+ }
+ goto st1;
+st2:
+ if ( ++p == pe )
+ goto _test_eof2;
+case 2:
+ if ( (*p) == 10 )
+ goto tr1;
+ goto st1;
+tr5:
+#line 12 "clang.rl"
+ {curline += 1;}
+ goto st3;
+st3:
+ if ( ++p == pe )
+ goto _test_eof3;
+case 3:
+#line 236 "clang.c"
+ switch( (*p) ) {
+ case 10: goto tr5;
+ case 39: goto tr6;
+ case 92: goto st4;
+ }
+ goto st3;
+st4:
+ if ( ++p == pe )
+ goto _test_eof4;
+case 4:
+ if ( (*p) == 10 )
+ goto tr5;
+ goto st3;
+tr21:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st11;
+st11:
+ if ( ++p == pe )
+ goto _test_eof11;
+case 11:
+#line 258 "clang.c"
+ switch( (*p) ) {
+ case 42: goto tr26;
+ case 47: goto st5;
+ }
+ goto tr25;
+st5:
+ if ( ++p == pe )
+ goto _test_eof5;
+case 5:
+ if ( (*p) == 10 )
+ goto tr10;
+ goto st5;
+tr22:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st12;
+st12:
+ if ( ++p == pe )
+ goto _test_eof12;
+case 12:
+#line 279 "clang.c"
+ switch( (*p) ) {
+ case 46: goto st6;
+ case 120: goto st7;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr23;
+ goto tr27;
+st6:
+ if ( ++p == pe )
+ goto _test_eof6;
+case 6:
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st13;
+ goto tr11;
+st13:
+ if ( ++p == pe )
+ goto _test_eof13;
+case 13:
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st13;
+ goto tr30;
+tr23:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st14;
+st14:
+ if ( ++p == pe )
+ goto _test_eof14;
+case 14:
+#line 309 "clang.c"
+ if ( (*p) == 46 )
+ goto st6;
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr23;
+ goto tr27;
+st7:
+ if ( ++p == pe )
+ goto _test_eof7;
+case 7:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st15;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st15;
+ } else
+ goto st15;
+ goto tr11;
+st15:
+ if ( ++p == pe )
+ goto _test_eof15;
+case 15:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st15;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st15;
+ } else
+ goto st15;
+ goto tr31;
+st16:
+ if ( ++p == pe )
+ goto _test_eof16;
+case 16:
+ if ( (*p) == 95 )
+ goto st16;
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st16;
+ } else if ( (*p) > 90 ) {
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st16;
+ } else
+ goto st16;
+ goto tr32;
+tr15:
+#line 12 "clang.rl"
+ {curline += 1;}
+ goto st8;
+st8:
+#line 1 "NONE"
+ {ts = 0;}
+ if ( ++p == pe )
+ goto _test_eof8;
+case 8:
+#line 366 "clang.c"
+ switch( (*p) ) {
+ case 10: goto tr15;
+ case 42: goto st9;
+ }
+ goto st8;
+st9:
+ if ( ++p == pe )
+ goto _test_eof9;
+case 9:
+ switch( (*p) ) {
+ case 10: goto tr15;
+ case 42: goto st9;
+ case 47: goto tr17;
+ }
+ goto st8;
+tr17:
+#line 16 "clang.rl"
+ {{goto st10;}}
+ goto st17;
+st17:
+ if ( ++p == pe )
+ goto _test_eof17;
+case 17:
+#line 390 "clang.c"
+ goto st0;
+st0:
+cs = 0;
+ goto _out;
+ }
+ _test_eof10: cs = 10; goto _test_eof;
+ _test_eof1: cs = 1; goto _test_eof;
+ _test_eof2: cs = 2; goto _test_eof;
+ _test_eof3: cs = 3; goto _test_eof;
+ _test_eof4: cs = 4; goto _test_eof;
+ _test_eof11: cs = 11; goto _test_eof;
+ _test_eof5: cs = 5; goto _test_eof;
+ _test_eof12: cs = 12; goto _test_eof;
+ _test_eof6: cs = 6; goto _test_eof;
+ _test_eof13: cs = 13; goto _test_eof;
+ _test_eof14: cs = 14; goto _test_eof;
+ _test_eof7: cs = 7; goto _test_eof;
+ _test_eof15: cs = 15; goto _test_eof;
+ _test_eof16: cs = 16; goto _test_eof;
+ _test_eof8: cs = 8; goto _test_eof;
+ _test_eof9: cs = 9; goto _test_eof;
+ _test_eof17: cs = 17; goto _test_eof;
+
+ _test_eof: {}
+ if ( p == eof )
+ {
+ switch ( cs ) {
+ case 11: goto tr25;
+ case 5: goto tr8;
+ case 12: goto tr27;
+ case 6: goto tr11;
+ case 13: goto tr30;
+ case 14: goto tr27;
+ case 7: goto tr11;
+ case 15: goto tr31;
+ case 16: goto tr32;
+ }
+ }
+
+ _out: {}
+ }
+
+#line 127 "clang.rl"
+
+ if ( cs == clang_error ) {
+ fprintf(stderr, "PARSE ERROR\n" );
+ break;
+ }
+
+ if ( ts == 0 )
+ have = 0;
+ else {
+ /* There is a prefix to preserve, shift it over. */
+ have = pe - ts;
+ memmove( buf, ts, have );
+ te = buf + (te-ts);
+ ts = buf;
+ }
+ }
+}
+
+int main()
+{
+ scanner();
+ return 0;
+}
+
diff --git a/examples/clang.rl b/examples/clang.rl
new file mode 100644
index 0000000..60491e5
--- /dev/null
+++ b/examples/clang.rl
@@ -0,0 +1,150 @@
+/*
+ * A mini C-like language scanner.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+%%{
+ machine clang;
+
+ newline = '\n' @{curline += 1;};
+ any_count_line = any | newline;
+
+ # Consume a C comment.
+ c_comment := any_count_line* :>> '*/' @{fgoto main;};
+
+ main := |*
+
+ # Alpha numberic characters or underscore.
+ alnum_u = alnum | '_';
+
+ # Alpha charactres or underscore.
+ alpha_u = alpha | '_';
+
+ # Symbols. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving dump the symbol.
+ ( punct - [_'"] ) {
+ printf( "symbol(%i): %c\n", curline, ts[0] );
+ };
+
+ # Identifier. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving, dump the identifier.
+ alpha_u alnum_u* {
+ printf( "ident(%i): ", curline );
+ fwrite( ts, 1, te-ts, stdout );
+ printf("\n");
+ };
+
+ # Single Quote.
+ sliteralChar = [^'\\] | newline | ( '\\' . any_count_line );
+ '\'' . sliteralChar* . '\'' {
+ printf( "single_lit(%i): ", curline );
+ fwrite( ts, 1, te-ts, stdout );
+ printf("\n");
+ };
+
+ # Double Quote.
+ dliteralChar = [^"\\] | newline | ( '\\' any_count_line );
+ '"' . dliteralChar* . '"' {
+ printf( "double_lit(%i): ", curline );
+ fwrite( ts, 1, te-ts, stdout );
+ printf("\n");
+ };
+
+ # Whitespace is standard ws, newlines and control codes.
+ any_count_line - 0x21..0x7e;
+
+ # Describe both c style comments and c++ style comments. The
+ # priority bump on tne terminator of the comments brings us
+ # out of the extend* which matches everything.
+ '//' [^\n]* newline;
+
+ '/*' { fgoto c_comment; };
+
+ # Match an integer. We don't bother clearing the buf or filling it.
+ # The float machine overlaps with int and it will do it.
+ digit+ {
+ printf( "int(%i): ", curline );
+ fwrite( ts, 1, te-ts, stdout );
+ printf("\n");
+ };
+
+ # Match a float. Upon entering the machine clear the buf, buffer
+ # characters on every trans and dump the float upon leaving.
+ digit+ '.' digit+ {
+ printf( "float(%i): ", curline );
+ fwrite( ts, 1, te-ts, stdout );
+ printf("\n");
+ };
+
+ # Match a hex. Upon entering the hex part, clear the buf, buffer characters
+ # on every trans and dump the hex on leaving transitions.
+ '0x' xdigit+ {
+ printf( "hex(%i): ", curline );
+ fwrite( ts, 1, te-ts, stdout );
+ printf("\n");
+ };
+
+ *|;
+}%%
+
+%% write data nofinal;
+
+#define BUFSIZE 128
+
+void scanner()
+{
+ static char buf[BUFSIZE];
+ int cs, act, have = 0, curline = 1;
+ char *ts, *te = 0;
+ int done = 0;
+
+ %% write init;
+
+ while ( !done ) {
+ char *p = buf + have, *pe, *eof = 0;
+ int len, space = BUFSIZE - have;
+
+ if ( space == 0 ) {
+ /* We've used up the entire buffer storing an already-parsed token
+ * prefix that must be preserved. */
+ fprintf(stderr, "OUT OF BUFFER SPACE\n" );
+ exit(1);
+ }
+
+ len = fread( p, 1, space, stdin );
+ pe = p + len;
+
+ /* Check if this is the end of file. */
+ if ( len < space ) {
+ eof = pe;
+ done = 1;
+ }
+
+ %% write exec;
+
+ if ( cs == clang_error ) {
+ fprintf(stderr, "PARSE ERROR\n" );
+ break;
+ }
+
+ if ( ts == 0 )
+ have = 0;
+ else {
+ /* There is a prefix to preserve, shift it over. */
+ have = pe - ts;
+ memmove( buf, ts, have );
+ te = buf + (te-ts);
+ ts = buf;
+ }
+ }
+}
+
+int main()
+{
+ scanner();
+ return 0;
+}
+
diff --git a/examples/concurrent.cpp b/examples/concurrent.cpp
new file mode 100644
index 0000000..c2278cb
--- /dev/null
+++ b/examples/concurrent.cpp
@@ -0,0 +1,986 @@
+
+#line 1 "concurrent.rl"
+/*
+ * Show off concurrent abilities.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+
+using namespace std;
+
+#define BUFSIZE 2048
+
+struct Concurrent
+{
+ int cur_char;
+ int start_word;
+ int start_comment;
+ int start_literal;
+
+ int cs;
+
+ int init( );
+ int execute( const char *data, int len, bool isEof );
+ int finish( );
+};
+
+
+#line 75 "concurrent.rl"
+
+
+
+#line 35 "concurrent.cpp"
+static const int Concurrent_start = 0;
+static const int Concurrent_first_final = 0;
+static const int Concurrent_error = -1;
+
+static const int Concurrent_en_main = 0;
+
+
+#line 78 "concurrent.rl"
+
+int Concurrent::init( )
+{
+
+#line 48 "concurrent.cpp"
+ {
+ cs = Concurrent_start;
+ }
+
+#line 82 "concurrent.rl"
+ cur_char = 0;
+ return 1;
+}
+
+int Concurrent::execute( const char *data, int len, bool isEof )
+{
+ const char *p = data;
+ const char *pe = data + len;
+ const char *eof = isEof ? pe : 0;
+
+
+#line 65 "concurrent.cpp"
+ {
+ if ( p == pe )
+ goto _test_eof;
+ switch ( cs )
+ {
+tr1:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st0;
+tr5:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 37 "concurrent.rl"
+ {
+ cout << "word: " << start_word <<
+ " " << cur_char-1 << endl;
+ }
+ goto st0;
+tr19:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 37 "concurrent.rl"
+ {
+ cout << "word: " << start_word <<
+ " " << cur_char-1 << endl;
+ }
+#line 53 "concurrent.rl"
+ {
+ cout << "literal: " << start_literal <<
+ " " << cur_char-1 << endl;
+ }
+ goto st0;
+tr46:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 37 "concurrent.rl"
+ {
+ cout << "word: " << start_word <<
+ " " << cur_char-1 << endl;
+ }
+#line 45 "concurrent.rl"
+ {
+ cout << "comment: " << start_comment <<
+ " " << cur_char-1 << endl;
+ }
+ goto st0;
+st0:
+ if ( ++p == pe )
+ goto _test_eof0;
+case 0:
+#line 124 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr1;
+ case 39: goto tr2;
+ case 47: goto tr3;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr1;
+ goto tr0;
+tr0:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 34 "concurrent.rl"
+ {
+ start_word = cur_char;
+ }
+ goto st1;
+tr4:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st1;
+tr18:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 53 "concurrent.rl"
+ {
+ cout << "literal: " << start_literal <<
+ " " << cur_char-1 << endl;
+ }
+ goto st1;
+tr45:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 45 "concurrent.rl"
+ {
+ cout << "comment: " << start_comment <<
+ " " << cur_char-1 << endl;
+ }
+ goto st1;
+st1:
+ if ( ++p == pe )
+ goto _test_eof1;
+case 1:
+#line 175 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr5;
+ case 39: goto tr6;
+ case 47: goto tr7;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr5;
+ goto tr4;
+tr13:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 34 "concurrent.rl"
+ {
+ start_word = cur_char;
+ }
+ goto st2;
+tr8:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st2;
+tr2:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 34 "concurrent.rl"
+ {
+ start_word = cur_char;
+ }
+#line 50 "concurrent.rl"
+ {
+ start_literal = cur_char;
+ }
+ goto st2;
+tr6:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 50 "concurrent.rl"
+ {
+ start_literal = cur_char;
+ }
+ goto st2;
+tr20:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 53 "concurrent.rl"
+ {
+ cout << "literal: " << start_literal <<
+ " " << cur_char-1 << endl;
+ }
+#line 50 "concurrent.rl"
+ {
+ start_literal = cur_char;
+ }
+ goto st2;
+tr50:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 45 "concurrent.rl"
+ {
+ cout << "comment: " << start_comment <<
+ " " << cur_char-1 << endl;
+ }
+ goto st2;
+tr47:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 45 "concurrent.rl"
+ {
+ cout << "comment: " << start_comment <<
+ " " << cur_char-1 << endl;
+ }
+#line 50 "concurrent.rl"
+ {
+ start_literal = cur_char;
+ }
+ goto st2;
+st2:
+ if ( ++p == pe )
+ goto _test_eof2;
+case 2:
+#line 269 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr9;
+ case 39: goto tr10;
+ case 47: goto tr11;
+ case 92: goto tr12;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr9;
+ goto tr8;
+tr14:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st3;
+tr9:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 37 "concurrent.rl"
+ {
+ cout << "word: " << start_word <<
+ " " << cur_char-1 << endl;
+ }
+ goto st3;
+tr51:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 37 "concurrent.rl"
+ {
+ cout << "word: " << start_word <<
+ " " << cur_char-1 << endl;
+ }
+#line 45 "concurrent.rl"
+ {
+ cout << "comment: " << start_comment <<
+ " " << cur_char-1 << endl;
+ }
+ goto st3;
+st3:
+ if ( ++p == pe )
+ goto _test_eof3;
+case 3:
+#line 316 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr14;
+ case 39: goto tr15;
+ case 47: goto tr16;
+ case 92: goto tr17;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr14;
+ goto tr13;
+tr15:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 34 "concurrent.rl"
+ {
+ start_word = cur_char;
+ }
+ goto st4;
+tr10:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st4;
+tr52:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 45 "concurrent.rl"
+ {
+ cout << "comment: " << start_comment <<
+ " " << cur_char-1 << endl;
+ }
+ goto st4;
+st4:
+ if ( ++p == pe )
+ goto _test_eof4;
+case 4:
+#line 357 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr19;
+ case 39: goto tr20;
+ case 47: goto tr21;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr19;
+ goto tr18;
+tr3:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 34 "concurrent.rl"
+ {
+ start_word = cur_char;
+ }
+#line 42 "concurrent.rl"
+ {
+ start_comment = cur_char;
+ }
+ goto st5;
+tr7:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 42 "concurrent.rl"
+ {
+ start_comment = cur_char;
+ }
+ goto st5;
+tr21:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 42 "concurrent.rl"
+ {
+ start_comment = cur_char;
+ }
+#line 53 "concurrent.rl"
+ {
+ cout << "literal: " << start_literal <<
+ " " << cur_char-1 << endl;
+ }
+ goto st5;
+tr48:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 45 "concurrent.rl"
+ {
+ cout << "comment: " << start_comment <<
+ " " << cur_char-1 << endl;
+ }
+#line 42 "concurrent.rl"
+ {
+ start_comment = cur_char;
+ }
+ goto st5;
+st5:
+ if ( ++p == pe )
+ goto _test_eof5;
+case 5:
+#line 424 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr5;
+ case 39: goto tr6;
+ case 42: goto tr22;
+ case 47: goto tr7;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr5;
+ goto tr4;
+tr26:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 34 "concurrent.rl"
+ {
+ start_word = cur_char;
+ }
+ goto st6;
+tr22:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st6;
+tr40:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 53 "concurrent.rl"
+ {
+ cout << "literal: " << start_literal <<
+ " " << cur_char-1 << endl;
+ }
+ goto st6;
+st6:
+ if ( ++p == pe )
+ goto _test_eof6;
+case 6:
+#line 465 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr23;
+ case 39: goto tr24;
+ case 42: goto tr25;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr23;
+ goto tr22;
+tr27:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st7;
+tr23:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 37 "concurrent.rl"
+ {
+ cout << "word: " << start_word <<
+ " " << cur_char-1 << endl;
+ }
+ goto st7;
+tr41:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 37 "concurrent.rl"
+ {
+ cout << "word: " << start_word <<
+ " " << cur_char-1 << endl;
+ }
+#line 53 "concurrent.rl"
+ {
+ cout << "literal: " << start_literal <<
+ " " << cur_char-1 << endl;
+ }
+ goto st7;
+st7:
+ if ( ++p == pe )
+ goto _test_eof7;
+case 7:
+#line 511 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr27;
+ case 39: goto tr28;
+ case 42: goto tr29;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr27;
+ goto tr26;
+tr35:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 34 "concurrent.rl"
+ {
+ start_word = cur_char;
+ }
+ goto st8;
+tr30:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st8;
+tr28:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 34 "concurrent.rl"
+ {
+ start_word = cur_char;
+ }
+#line 50 "concurrent.rl"
+ {
+ start_literal = cur_char;
+ }
+ goto st8;
+tr24:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 50 "concurrent.rl"
+ {
+ start_literal = cur_char;
+ }
+ goto st8;
+tr42:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 53 "concurrent.rl"
+ {
+ cout << "literal: " << start_literal <<
+ " " << cur_char-1 << endl;
+ }
+#line 50 "concurrent.rl"
+ {
+ start_literal = cur_char;
+ }
+ goto st8;
+st8:
+ if ( ++p == pe )
+ goto _test_eof8;
+case 8:
+#line 579 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr31;
+ case 39: goto tr32;
+ case 42: goto tr33;
+ case 92: goto tr34;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr31;
+ goto tr30;
+tr36:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st9;
+tr31:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 37 "concurrent.rl"
+ {
+ cout << "word: " << start_word <<
+ " " << cur_char-1 << endl;
+ }
+ goto st9;
+st9:
+ if ( ++p == pe )
+ goto _test_eof9;
+case 9:
+#line 610 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr36;
+ case 39: goto tr37;
+ case 42: goto tr38;
+ case 92: goto tr39;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr36;
+ goto tr35;
+tr37:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 34 "concurrent.rl"
+ {
+ start_word = cur_char;
+ }
+ goto st10;
+tr32:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st10;
+st10:
+ if ( ++p == pe )
+ goto _test_eof10;
+case 10:
+#line 640 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr41;
+ case 39: goto tr42;
+ case 42: goto tr43;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr41;
+ goto tr40;
+tr29:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 34 "concurrent.rl"
+ {
+ start_word = cur_char;
+ }
+ goto st11;
+tr25:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st11;
+tr43:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 53 "concurrent.rl"
+ {
+ cout << "literal: " << start_literal <<
+ " " << cur_char-1 << endl;
+ }
+ goto st11;
+st11:
+ if ( ++p == pe )
+ goto _test_eof11;
+case 11:
+#line 680 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr23;
+ case 39: goto tr24;
+ case 42: goto tr25;
+ case 47: goto tr44;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr23;
+ goto tr22;
+tr44:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st12;
+st12:
+ if ( ++p == pe )
+ goto _test_eof12;
+case 12:
+#line 700 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr46;
+ case 39: goto tr47;
+ case 47: goto tr48;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr46;
+ goto tr45;
+tr38:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 34 "concurrent.rl"
+ {
+ start_word = cur_char;
+ }
+ goto st13;
+tr33:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st13;
+st13:
+ if ( ++p == pe )
+ goto _test_eof13;
+case 13:
+#line 729 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr31;
+ case 39: goto tr32;
+ case 42: goto tr33;
+ case 47: goto tr49;
+ case 92: goto tr34;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr31;
+ goto tr30;
+tr49:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st14;
+st14:
+ if ( ++p == pe )
+ goto _test_eof14;
+case 14:
+#line 750 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr51;
+ case 39: goto tr52;
+ case 47: goto tr53;
+ case 92: goto tr54;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr51;
+ goto tr50;
+tr16:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 34 "concurrent.rl"
+ {
+ start_word = cur_char;
+ }
+#line 42 "concurrent.rl"
+ {
+ start_comment = cur_char;
+ }
+ goto st15;
+tr11:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 42 "concurrent.rl"
+ {
+ start_comment = cur_char;
+ }
+ goto st15;
+tr53:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 45 "concurrent.rl"
+ {
+ cout << "comment: " << start_comment <<
+ " " << cur_char-1 << endl;
+ }
+#line 42 "concurrent.rl"
+ {
+ start_comment = cur_char;
+ }
+ goto st15;
+st15:
+ if ( ++p == pe )
+ goto _test_eof15;
+case 15:
+#line 803 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr9;
+ case 39: goto tr10;
+ case 42: goto tr30;
+ case 47: goto tr11;
+ case 92: goto tr12;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr9;
+ goto tr8;
+tr17:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 34 "concurrent.rl"
+ {
+ start_word = cur_char;
+ }
+ goto st16;
+tr12:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st16;
+tr54:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 45 "concurrent.rl"
+ {
+ cout << "comment: " << start_comment <<
+ " " << cur_char-1 << endl;
+ }
+ goto st16;
+st16:
+ if ( ++p == pe )
+ goto _test_eof16;
+case 16:
+#line 845 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr9;
+ case 47: goto tr11;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr9;
+ goto tr8;
+tr39:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+#line 34 "concurrent.rl"
+ {
+ start_word = cur_char;
+ }
+ goto st17;
+tr34:
+#line 30 "concurrent.rl"
+ {
+ cur_char += 1;
+ }
+ goto st17;
+st17:
+ if ( ++p == pe )
+ goto _test_eof17;
+case 17:
+#line 873 "concurrent.cpp"
+ switch( (*p) ) {
+ case 32: goto tr31;
+ case 42: goto tr33;
+ }
+ if ( 9 <= (*p) && (*p) <= 13 )
+ goto tr31;
+ goto tr30;
+ }
+ _test_eof0: cs = 0; goto _test_eof;
+ _test_eof1: cs = 1; goto _test_eof;
+ _test_eof2: cs = 2; goto _test_eof;
+ _test_eof3: cs = 3; goto _test_eof;
+ _test_eof4: cs = 4; goto _test_eof;
+ _test_eof5: cs = 5; goto _test_eof;
+ _test_eof6: cs = 6; goto _test_eof;
+ _test_eof7: cs = 7; goto _test_eof;
+ _test_eof8: cs = 8; goto _test_eof;
+ _test_eof9: cs = 9; goto _test_eof;
+ _test_eof10: cs = 10; goto _test_eof;
+ _test_eof11: cs = 11; goto _test_eof;
+ _test_eof12: cs = 12; goto _test_eof;
+ _test_eof13: cs = 13; goto _test_eof;
+ _test_eof14: cs = 14; goto _test_eof;
+ _test_eof15: cs = 15; goto _test_eof;
+ _test_eof16: cs = 16; goto _test_eof;
+ _test_eof17: cs = 17; goto _test_eof;
+
+ _test_eof: {}
+ if ( p == eof )
+ {
+ switch ( cs ) {
+ case 1:
+ case 2:
+ case 5:
+ case 6:
+ case 8:
+ case 11:
+ case 13:
+ case 15:
+ case 16:
+ case 17:
+#line 37 "concurrent.rl"
+ {
+ cout << "word: " << start_word <<
+ " " << cur_char-1 << endl;
+ }
+ break;
+ case 12:
+ case 14:
+#line 37 "concurrent.rl"
+ {
+ cout << "word: " << start_word <<
+ " " << cur_char-1 << endl;
+ }
+#line 45 "concurrent.rl"
+ {
+ cout << "comment: " << start_comment <<
+ " " << cur_char-1 << endl;
+ }
+ break;
+ case 4:
+ case 10:
+#line 37 "concurrent.rl"
+ {
+ cout << "word: " << start_word <<
+ " " << cur_char-1 << endl;
+ }
+#line 53 "concurrent.rl"
+ {
+ cout << "literal: " << start_literal <<
+ " " << cur_char-1 << endl;
+ }
+ break;
+#line 947 "concurrent.cpp"
+ }
+ }
+
+ }
+
+#line 93 "concurrent.rl"
+
+ if ( cs == Concurrent_error )
+ return -1;
+ if ( cs >= Concurrent_first_final )
+ return 1;
+ return 0;
+}
+
+int Concurrent::finish( )
+{
+ if ( cs == Concurrent_error )
+ return -1;
+ if ( cs >= Concurrent_first_final )
+ return 1;
+ return 0;
+}
+
+Concurrent concurrent;
+char buf[BUFSIZE];
+
+int main()
+{
+ concurrent.init();
+ while ( 1 ) {
+ int len = fread( buf, 1, BUFSIZE, stdin );
+ concurrent.execute( buf, len, len != BUFSIZE );
+ if ( len != BUFSIZE )
+ break;
+ }
+
+ if ( concurrent.finish() <= 0 )
+ cerr << "concurrent: error parsing input" << endl;
+ return 0;
+}
diff --git a/examples/concurrent.rl b/examples/concurrent.rl
new file mode 100644
index 0000000..224f960
--- /dev/null
+++ b/examples/concurrent.rl
@@ -0,0 +1,126 @@
+/*
+ * Show off concurrent abilities.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+
+using namespace std;
+
+#define BUFSIZE 2048
+
+struct Concurrent
+{
+ int cur_char;
+ int start_word;
+ int start_comment;
+ int start_literal;
+
+ int cs;
+
+ int init( );
+ int execute( const char *data, int len, bool isEof );
+ int finish( );
+};
+
+%%{
+ machine Concurrent;
+
+ action next_char {
+ cur_char += 1;
+ }
+
+ action start_word {
+ start_word = cur_char;
+ }
+ action end_word {
+ cout << "word: " << start_word <<
+ " " << cur_char-1 << endl;
+ }
+
+ action start_comment {
+ start_comment = cur_char;
+ }
+ action end_comment {
+ cout << "comment: " << start_comment <<
+ " " << cur_char-1 << endl;
+ }
+
+ action start_literal {
+ start_literal = cur_char;
+ }
+ action end_literal {
+ cout << "literal: " << start_literal <<
+ " " << cur_char-1 << endl;
+ }
+
+ # Count characters.
+ chars = ( any @next_char )*;
+
+ # Words are non-whitespace.
+ word = ( any-space )+ >start_word %end_word;
+ words = ( ( word | space ) $1 %0 )*;
+
+ # Finds C style comments.
+ comment = ( '/*' any* :>> '*/' ) >start_comment %end_comment;
+ comments = ( comment | any )**;
+
+ # Finds single quoted strings.
+ literalChar = ( any - ['\\] ) | ( '\\' . any );
+ literal = ('\'' literalChar* '\'' ) >start_literal %end_literal;
+ literals = ( ( literal | (any-'\'') ) $1 %0 )*;
+
+ main := chars | words | comments | literals;
+}%%
+
+%% write data;
+
+int Concurrent::init( )
+{
+ %% write init;
+ cur_char = 0;
+ return 1;
+}
+
+int Concurrent::execute( const char *data, int len, bool isEof )
+{
+ const char *p = data;
+ const char *pe = data + len;
+ const char *eof = isEof ? pe : 0;
+
+ %% write exec;
+
+ if ( cs == Concurrent_error )
+ return -1;
+ if ( cs >= Concurrent_first_final )
+ return 1;
+ return 0;
+}
+
+int Concurrent::finish( )
+{
+ if ( cs == Concurrent_error )
+ return -1;
+ if ( cs >= Concurrent_first_final )
+ return 1;
+ return 0;
+}
+
+Concurrent concurrent;
+char buf[BUFSIZE];
+
+int main()
+{
+ concurrent.init();
+ while ( 1 ) {
+ int len = fread( buf, 1, BUFSIZE, stdin );
+ concurrent.execute( buf, len, len != BUFSIZE );
+ if ( len != BUFSIZE )
+ break;
+ }
+
+ if ( concurrent.finish() <= 0 )
+ cerr << "concurrent: error parsing input" << endl;
+ return 0;
+}
diff --git a/examples/cppscan.cpp b/examples/cppscan.cpp
new file mode 100644
index 0000000..6894311
--- /dev/null
+++ b/examples/cppscan.cpp
@@ -0,0 +1,908 @@
+
+#line 1 "cppscan.rl"
+/*
+ * A C++ scanner. Uses the longest match construction.
+ * << <= <<= >> >= >>= are left out since angle brackets are used in templates.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <iostream>
+
+#define TK_Dlit 256
+#define TK_Slit 257
+#define TK_Float 258
+#define TK_Id 259
+#define TK_NameSep 260
+#define TK_Arrow 261
+#define TK_PlusPlus 262
+#define TK_MinusMinus 263
+#define TK_ArrowStar 264
+#define TK_DotStar 265
+#define TK_ShiftLeft 266
+#define TK_ShiftRight 267
+#define TK_IntegerDecimal 268
+#define TK_IntegerOctal 269
+#define TK_IntegerHex 270
+#define TK_EqualsEquals 271
+#define TK_NotEquals 272
+#define TK_AndAnd 273
+#define TK_OrOr 274
+#define TK_MultAssign 275
+#define TK_DivAssign 276
+#define TK_PercentAssign 277
+#define TK_PlusAssign 278
+#define TK_MinusAssign 279
+#define TK_AmpAssign 280
+#define TK_CaretAssign 281
+#define TK_BarAssign 282
+#define TK_DotDotDot 283
+#define TK_Whitespace 284
+#define TK_Comment 285
+
+#define BUFSIZE 16384
+
+/* EOF char used to flush out that last token. This should be a whitespace
+ * token. */
+
+#define LAST_CHAR 0
+
+using std::cerr;
+using std::cout;
+using std::cin;
+using std::endl;
+
+static char buf[BUFSIZE];
+static int line = 1, col = 1;
+static char *ts, *te;
+static int act, have = 0;
+static int cs;
+
+
+#line 63 "cppscan.cpp"
+static const int Scanner_start = 12;
+static const int Scanner_error = 0;
+
+static const int Scanner_en_c_comment = 10;
+static const int Scanner_en_main = 12;
+
+
+#line 132 "cppscan.rl"
+
+
+void token( int tok )
+{
+ char *data = ts;
+ int len = te - ts;
+
+ cout << '<' << tok << "> ";
+ cout.write( data, len );
+ cout << '\n';
+
+ /* Count newlines and columns. This code is here mainly for having some
+ * code in the token routine when commenting out the above output during
+ * performance testing. */
+ for ( int i = 0; i < len; i ++ ) {
+ if ( data[i] == '\n' ) {
+ line += 1;
+ col = 1;
+ }
+ else {
+ col += 1;
+ }
+ }
+}
+
+int main()
+{
+ std::ios::sync_with_stdio(false);
+
+
+#line 102 "cppscan.cpp"
+ {
+ cs = Scanner_start;
+ ts = 0;
+ te = 0;
+ act = 0;
+ }
+
+#line 162 "cppscan.rl"
+
+ /* Do the first read. */
+ bool done = false;
+ while ( !done ) {
+ char *p = buf + have;
+ int space = BUFSIZE - have;
+
+ if ( space == 0 ) {
+ /* We filled up the buffer trying to scan a token. */
+ cerr << "OUT OF BUFFER SPACE" << endl;
+ exit(1);
+ }
+
+ cin.read( p, space );
+ int len = cin.gcount();
+ char *pe = p + len;
+ char *eof = 0;
+
+ /* If we see eof then append the EOF char. */
+ if ( cin.eof() ) {
+ eof = pe;
+ done = true;
+ }
+
+
+#line 136 "cppscan.cpp"
+ {
+ if ( p == pe )
+ goto _test_eof;
+ switch ( cs )
+ {
+tr0:
+#line 1 "NONE"
+ { switch( act ) {
+ case 0:
+ {{goto st0;}}
+ break;
+ case 3:
+ {{p = ((te))-1;}token( TK_Id );}
+ break;
+ case 4:
+ {{p = ((te))-1;}token( TK_Float );}
+ break;
+ case 5:
+ {{p = ((te))-1;}token( TK_IntegerDecimal );}
+ break;
+ case 6:
+ {{p = ((te))-1;}token( TK_IntegerOctal );}
+ break;
+ }
+ }
+ goto st12;
+tr2:
+#line 78 "cppscan.rl"
+ {te = p+1;{token( TK_Dlit );}}
+ goto st12;
+tr5:
+#line 76 "cppscan.rl"
+ {te = p+1;{token( TK_Slit );}}
+ goto st12;
+tr7:
+#line 124 "cppscan.rl"
+ {{p = ((te))-1;}{token( ts[0] );}}
+ goto st12;
+tr8:
+#line 121 "cppscan.rl"
+ {te = p+1;{token( TK_DotDotDot );}}
+ goto st12;
+tr12:
+#line 128 "cppscan.rl"
+ {te = p+1;}
+ goto st12;
+tr13:
+#line 90 "cppscan.rl"
+ {{p = ((te))-1;}{token( TK_IntegerDecimal );}}
+ goto st12;
+tr20:
+#line 124 "cppscan.rl"
+ {te = p+1;{token( ts[0] );}}
+ goto st12;
+tr36:
+#line 129 "cppscan.rl"
+ {te = p;p--;}
+ goto st12;
+tr37:
+#line 124 "cppscan.rl"
+ {te = p;p--;{token( ts[0] );}}
+ goto st12;
+tr38:
+#line 103 "cppscan.rl"
+ {te = p+1;{token( TK_NotEquals );}}
+ goto st12;
+tr39:
+#line 108 "cppscan.rl"
+ {te = p+1;{token( TK_PercentAssign );}}
+ goto st12;
+tr40:
+#line 104 "cppscan.rl"
+ {te = p+1;{token( TK_AndAnd );}}
+ goto st12;
+tr41:
+#line 111 "cppscan.rl"
+ {te = p+1;{token( TK_AmpAssign );}}
+ goto st12;
+tr42:
+#line 106 "cppscan.rl"
+ {te = p+1;{token( TK_MultAssign );}}
+ goto st12;
+tr43:
+#line 114 "cppscan.rl"
+ {te = p+1;{token( TK_PlusPlus );}}
+ goto st12;
+tr44:
+#line 109 "cppscan.rl"
+ {te = p+1;{token( TK_PlusAssign );}}
+ goto st12;
+tr45:
+#line 115 "cppscan.rl"
+ {te = p+1;{token( TK_MinusMinus );}}
+ goto st12;
+tr46:
+#line 110 "cppscan.rl"
+ {te = p+1;{token( TK_MinusAssign );}}
+ goto st12;
+tr48:
+#line 116 "cppscan.rl"
+ {te = p;p--;{token( TK_Arrow );}}
+ goto st12;
+tr49:
+#line 117 "cppscan.rl"
+ {te = p+1;{token( TK_ArrowStar );}}
+ goto st12;
+tr50:
+#line 118 "cppscan.rl"
+ {te = p+1;{token( TK_DotStar );}}
+ goto st12;
+tr53:
+#line 86 "cppscan.rl"
+ {te = p;p--;{token( TK_Float );}}
+ goto st12;
+tr55:
+#line 86 "cppscan.rl"
+ {te = p+1;{token( TK_Float );}}
+ goto st12;
+tr56:
+#line 127 "cppscan.rl"
+ {te = p+1;{ {goto st10;} }}
+ goto st12;
+tr57:
+#line 107 "cppscan.rl"
+ {te = p+1;{token( TK_DivAssign );}}
+ goto st12;
+tr58:
+#line 90 "cppscan.rl"
+ {te = p;p--;{token( TK_IntegerDecimal );}}
+ goto st12;
+tr62:
+#line 94 "cppscan.rl"
+ {te = p;p--;{token( TK_IntegerOctal );}}
+ goto st12;
+tr64:
+#line 94 "cppscan.rl"
+ {te = p+1;{token( TK_IntegerOctal );}}
+ goto st12;
+tr66:
+#line 90 "cppscan.rl"
+ {te = p+1;{token( TK_IntegerDecimal );}}
+ goto st12;
+tr67:
+#line 98 "cppscan.rl"
+ {te = p;p--;{token( TK_IntegerHex );}}
+ goto st12;
+tr69:
+#line 98 "cppscan.rl"
+ {te = p+1;{token( TK_IntegerHex );}}
+ goto st12;
+tr70:
+#line 101 "cppscan.rl"
+ {te = p+1;{token( TK_NameSep );}}
+ goto st12;
+tr71:
+#line 102 "cppscan.rl"
+ {te = p+1;{token( TK_EqualsEquals );}}
+ goto st12;
+tr72:
+#line 82 "cppscan.rl"
+ {te = p;p--;{token( TK_Id );}}
+ goto st12;
+tr73:
+#line 112 "cppscan.rl"
+ {te = p+1;{token( TK_CaretAssign );}}
+ goto st12;
+tr74:
+#line 113 "cppscan.rl"
+ {te = p+1;{token( TK_BarAssign );}}
+ goto st12;
+tr75:
+#line 105 "cppscan.rl"
+ {te = p+1;{token( TK_OrOr );}}
+ goto st12;
+st12:
+#line 1 "NONE"
+ {ts = 0;}
+#line 1 "NONE"
+ {act = 0;}
+ if ( ++p == pe )
+ goto _test_eof12;
+case 12:
+#line 1 "NONE"
+ {ts = p;}
+#line 321 "cppscan.cpp"
+ switch( (*p) ) {
+ case 33: goto st14;
+ case 34: goto st1;
+ case 37: goto st15;
+ case 38: goto st16;
+ case 39: goto st3;
+ case 42: goto st17;
+ case 43: goto st18;
+ case 45: goto st19;
+ case 46: goto tr26;
+ case 47: goto tr27;
+ case 48: goto tr28;
+ case 58: goto st33;
+ case 61: goto st34;
+ case 76: goto tr33;
+ case 94: goto st37;
+ case 95: goto st35;
+ case 124: goto st38;
+ }
+ if ( (*p) < 65 ) {
+ if ( (*p) < 49 ) {
+ if ( 35 <= (*p) && (*p) <= 44 )
+ goto tr20;
+ } else if ( (*p) > 57 ) {
+ if ( 59 <= (*p) && (*p) <= 64 )
+ goto tr20;
+ } else
+ goto tr29;
+ } else if ( (*p) > 90 ) {
+ if ( (*p) < 97 ) {
+ if ( 91 <= (*p) && (*p) <= 96 )
+ goto tr20;
+ } else if ( (*p) > 122 ) {
+ if ( 123 <= (*p) && (*p) <= 126 )
+ goto tr20;
+ } else
+ goto st35;
+ } else
+ goto st35;
+ goto st13;
+st13:
+ if ( ++p == pe )
+ goto _test_eof13;
+case 13:
+ if ( 33 <= (*p) && (*p) <= 126 )
+ goto tr36;
+ goto st13;
+st14:
+ if ( ++p == pe )
+ goto _test_eof14;
+case 14:
+ if ( (*p) == 61 )
+ goto tr38;
+ goto tr37;
+st1:
+ if ( ++p == pe )
+ goto _test_eof1;
+case 1:
+ switch( (*p) ) {
+ case 10: goto tr0;
+ case 34: goto tr2;
+ case 92: goto st2;
+ }
+ goto st1;
+st2:
+ if ( ++p == pe )
+ goto _test_eof2;
+case 2:
+ goto st1;
+st15:
+ if ( ++p == pe )
+ goto _test_eof15;
+case 15:
+ if ( (*p) == 61 )
+ goto tr39;
+ goto tr37;
+st16:
+ if ( ++p == pe )
+ goto _test_eof16;
+case 16:
+ switch( (*p) ) {
+ case 38: goto tr40;
+ case 61: goto tr41;
+ }
+ goto tr37;
+st3:
+ if ( ++p == pe )
+ goto _test_eof3;
+case 3:
+ switch( (*p) ) {
+ case 10: goto tr0;
+ case 39: goto tr5;
+ case 92: goto st4;
+ }
+ goto st3;
+st4:
+ if ( ++p == pe )
+ goto _test_eof4;
+case 4:
+ goto st3;
+st17:
+ if ( ++p == pe )
+ goto _test_eof17;
+case 17:
+ if ( (*p) == 61 )
+ goto tr42;
+ goto tr37;
+st18:
+ if ( ++p == pe )
+ goto _test_eof18;
+case 18:
+ switch( (*p) ) {
+ case 43: goto tr43;
+ case 61: goto tr44;
+ }
+ goto tr37;
+st19:
+ if ( ++p == pe )
+ goto _test_eof19;
+case 19:
+ switch( (*p) ) {
+ case 45: goto tr45;
+ case 61: goto tr46;
+ case 62: goto st20;
+ }
+ goto tr37;
+st20:
+ if ( ++p == pe )
+ goto _test_eof20;
+case 20:
+ if ( (*p) == 42 )
+ goto tr49;
+ goto tr48;
+tr26:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st21;
+st21:
+ if ( ++p == pe )
+ goto _test_eof21;
+case 21:
+#line 463 "cppscan.cpp"
+ switch( (*p) ) {
+ case 42: goto tr50;
+ case 46: goto st5;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr52;
+ goto tr37;
+st5:
+ if ( ++p == pe )
+ goto _test_eof5;
+case 5:
+ if ( (*p) == 46 )
+ goto tr8;
+ goto tr7;
+tr52:
+#line 1 "NONE"
+ {te = p+1;}
+#line 86 "cppscan.rl"
+ {act = 4;}
+ goto st22;
+st22:
+ if ( ++p == pe )
+ goto _test_eof22;
+case 22:
+#line 488 "cppscan.cpp"
+ switch( (*p) ) {
+ case 69: goto st6;
+ case 70: goto tr55;
+ case 76: goto tr55;
+ case 101: goto st6;
+ case 102: goto tr55;
+ case 108: goto tr55;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr52;
+ goto tr53;
+st6:
+ if ( ++p == pe )
+ goto _test_eof6;
+case 6:
+ switch( (*p) ) {
+ case 43: goto st7;
+ case 45: goto st7;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st23;
+ goto tr0;
+st7:
+ if ( ++p == pe )
+ goto _test_eof7;
+case 7:
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st23;
+ goto tr0;
+st23:
+ if ( ++p == pe )
+ goto _test_eof23;
+case 23:
+ switch( (*p) ) {
+ case 70: goto tr55;
+ case 76: goto tr55;
+ case 102: goto tr55;
+ case 108: goto tr55;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st23;
+ goto tr53;
+tr27:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st24;
+st24:
+ if ( ++p == pe )
+ goto _test_eof24;
+case 24:
+#line 539 "cppscan.cpp"
+ switch( (*p) ) {
+ case 42: goto tr56;
+ case 47: goto st8;
+ case 61: goto tr57;
+ }
+ goto tr37;
+st8:
+ if ( ++p == pe )
+ goto _test_eof8;
+case 8:
+ if ( (*p) == 10 )
+ goto tr12;
+ goto st8;
+tr28:
+#line 1 "NONE"
+ {te = p+1;}
+#line 90 "cppscan.rl"
+ {act = 5;}
+ goto st25;
+st25:
+ if ( ++p == pe )
+ goto _test_eof25;
+case 25:
+#line 563 "cppscan.cpp"
+ switch( (*p) ) {
+ case 46: goto tr52;
+ case 69: goto st6;
+ case 76: goto st28;
+ case 85: goto st28;
+ case 101: goto st6;
+ case 108: goto st28;
+ case 117: goto st28;
+ case 120: goto st9;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr59;
+ goto tr58;
+tr59:
+#line 1 "NONE"
+ {te = p+1;}
+#line 94 "cppscan.rl"
+ {act = 6;}
+ goto st26;
+st26:
+ if ( ++p == pe )
+ goto _test_eof26;
+case 26:
+#line 587 "cppscan.cpp"
+ switch( (*p) ) {
+ case 46: goto tr52;
+ case 69: goto st6;
+ case 76: goto st27;
+ case 85: goto st27;
+ case 101: goto st6;
+ case 108: goto st27;
+ case 117: goto st27;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr59;
+ goto tr62;
+st27:
+ if ( ++p == pe )
+ goto _test_eof27;
+case 27:
+ switch( (*p) ) {
+ case 76: goto tr64;
+ case 85: goto tr64;
+ case 108: goto tr64;
+ case 117: goto tr64;
+ }
+ goto tr62;
+st28:
+ if ( ++p == pe )
+ goto _test_eof28;
+case 28:
+ switch( (*p) ) {
+ case 76: goto st29;
+ case 85: goto st29;
+ case 108: goto st29;
+ case 117: goto st29;
+ }
+ goto tr58;
+st29:
+ if ( ++p == pe )
+ goto _test_eof29;
+case 29:
+ switch( (*p) ) {
+ case 76: goto tr66;
+ case 85: goto tr66;
+ case 108: goto tr66;
+ case 117: goto tr66;
+ }
+ goto tr58;
+st9:
+ if ( ++p == pe )
+ goto _test_eof9;
+case 9:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st30;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st30;
+ } else
+ goto st30;
+ goto tr13;
+st30:
+ if ( ++p == pe )
+ goto _test_eof30;
+case 30:
+ switch( (*p) ) {
+ case 76: goto st31;
+ case 85: goto st31;
+ case 108: goto st31;
+ case 117: goto st31;
+ }
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st30;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st30;
+ } else
+ goto st30;
+ goto tr67;
+st31:
+ if ( ++p == pe )
+ goto _test_eof31;
+case 31:
+ switch( (*p) ) {
+ case 76: goto tr69;
+ case 85: goto tr69;
+ case 108: goto tr69;
+ case 117: goto tr69;
+ }
+ goto tr67;
+tr29:
+#line 1 "NONE"
+ {te = p+1;}
+#line 90 "cppscan.rl"
+ {act = 5;}
+ goto st32;
+st32:
+ if ( ++p == pe )
+ goto _test_eof32;
+case 32:
+#line 686 "cppscan.cpp"
+ switch( (*p) ) {
+ case 46: goto tr52;
+ case 69: goto st6;
+ case 76: goto st28;
+ case 85: goto st28;
+ case 101: goto st6;
+ case 108: goto st28;
+ case 117: goto st28;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr29;
+ goto tr58;
+st33:
+ if ( ++p == pe )
+ goto _test_eof33;
+case 33:
+ if ( (*p) == 58 )
+ goto tr70;
+ goto tr37;
+st34:
+ if ( ++p == pe )
+ goto _test_eof34;
+case 34:
+ if ( (*p) == 61 )
+ goto tr71;
+ goto tr37;
+st35:
+ if ( ++p == pe )
+ goto _test_eof35;
+case 35:
+ if ( (*p) == 95 )
+ goto st35;
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st35;
+ } else if ( (*p) > 90 ) {
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st35;
+ } else
+ goto st35;
+ goto tr72;
+tr33:
+#line 1 "NONE"
+ {te = p+1;}
+#line 82 "cppscan.rl"
+ {act = 3;}
+ goto st36;
+st36:
+ if ( ++p == pe )
+ goto _test_eof36;
+case 36:
+#line 738 "cppscan.cpp"
+ switch( (*p) ) {
+ case 34: goto st1;
+ case 39: goto st3;
+ case 95: goto st35;
+ }
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st35;
+ } else if ( (*p) > 90 ) {
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st35;
+ } else
+ goto st35;
+ goto tr72;
+st37:
+ if ( ++p == pe )
+ goto _test_eof37;
+case 37:
+ if ( (*p) == 61 )
+ goto tr73;
+ goto tr37;
+st38:
+ if ( ++p == pe )
+ goto _test_eof38;
+case 38:
+ switch( (*p) ) {
+ case 61: goto tr74;
+ case 124: goto tr75;
+ }
+ goto tr37;
+st10:
+#line 1 "NONE"
+ {ts = 0;}
+ if ( ++p == pe )
+ goto _test_eof10;
+case 10:
+#line 775 "cppscan.cpp"
+ if ( (*p) == 42 )
+ goto st11;
+ goto st10;
+st11:
+ if ( ++p == pe )
+ goto _test_eof11;
+case 11:
+ switch( (*p) ) {
+ case 42: goto st11;
+ case 47: goto tr17;
+ }
+ goto st10;
+tr17:
+#line 70 "cppscan.rl"
+ { {goto st12;} }
+ goto st39;
+st39:
+ if ( ++p == pe )
+ goto _test_eof39;
+case 39:
+#line 796 "cppscan.cpp"
+ goto st0;
+st0:
+cs = 0;
+ goto _out;
+ }
+ _test_eof12: cs = 12; goto _test_eof;
+ _test_eof13: cs = 13; goto _test_eof;
+ _test_eof14: cs = 14; goto _test_eof;
+ _test_eof1: cs = 1; goto _test_eof;
+ _test_eof2: cs = 2; goto _test_eof;
+ _test_eof15: cs = 15; goto _test_eof;
+ _test_eof16: cs = 16; goto _test_eof;
+ _test_eof3: cs = 3; goto _test_eof;
+ _test_eof4: cs = 4; goto _test_eof;
+ _test_eof17: cs = 17; goto _test_eof;
+ _test_eof18: cs = 18; goto _test_eof;
+ _test_eof19: cs = 19; goto _test_eof;
+ _test_eof20: cs = 20; goto _test_eof;
+ _test_eof21: cs = 21; goto _test_eof;
+ _test_eof5: cs = 5; goto _test_eof;
+ _test_eof22: cs = 22; goto _test_eof;
+ _test_eof6: cs = 6; goto _test_eof;
+ _test_eof7: cs = 7; goto _test_eof;
+ _test_eof23: cs = 23; goto _test_eof;
+ _test_eof24: cs = 24; goto _test_eof;
+ _test_eof8: cs = 8; goto _test_eof;
+ _test_eof25: cs = 25; goto _test_eof;
+ _test_eof26: cs = 26; goto _test_eof;
+ _test_eof27: cs = 27; goto _test_eof;
+ _test_eof28: cs = 28; goto _test_eof;
+ _test_eof29: cs = 29; goto _test_eof;
+ _test_eof9: cs = 9; goto _test_eof;
+ _test_eof30: cs = 30; goto _test_eof;
+ _test_eof31: cs = 31; goto _test_eof;
+ _test_eof32: cs = 32; goto _test_eof;
+ _test_eof33: cs = 33; goto _test_eof;
+ _test_eof34: cs = 34; goto _test_eof;
+ _test_eof35: cs = 35; goto _test_eof;
+ _test_eof36: cs = 36; goto _test_eof;
+ _test_eof37: cs = 37; goto _test_eof;
+ _test_eof38: cs = 38; goto _test_eof;
+ _test_eof10: cs = 10; goto _test_eof;
+ _test_eof11: cs = 11; goto _test_eof;
+ _test_eof39: cs = 39; goto _test_eof;
+
+ _test_eof: {}
+ if ( p == eof )
+ {
+ switch ( cs ) {
+ case 13: goto tr36;
+ case 14: goto tr37;
+ case 1: goto tr0;
+ case 2: goto tr0;
+ case 15: goto tr37;
+ case 16: goto tr37;
+ case 3: goto tr0;
+ case 4: goto tr0;
+ case 17: goto tr37;
+ case 18: goto tr37;
+ case 19: goto tr37;
+ case 20: goto tr48;
+ case 21: goto tr37;
+ case 5: goto tr7;
+ case 22: goto tr53;
+ case 6: goto tr0;
+ case 7: goto tr0;
+ case 23: goto tr53;
+ case 24: goto tr37;
+ case 8: goto tr7;
+ case 25: goto tr58;
+ case 26: goto tr62;
+ case 27: goto tr62;
+ case 28: goto tr58;
+ case 29: goto tr58;
+ case 9: goto tr13;
+ case 30: goto tr67;
+ case 31: goto tr67;
+ case 32: goto tr58;
+ case 33: goto tr37;
+ case 34: goto tr37;
+ case 35: goto tr72;
+ case 36: goto tr72;
+ case 37: goto tr37;
+ case 38: goto tr37;
+ }
+ }
+
+ _out: {}
+ }
+
+#line 187 "cppscan.rl"
+
+ /* Check if we failed. */
+ if ( cs == Scanner_error ) {
+ /* Machine failed before finding a token. */
+ cerr << "PARSE ERROR" << endl;
+ exit(1);
+ }
+
+ /* Now set up the prefix. */
+ if ( ts == 0 )
+ have = 0;
+ else {
+ /* There is data that needs to be shifted over. */
+ have = pe - ts;
+ memmove( buf, ts, have );
+ te -= (ts-buf);
+ ts = buf;
+ }
+ }
+
+ return 0;
+}
diff --git a/examples/cppscan.rl b/examples/cppscan.rl
new file mode 100644
index 0000000..1ead5aa
--- /dev/null
+++ b/examples/cppscan.rl
@@ -0,0 +1,208 @@
+/*
+ * A C++ scanner. Uses the longest match construction.
+ * << <= <<= >> >= >>= are left out since angle brackets are used in templates.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <iostream>
+
+#define TK_Dlit 256
+#define TK_Slit 257
+#define TK_Float 258
+#define TK_Id 259
+#define TK_NameSep 260
+#define TK_Arrow 261
+#define TK_PlusPlus 262
+#define TK_MinusMinus 263
+#define TK_ArrowStar 264
+#define TK_DotStar 265
+#define TK_ShiftLeft 266
+#define TK_ShiftRight 267
+#define TK_IntegerDecimal 268
+#define TK_IntegerOctal 269
+#define TK_IntegerHex 270
+#define TK_EqualsEquals 271
+#define TK_NotEquals 272
+#define TK_AndAnd 273
+#define TK_OrOr 274
+#define TK_MultAssign 275
+#define TK_DivAssign 276
+#define TK_PercentAssign 277
+#define TK_PlusAssign 278
+#define TK_MinusAssign 279
+#define TK_AmpAssign 280
+#define TK_CaretAssign 281
+#define TK_BarAssign 282
+#define TK_DotDotDot 283
+#define TK_Whitespace 284
+#define TK_Comment 285
+
+#define BUFSIZE 16384
+
+/* EOF char used to flush out that last token. This should be a whitespace
+ * token. */
+
+#define LAST_CHAR 0
+
+using std::cerr;
+using std::cout;
+using std::cin;
+using std::endl;
+
+static char buf[BUFSIZE];
+static int line = 1, col = 1;
+static char *ts, *te;
+static int act, have = 0;
+static int cs;
+
+%%{
+ machine Scanner;
+ write data nofinal;
+
+ # Floating literals.
+ fract_const = digit* '.' digit+ | digit+ '.';
+ exponent = [eE] [+\-]? digit+;
+ float_suffix = [flFL];
+
+ c_comment :=
+ any* :>> '*/'
+ @{ fgoto main; };
+
+ main := |*
+
+ # Single and double literals.
+ ( 'L'? "'" ( [^'\\\n] | /\\./ )* "'" )
+ {token( TK_Slit );};
+ ( 'L'? '"' ( [^"\\\n] | /\\./ )* '"' )
+ {token( TK_Dlit );};
+
+ # Identifiers
+ ( [a-zA-Z_] [a-zA-Z0-9_]* )
+ {token( TK_Id );};
+
+ # Floating literals.
+ ( fract_const exponent? float_suffix? | digit+ exponent float_suffix? )
+ {token( TK_Float );};
+
+ # Integer decimal. Leading part buffered by float.
+ ( ( '0' | [1-9] [0-9]* ) [ulUL]{0,3} )
+ {token( TK_IntegerDecimal );};
+
+ # Integer octal. Leading part buffered by float.
+ ( '0' [0-9]+ [ulUL]{0,2} )
+ {token( TK_IntegerOctal );};
+
+ # Integer hex. Leading 0 buffered by float.
+ ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]{0,2} ) )
+ {token( TK_IntegerHex );};
+
+ # Only buffer the second item, first buffered by symbol. */
+ '::' {token( TK_NameSep );};
+ '==' {token( TK_EqualsEquals );};
+ '!=' {token( TK_NotEquals );};
+ '&&' {token( TK_AndAnd );};
+ '||' {token( TK_OrOr );};
+ '*=' {token( TK_MultAssign );};
+ '/=' {token( TK_DivAssign );};
+ '%=' {token( TK_PercentAssign );};
+ '+=' {token( TK_PlusAssign );};
+ '-=' {token( TK_MinusAssign );};
+ '&=' {token( TK_AmpAssign );};
+ '^=' {token( TK_CaretAssign );};
+ '|=' {token( TK_BarAssign );};
+ '++' {token( TK_PlusPlus );};
+ '--' {token( TK_MinusMinus );};
+ '->' {token( TK_Arrow );};
+ '->*' {token( TK_ArrowStar );};
+ '.*' {token( TK_DotStar );};
+
+ # Three char compounds, first item already buffered. */
+ '...' {token( TK_DotDotDot );};
+
+ # Single char symbols.
+ ( punct - [_"'] ) {token( ts[0] );};
+
+ # Comments and whitespace.
+ '/*' { fgoto c_comment; };
+ '//' [^\n]* '\n';
+ ( any - 33..126 )+;
+
+ *|;
+}%%
+
+void token( int tok )
+{
+ char *data = ts;
+ int len = te - ts;
+
+ cout << '<' << tok << "> ";
+ cout.write( data, len );
+ cout << '\n';
+
+ /* Count newlines and columns. This code is here mainly for having some
+ * code in the token routine when commenting out the above output during
+ * performance testing. */
+ for ( int i = 0; i < len; i ++ ) {
+ if ( data[i] == '\n' ) {
+ line += 1;
+ col = 1;
+ }
+ else {
+ col += 1;
+ }
+ }
+}
+
+int main()
+{
+ std::ios::sync_with_stdio(false);
+
+ %% write init;
+
+ /* Do the first read. */
+ bool done = false;
+ while ( !done ) {
+ char *p = buf + have;
+ int space = BUFSIZE - have;
+
+ if ( space == 0 ) {
+ /* We filled up the buffer trying to scan a token. */
+ cerr << "OUT OF BUFFER SPACE" << endl;
+ exit(1);
+ }
+
+ cin.read( p, space );
+ int len = cin.gcount();
+ char *pe = p + len;
+ char *eof = 0;
+
+ /* If we see eof then append the EOF char. */
+ if ( cin.eof() ) {
+ eof = pe;
+ done = true;
+ }
+
+ %% write exec;
+
+ /* Check if we failed. */
+ if ( cs == Scanner_error ) {
+ /* Machine failed before finding a token. */
+ cerr << "PARSE ERROR" << endl;
+ exit(1);
+ }
+
+ /* Now set up the prefix. */
+ if ( ts == 0 )
+ have = 0;
+ else {
+ /* There is data that needs to be shifted over. */
+ have = pe - ts;
+ memmove( buf, ts, have );
+ te -= (ts-buf);
+ ts = buf;
+ }
+ }
+
+ return 0;
+}
diff --git a/examples/format.c b/examples/format.c
new file mode 100644
index 0000000..768b063
--- /dev/null
+++ b/examples/format.c
@@ -0,0 +1,544 @@
+
+#line 1 "format.rl"
+/*
+ * Partial printf implementation.
+ */
+
+#define BUFLEN 1024
+#include <stdio.h>
+
+typedef void (*WriteFunc)( char *data, int len );
+
+struct format
+{
+ char buf[BUFLEN+1];
+ int buflen;
+ WriteFunc write;
+
+ int flags;
+ int width;
+ int prec;
+ int cs;
+};
+
+void do_conv( struct format *fsm, char c )
+{
+ printf( "flags: %x\n", fsm->flags );
+ printf( "width: %i\n", fsm->width );
+ printf( "prec: %i\n", fsm->prec );
+ printf( "conv: %c\n", c );
+ printf( "\n" );
+}
+
+#define FL_HASH 0x01
+#define FL_ZERO 0x02
+#define FL_DASH 0x04
+#define FL_SPACE 0x08
+#define FL_PLUS 0x10
+
+#define FL_HAS_WIDTH 0x0100
+#define FL_WIDTH_ARG 0x0200
+#define FL_HAS_PREC 0x0400
+#define FL_PREC_ARG 0x0800
+
+#define FL_LEN_H 0x010000
+#define FL_LEN_HH 0x020000
+#define FL_LEN_L 0x040000
+#define FL_LEN_LL 0x080000
+
+
+#line 137 "format.rl"
+
+
+
+#line 55 "format.c"
+static const int format_start = 11;
+static const int format_first_final = 11;
+static const int format_error = 0;
+
+static const int format_en_main = 11;
+
+
+#line 140 "format.rl"
+
+void format_init( struct format *fsm )
+{
+ fsm->buflen = 0;
+
+#line 69 "format.c"
+ {
+ fsm->cs = format_start;
+ }
+
+#line 145 "format.rl"
+}
+
+void format_execute( struct format *fsm, const char *data, int len, int isEof )
+{
+ const char *p = data;
+ const char *pe = data + len;
+ const char *eof = isEof ? pe : 0;
+
+
+#line 84 "format.c"
+ {
+ if ( p == pe )
+ goto _test_eof;
+ switch ( fsm->cs )
+ {
+tr3:
+#line 113 "format.rl"
+ {
+ if ( fsm->buflen == BUFLEN ) {
+ fsm->write( fsm->buf, fsm->buflen );
+ fsm->buflen = 0;
+ }
+ fsm->buf[fsm->buflen++] = (*p);
+ }
+ goto st11;
+tr10:
+#line 99 "format.rl"
+ {
+ do_conv( fsm, (*p) );
+ }
+ goto st11;
+tr14:
+#line 63 "format.rl"
+ { fsm->flags |= FL_HAS_WIDTH; }
+#line 99 "format.rl"
+ {
+ do_conv( fsm, (*p) );
+ }
+ goto st11;
+tr19:
+#line 69 "format.rl"
+ { fsm->flags |= FL_HAS_PREC; }
+#line 99 "format.rl"
+ {
+ do_conv( fsm, (*p) );
+ }
+ goto st11;
+tr22:
+#line 86 "format.rl"
+ { fsm->flags |= FL_LEN_H; }
+#line 99 "format.rl"
+ {
+ do_conv( fsm, (*p) );
+ }
+ goto st11;
+tr24:
+#line 87 "format.rl"
+ { fsm->flags |= FL_LEN_L; }
+#line 99 "format.rl"
+ {
+ do_conv( fsm, (*p) );
+ }
+ goto st11;
+st11:
+ if ( ++p == pe )
+ goto _test_eof11;
+case 11:
+#line 142 "format.c"
+ if ( (*p) == 37 )
+ goto tr26;
+ goto tr3;
+tr26:
+#line 51 "format.rl"
+ {
+ fsm->flags = 0;
+ fsm->width = 0;
+ fsm->prec = 0;
+ }
+ goto st1;
+st1:
+ if ( ++p == pe )
+ goto _test_eof1;
+case 1:
+#line 158 "format.c"
+ switch( (*p) ) {
+ case 32: goto tr1;
+ case 35: goto tr2;
+ case 37: goto tr3;
+ case 42: goto tr4;
+ case 43: goto tr5;
+ case 45: goto tr6;
+ case 46: goto st4;
+ case 48: goto tr8;
+ case 88: goto tr10;
+ case 104: goto st6;
+ case 105: goto tr10;
+ case 108: goto st8;
+ case 115: goto tr10;
+ case 117: goto tr10;
+ case 120: goto tr10;
+ }
+ if ( (*p) < 99 ) {
+ if ( 49 <= (*p) && (*p) <= 57 )
+ goto tr9;
+ } else if ( (*p) > 100 ) {
+ if ( 111 <= (*p) && (*p) <= 112 )
+ goto tr10;
+ } else
+ goto tr10;
+ goto tr0;
+tr0:
+#line 128 "format.rl"
+ {
+ printf("ERROR ON CHAR: 0x%x\n", (*p) );
+ }
+ goto st0;
+#line 191 "format.c"
+st0:
+ fsm->cs = 0;
+ goto _out;
+tr1:
+#line 76 "format.rl"
+ { fsm->flags |= FL_SPACE; }
+ goto st2;
+tr2:
+#line 73 "format.rl"
+ { fsm->flags |= FL_HASH; }
+ goto st2;
+tr5:
+#line 77 "format.rl"
+ { fsm->flags |= FL_PLUS; }
+ goto st2;
+tr6:
+#line 75 "format.rl"
+ { fsm->flags |= FL_DASH; }
+ goto st2;
+tr8:
+#line 74 "format.rl"
+ { fsm->flags |= FL_ZERO; }
+ goto st2;
+st2:
+ if ( ++p == pe )
+ goto _test_eof2;
+case 2:
+#line 219 "format.c"
+ switch( (*p) ) {
+ case 32: goto tr1;
+ case 35: goto tr2;
+ case 42: goto tr4;
+ case 43: goto tr5;
+ case 45: goto tr6;
+ case 46: goto st4;
+ case 48: goto tr8;
+ case 88: goto tr10;
+ case 104: goto st6;
+ case 105: goto tr10;
+ case 108: goto st8;
+ case 115: goto tr10;
+ case 117: goto tr10;
+ case 120: goto tr10;
+ }
+ if ( (*p) < 99 ) {
+ if ( 49 <= (*p) && (*p) <= 57 )
+ goto tr9;
+ } else if ( (*p) > 100 ) {
+ if ( 111 <= (*p) && (*p) <= 112 )
+ goto tr10;
+ } else
+ goto tr10;
+ goto tr0;
+tr4:
+#line 62 "format.rl"
+ { fsm->flags |= FL_WIDTH_ARG; }
+ goto st3;
+st3:
+ if ( ++p == pe )
+ goto _test_eof3;
+case 3:
+#line 253 "format.c"
+ switch( (*p) ) {
+ case 46: goto tr13;
+ case 88: goto tr14;
+ case 104: goto tr15;
+ case 105: goto tr14;
+ case 108: goto tr16;
+ case 115: goto tr14;
+ case 117: goto tr14;
+ case 120: goto tr14;
+ }
+ if ( (*p) > 100 ) {
+ if ( 111 <= (*p) && (*p) <= 112 )
+ goto tr14;
+ } else if ( (*p) >= 99 )
+ goto tr14;
+ goto tr0;
+tr13:
+#line 63 "format.rl"
+ { fsm->flags |= FL_HAS_WIDTH; }
+ goto st4;
+st4:
+ if ( ++p == pe )
+ goto _test_eof4;
+case 4:
+#line 278 "format.c"
+ switch( (*p) ) {
+ case 42: goto tr17;
+ case 88: goto tr19;
+ case 104: goto tr20;
+ case 105: goto tr19;
+ case 108: goto tr21;
+ case 115: goto tr19;
+ case 117: goto tr19;
+ case 120: goto tr19;
+ }
+ if ( (*p) < 99 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr18;
+ } else if ( (*p) > 100 ) {
+ if ( 111 <= (*p) && (*p) <= 112 )
+ goto tr19;
+ } else
+ goto tr19;
+ goto tr0;
+tr17:
+#line 68 "format.rl"
+ { fsm->flags |= FL_PREC_ARG; }
+ goto st5;
+st5:
+ if ( ++p == pe )
+ goto _test_eof5;
+case 5:
+#line 306 "format.c"
+ switch( (*p) ) {
+ case 88: goto tr10;
+ case 104: goto st6;
+ case 105: goto tr10;
+ case 108: goto st8;
+ case 115: goto tr10;
+ case 117: goto tr10;
+ case 120: goto tr10;
+ }
+ if ( (*p) > 100 ) {
+ if ( 111 <= (*p) && (*p) <= 112 )
+ goto tr10;
+ } else if ( (*p) >= 99 )
+ goto tr10;
+ goto tr0;
+tr15:
+#line 63 "format.rl"
+ { fsm->flags |= FL_HAS_WIDTH; }
+ goto st6;
+tr20:
+#line 69 "format.rl"
+ { fsm->flags |= FL_HAS_PREC; }
+ goto st6;
+st6:
+ if ( ++p == pe )
+ goto _test_eof6;
+case 6:
+#line 334 "format.c"
+ switch( (*p) ) {
+ case 88: goto tr22;
+ case 104: goto tr23;
+ case 105: goto tr22;
+ case 115: goto tr22;
+ case 117: goto tr22;
+ case 120: goto tr22;
+ }
+ if ( (*p) > 100 ) {
+ if ( 111 <= (*p) && (*p) <= 112 )
+ goto tr22;
+ } else if ( (*p) >= 99 )
+ goto tr22;
+ goto tr0;
+tr23:
+#line 88 "format.rl"
+ { fsm->flags |= FL_LEN_HH; }
+ goto st7;
+tr25:
+#line 89 "format.rl"
+ { fsm->flags |= FL_LEN_LL; }
+ goto st7;
+st7:
+ if ( ++p == pe )
+ goto _test_eof7;
+case 7:
+#line 361 "format.c"
+ switch( (*p) ) {
+ case 88: goto tr10;
+ case 105: goto tr10;
+ case 115: goto tr10;
+ case 117: goto tr10;
+ case 120: goto tr10;
+ }
+ if ( (*p) > 100 ) {
+ if ( 111 <= (*p) && (*p) <= 112 )
+ goto tr10;
+ } else if ( (*p) >= 99 )
+ goto tr10;
+ goto tr0;
+tr16:
+#line 63 "format.rl"
+ { fsm->flags |= FL_HAS_WIDTH; }
+ goto st8;
+tr21:
+#line 69 "format.rl"
+ { fsm->flags |= FL_HAS_PREC; }
+ goto st8;
+st8:
+ if ( ++p == pe )
+ goto _test_eof8;
+case 8:
+#line 387 "format.c"
+ switch( (*p) ) {
+ case 88: goto tr24;
+ case 105: goto tr24;
+ case 108: goto tr25;
+ case 115: goto tr24;
+ case 117: goto tr24;
+ case 120: goto tr24;
+ }
+ if ( (*p) > 100 ) {
+ if ( 111 <= (*p) && (*p) <= 112 )
+ goto tr24;
+ } else if ( (*p) >= 99 )
+ goto tr24;
+ goto tr0;
+tr18:
+#line 67 "format.rl"
+ { fsm->prec = 10 * fsm->prec + ((*p)-'0'); }
+ goto st9;
+st9:
+ if ( ++p == pe )
+ goto _test_eof9;
+case 9:
+#line 410 "format.c"
+ switch( (*p) ) {
+ case 88: goto tr19;
+ case 104: goto tr20;
+ case 105: goto tr19;
+ case 108: goto tr21;
+ case 115: goto tr19;
+ case 117: goto tr19;
+ case 120: goto tr19;
+ }
+ if ( (*p) < 99 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr18;
+ } else if ( (*p) > 100 ) {
+ if ( 111 <= (*p) && (*p) <= 112 )
+ goto tr19;
+ } else
+ goto tr19;
+ goto tr0;
+tr9:
+#line 61 "format.rl"
+ { fsm->width = 10 * fsm->width + ((*p)-'0'); }
+ goto st10;
+st10:
+ if ( ++p == pe )
+ goto _test_eof10;
+case 10:
+#line 437 "format.c"
+ switch( (*p) ) {
+ case 46: goto tr13;
+ case 88: goto tr14;
+ case 104: goto tr15;
+ case 105: goto tr14;
+ case 108: goto tr16;
+ case 115: goto tr14;
+ case 117: goto tr14;
+ case 120: goto tr14;
+ }
+ if ( (*p) < 99 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr9;
+ } else if ( (*p) > 100 ) {
+ if ( 111 <= (*p) && (*p) <= 112 )
+ goto tr14;
+ } else
+ goto tr14;
+ goto tr0;
+ }
+ _test_eof11: fsm->cs = 11; goto _test_eof;
+ _test_eof1: fsm->cs = 1; goto _test_eof;
+ _test_eof2: fsm->cs = 2; goto _test_eof;
+ _test_eof3: fsm->cs = 3; goto _test_eof;
+ _test_eof4: fsm->cs = 4; goto _test_eof;
+ _test_eof5: fsm->cs = 5; goto _test_eof;
+ _test_eof6: fsm->cs = 6; goto _test_eof;
+ _test_eof7: fsm->cs = 7; goto _test_eof;
+ _test_eof8: fsm->cs = 8; goto _test_eof;
+ _test_eof9: fsm->cs = 9; goto _test_eof;
+ _test_eof10: fsm->cs = 10; goto _test_eof;
+
+ _test_eof: {}
+ if ( p == eof )
+ {
+ switch ( fsm->cs ) {
+ case 11:
+#line 121 "format.rl"
+ {
+ if ( fsm->buflen > 0 )
+ fsm->write( fsm->buf, fsm->buflen );
+ }
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+#line 125 "format.rl"
+ {
+ printf("EOF IN FORMAT\n");
+ }
+#line 128 "format.rl"
+ {
+ printf("ERROR ON CHAR: 0x%x\n", (*p) );
+ }
+ break;
+#line 500 "format.c"
+ }
+ }
+
+ _out: {}
+ }
+
+#line 154 "format.rl"
+}
+
+int format_finish( struct format *fsm )
+{
+ if ( fsm->cs == format_error )
+ return -1;
+ if ( fsm->cs >= format_first_final )
+ return 1;
+ return 0;
+}
+
+
+#define INPUT_BUFSIZE 2048
+
+struct format fsm;
+char buf[INPUT_BUFSIZE];
+
+void write(char *data, int len )
+{
+ fwrite( data, 1, len, stdout );
+}
+
+int main()
+{
+ fsm.write = write;
+ format_init( &fsm );
+ while ( 1 ) {
+ int len = fread( buf, 1, INPUT_BUFSIZE, stdin );
+ int eof = len != INPUT_BUFSIZE;
+ format_execute( &fsm, buf, len, eof );
+ if ( eof )
+ break;
+ }
+ if ( format_finish( &fsm ) <= 0 )
+ printf("FAIL\n");
+ return 0;
+}
+
diff --git a/examples/format.rl b/examples/format.rl
new file mode 100644
index 0000000..f8a37be
--- /dev/null
+++ b/examples/format.rl
@@ -0,0 +1,191 @@
+/*
+ * Partial printf implementation.
+ */
+
+#define BUFLEN 1024
+#include <stdio.h>
+
+typedef void (*WriteFunc)( char *data, int len );
+
+struct format
+{
+ char buf[BUFLEN+1];
+ int buflen;
+ WriteFunc write;
+
+ int flags;
+ int width;
+ int prec;
+ int cs;
+};
+
+void do_conv( struct format *fsm, char c )
+{
+ printf( "flags: %x\n", fsm->flags );
+ printf( "width: %i\n", fsm->width );
+ printf( "prec: %i\n", fsm->prec );
+ printf( "conv: %c\n", c );
+ printf( "\n" );
+}
+
+#define FL_HASH 0x01
+#define FL_ZERO 0x02
+#define FL_DASH 0x04
+#define FL_SPACE 0x08
+#define FL_PLUS 0x10
+
+#define FL_HAS_WIDTH 0x0100
+#define FL_WIDTH_ARG 0x0200
+#define FL_HAS_PREC 0x0400
+#define FL_PREC_ARG 0x0800
+
+#define FL_LEN_H 0x010000
+#define FL_LEN_HH 0x020000
+#define FL_LEN_L 0x040000
+#define FL_LEN_LL 0x080000
+
+%%{
+ machine format;
+ access fsm->;
+
+ action clear {
+ fsm->flags = 0;
+ fsm->width = 0;
+ fsm->prec = 0;
+ }
+
+ # A non-zero number.
+ nznum = [1-9] [0-9]*;
+
+ # Width
+ action width_num { fsm->width = 10 * fsm->width + (fc-'0'); }
+ action width_arg { fsm->flags |= FL_WIDTH_ARG; }
+ action width { fsm->flags |= FL_HAS_WIDTH; }
+ width = ( ( nznum $width_num | '*' @width_arg ) %width )?;
+
+ # Precision
+ action prec_num { fsm->prec = 10 * fsm->prec + (fc-'0'); }
+ action prec_arg { fsm->flags |= FL_PREC_ARG; }
+ action prec { fsm->flags |= FL_HAS_PREC; }
+ precision = ( '.' ( digit* $prec_num %prec | '*' @prec_arg ) )?;
+
+ # Flags
+ action flags_hash { fsm->flags |= FL_HASH; }
+ action flags_zero { fsm->flags |= FL_ZERO; }
+ action flags_dash { fsm->flags |= FL_DASH; }
+ action flags_space { fsm->flags |= FL_SPACE; }
+ action flags_plus { fsm->flags |= FL_PLUS; }
+
+ flags = (
+ '#' @flags_hash |
+ '0' @flags_zero |
+ '-' @flags_dash |
+ ' ' @flags_space |
+ '+' @flags_plus )*;
+
+ action length_h { fsm->flags |= FL_LEN_H; }
+ action length_l { fsm->flags |= FL_LEN_L; }
+ action length_hh { fsm->flags |= FL_LEN_HH; }
+ action length_ll { fsm->flags |= FL_LEN_LL; }
+
+ # Must use leaving transitions on 'h' and 'l' because they are
+ # prefixes for 'hh' and 'll'.
+ length = (
+ 'h' %length_h |
+ 'l' %length_l |
+ 'hh' @length_hh |
+ 'll' @length_ll )?;
+
+ action conversion {
+ do_conv( fsm, fc );
+ }
+
+ conversion = [diouxXcsp] @conversion;
+
+ fmt_spec =
+ '%' @clear
+ flags
+ width
+ precision
+ length
+ conversion;
+
+ action emit {
+ if ( fsm->buflen == BUFLEN ) {
+ fsm->write( fsm->buf, fsm->buflen );
+ fsm->buflen = 0;
+ }
+ fsm->buf[fsm->buflen++] = fc;
+ }
+
+ action finish_ok {
+ if ( fsm->buflen > 0 )
+ fsm->write( fsm->buf, fsm->buflen );
+ }
+ action finish_err {
+ printf("EOF IN FORMAT\n");
+ }
+ action err_char {
+ printf("ERROR ON CHAR: 0x%x\n", fc );
+ }
+
+ main := (
+ [^%] @emit |
+ '%%' @emit |
+ fmt_spec
+ )* @/finish_err %/finish_ok $!err_char;
+}%%
+
+%% write data;
+
+void format_init( struct format *fsm )
+{
+ fsm->buflen = 0;
+ %% write init;
+}
+
+void format_execute( struct format *fsm, const char *data, int len, int isEof )
+{
+ const char *p = data;
+ const char *pe = data + len;
+ const char *eof = isEof ? pe : 0;
+
+ %% write exec;
+}
+
+int format_finish( struct format *fsm )
+{
+ if ( fsm->cs == format_error )
+ return -1;
+ if ( fsm->cs >= format_first_final )
+ return 1;
+ return 0;
+}
+
+
+#define INPUT_BUFSIZE 2048
+
+struct format fsm;
+char buf[INPUT_BUFSIZE];
+
+void write(char *data, int len )
+{
+ fwrite( data, 1, len, stdout );
+}
+
+int main()
+{
+ fsm.write = write;
+ format_init( &fsm );
+ while ( 1 ) {
+ int len = fread( buf, 1, INPUT_BUFSIZE, stdin );
+ int eof = len != INPUT_BUFSIZE;
+ format_execute( &fsm, buf, len, eof );
+ if ( eof )
+ break;
+ }
+ if ( format_finish( &fsm ) <= 0 )
+ printf("FAIL\n");
+ return 0;
+}
+
diff --git a/examples/gotocallret.cpp b/examples/gotocallret.cpp
new file mode 100644
index 0000000..18a9531
--- /dev/null
+++ b/examples/gotocallret.cpp
@@ -0,0 +1,282 @@
+
+#line 1 "gotocallret.rl"
+/*
+ * Demonstrate the use of goto, call and return. This machine expects either a
+ * lower case char or a digit as a command then a space followed by the command
+ * arg. If the command is a char, then the arg must be an a string of chars.
+ * If the command is a digit, then the arg must be a string of digits. This
+ * choice is determined by action code, rather than though transition
+ * desitinations.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+using namespace std;
+
+struct GotoCallRet
+{
+ char comm;
+ int cs, top, stack[32];
+
+ int init( );
+ int execute( const char *data, int len, bool isEof );
+ int finish( );
+};
+
+
+#line 57 "gotocallret.rl"
+
+
+
+#line 35 "gotocallret.cpp"
+static const int GotoCallRet_start = 7;
+static const int GotoCallRet_first_final = 7;
+static const int GotoCallRet_error = 0;
+
+static const int GotoCallRet_en_garble_line = 3;
+static const int GotoCallRet_en_alp_comm = 5;
+static const int GotoCallRet_en_dig_comm = 6;
+static const int GotoCallRet_en_main = 7;
+
+
+#line 60 "gotocallret.rl"
+
+int GotoCallRet::init( )
+{
+
+#line 51 "gotocallret.cpp"
+ {
+ cs = GotoCallRet_start;
+ top = 0;
+ }
+
+#line 64 "gotocallret.rl"
+ return 1;
+}
+
+int GotoCallRet::execute( const char *data, int len, bool isEof )
+{
+ const char *p = data;
+ const char *pe = data + len;
+ const char *eof = isEof ? pe : 0;
+
+
+#line 68 "gotocallret.cpp"
+ {
+ if ( p == pe )
+ goto _test_eof;
+ goto _resume;
+
+_again:
+ switch ( cs ) {
+ case 7: goto st7;
+ case 0: goto st0;
+ case 1: goto st1;
+ case 2: goto st2;
+ case 3: goto st3;
+ case 4: goto st4;
+ case 8: goto st8;
+ case 5: goto st5;
+ case 9: goto st9;
+ case 6: goto st6;
+ case 10: goto st10;
+ default: break;
+ }
+
+ if ( ++p == pe )
+ goto _test_eof;
+_resume:
+ switch ( cs )
+ {
+tr2:
+#line 52 "gotocallret.rl"
+ {cout << "correct command" << endl;}
+ goto st7;
+st7:
+ if ( ++p == pe )
+ goto _test_eof7;
+case 7:
+#line 103 "gotocallret.cpp"
+ if ( (*p) > 57 ) {
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto tr11;
+ } else if ( (*p) >= 48 )
+ goto tr11;
+ goto tr0;
+tr0:
+#line 56 "gotocallret.rl"
+ {p--;{goto st3;}}
+ goto st0;
+tr7:
+#line 38 "gotocallret.rl"
+ {p--;{cs = stack[--top];goto _again;}}
+ goto st0;
+tr9:
+#line 39 "gotocallret.rl"
+ {p--;{cs = stack[--top];goto _again;}}
+ goto st0;
+#line 122 "gotocallret.cpp"
+st0:
+cs = 0;
+ goto _out;
+tr11:
+#line 51 "gotocallret.rl"
+ {comm = (*p);}
+ goto st1;
+st1:
+ if ( ++p == pe )
+ goto _test_eof1;
+case 1:
+#line 134 "gotocallret.cpp"
+ if ( (*p) == 32 )
+ goto tr1;
+ goto tr0;
+tr1:
+#line 42 "gotocallret.rl"
+ {
+ if ( comm >= 'a' )
+ {stack[top++] = 2; goto st5;}
+ else
+ {stack[top++] = 2; goto st6;}
+ }
+ goto st2;
+st2:
+ if ( ++p == pe )
+ goto _test_eof2;
+case 2:
+#line 151 "gotocallret.cpp"
+ if ( (*p) == 10 )
+ goto tr2;
+ goto tr0;
+st3:
+ if ( ++p == pe )
+ goto _test_eof3;
+case 3:
+ if ( (*p) == 10 )
+ goto tr4;
+ goto tr3;
+tr3:
+#line 34 "gotocallret.rl"
+ {cout << "error: garbling line" << endl;}
+ goto st4;
+st4:
+ if ( ++p == pe )
+ goto _test_eof4;
+case 4:
+#line 170 "gotocallret.cpp"
+ if ( (*p) == 10 )
+ goto tr6;
+ goto st4;
+tr4:
+#line 34 "gotocallret.rl"
+ {cout << "error: garbling line" << endl;}
+#line 34 "gotocallret.rl"
+ {{goto st7;}}
+ goto st8;
+tr6:
+#line 34 "gotocallret.rl"
+ {{goto st7;}}
+ goto st8;
+st8:
+ if ( ++p == pe )
+ goto _test_eof8;
+case 8:
+#line 188 "gotocallret.cpp"
+ goto st0;
+st5:
+ if ( ++p == pe )
+ goto _test_eof5;
+case 5:
+ if ( (*p) > 90 ) {
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st9;
+ } else if ( (*p) >= 65 )
+ goto st9;
+ goto tr7;
+st9:
+ if ( ++p == pe )
+ goto _test_eof9;
+case 9:
+ if ( (*p) > 90 ) {
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st9;
+ } else if ( (*p) >= 65 )
+ goto st9;
+ goto tr7;
+st6:
+ if ( ++p == pe )
+ goto _test_eof6;
+case 6:
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st10;
+ goto tr9;
+st10:
+ if ( ++p == pe )
+ goto _test_eof10;
+case 10:
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st10;
+ goto tr9;
+ }
+ _test_eof7: cs = 7; goto _test_eof;
+ _test_eof1: cs = 1; goto _test_eof;
+ _test_eof2: cs = 2; goto _test_eof;
+ _test_eof3: cs = 3; goto _test_eof;
+ _test_eof4: cs = 4; goto _test_eof;
+ _test_eof8: cs = 8; goto _test_eof;
+ _test_eof5: cs = 5; goto _test_eof;
+ _test_eof9: cs = 9; goto _test_eof;
+ _test_eof6: cs = 6; goto _test_eof;
+ _test_eof10: cs = 10; goto _test_eof;
+
+ _test_eof: {}
+ if ( p == eof )
+ {
+ switch ( cs ) {
+ case 5:
+#line 38 "gotocallret.rl"
+ {p--;{cs = stack[--top];goto _again;}}
+ break;
+ case 6:
+#line 39 "gotocallret.rl"
+ {p--;{cs = stack[--top];goto _again;}}
+ break;
+ case 1:
+ case 2:
+#line 56 "gotocallret.rl"
+ {p--;{goto st3;}}
+ break;
+#line 253 "gotocallret.cpp"
+ }
+ }
+
+ _out: {}
+ }
+
+#line 74 "gotocallret.rl"
+ if ( cs == GotoCallRet_error )
+ return -1;
+ if ( cs >= GotoCallRet_first_final )
+ return 1;
+ return 0;
+}
+
+#define BUFSIZE 1024
+
+int main()
+{
+ char buf[BUFSIZE];
+
+ GotoCallRet gcr;
+ gcr.init();
+ while ( fgets( buf, sizeof(buf), stdin ) != 0 )
+ gcr.execute( buf, strlen(buf), false );
+
+ gcr.execute( 0, 0, true );
+ if ( gcr.cs < GotoCallRet_first_final )
+ cerr << "gotocallret: error: parsing input" << endl;
+ return 0;
+}
diff --git a/examples/gotocallret.rl b/examples/gotocallret.rl
new file mode 100644
index 0000000..32c01a2
--- /dev/null
+++ b/examples/gotocallret.rl
@@ -0,0 +1,96 @@
+/*
+ * Demonstrate the use of goto, call and return. This machine expects either a
+ * lower case char or a digit as a command then a space followed by the command
+ * arg. If the command is a char, then the arg must be an a string of chars.
+ * If the command is a digit, then the arg must be a string of digits. This
+ * choice is determined by action code, rather than though transition
+ * desitinations.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+using namespace std;
+
+struct GotoCallRet
+{
+ char comm;
+ int cs, top, stack[32];
+
+ int init( );
+ int execute( const char *data, int len, bool isEof );
+ int finish( );
+};
+
+%%{
+ machine GotoCallRet;
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := (
+ (any-'\n')*'\n'
+ ) >{cout << "error: garbling line" << endl;} @{fgoto main;};
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!{fhold;fret;};
+ dig_comm := digit+ $!{fhold;fret;};
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {
+ if ( comm >= 'a' )
+ fcall alp_comm;
+ else
+ fcall dig_comm;
+ }
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;} ' ' @comm_arg '\n'
+ ) @{cout << "correct command" << endl;};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fgoto garble_line;};
+}%%
+
+%% write data;
+
+int GotoCallRet::init( )
+{
+ %% write init;
+ return 1;
+}
+
+int GotoCallRet::execute( const char *data, int len, bool isEof )
+{
+ const char *p = data;
+ const char *pe = data + len;
+ const char *eof = isEof ? pe : 0;
+
+ %% write exec;
+ if ( cs == GotoCallRet_error )
+ return -1;
+ if ( cs >= GotoCallRet_first_final )
+ return 1;
+ return 0;
+}
+
+#define BUFSIZE 1024
+
+int main()
+{
+ char buf[BUFSIZE];
+
+ GotoCallRet gcr;
+ gcr.init();
+ while ( fgets( buf, sizeof(buf), stdin ) != 0 )
+ gcr.execute( buf, strlen(buf), false );
+
+ gcr.execute( 0, 0, true );
+ if ( gcr.cs < GotoCallRet_first_final )
+ cerr << "gotocallret: error: parsing input" << endl;
+ return 0;
+}
diff --git a/examples/mailbox.cpp b/examples/mailbox.cpp
new file mode 100644
index 0000000..7e9c46e
--- /dev/null
+++ b/examples/mailbox.cpp
@@ -0,0 +1,1563 @@
+
+#line 1 "mailbox.rl"
+/*
+ * Parses unix mail boxes into headers and bodies.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+using namespace std;
+
+#define BUFSIZE 2048
+
+/* A growable buffer for collecting headers. */
+struct Buffer
+{
+ Buffer() : data(0), allocated(0), length(0) { }
+ ~Buffer() { empty(); }
+
+ void append( char p ) {
+ if ( ++length > allocated )
+ upAllocate( length*2 );
+ data[length-1] = p;
+ }
+
+ void clear() { length = 0; }
+ void upAllocate( int len );
+ void empty();
+
+ char *data;
+ int allocated;
+ int length;
+};
+
+
+struct MailboxScanner
+{
+ Buffer headName;
+ Buffer headContent;
+
+ int cs, top, stack[1];
+
+ int init( );
+ int execute( const char *data, int len, bool isEof );
+ int finish( );
+};
+
+
+#line 137 "mailbox.rl"
+
+
+
+#line 56 "mailbox.cpp"
+static const int MailboxScanner_start = 100;
+static const int MailboxScanner_first_final = 100;
+static const int MailboxScanner_error = 0;
+
+static const int MailboxScanner_en_consumeHeader = 102;
+static const int MailboxScanner_en_printHeader = 103;
+static const int MailboxScanner_en_main = 100;
+
+
+#line 140 "mailbox.rl"
+
+int MailboxScanner::init( )
+{
+
+#line 71 "mailbox.cpp"
+ {
+ cs = MailboxScanner_start;
+ top = 0;
+ }
+
+#line 144 "mailbox.rl"
+ return 1;
+}
+
+int MailboxScanner::execute( const char *data, int len, bool isEof )
+{
+ const char *p = data;
+ const char *pe = data + len;
+ const char *eof = isEof ? pe : 0;
+
+
+#line 88 "mailbox.cpp"
+ {
+ if ( p == pe )
+ goto _test_eof;
+ goto _resume;
+
+_again:
+ switch ( cs ) {
+ case 100: goto st100;
+ case 0: goto st0;
+ case 1: goto st1;
+ case 2: goto st2;
+ case 3: goto st3;
+ case 4: goto st4;
+ case 5: goto st5;
+ case 6: goto st6;
+ case 7: goto st7;
+ case 8: goto st8;
+ case 9: goto st9;
+ case 10: goto st10;
+ case 11: goto st11;
+ case 12: goto st12;
+ case 13: goto st13;
+ case 14: goto st14;
+ case 15: goto st15;
+ case 16: goto st16;
+ case 17: goto st17;
+ case 18: goto st18;
+ case 19: goto st19;
+ case 20: goto st20;
+ case 21: goto st21;
+ case 22: goto st22;
+ case 23: goto st23;
+ case 24: goto st24;
+ case 25: goto st25;
+ case 26: goto st26;
+ case 27: goto st27;
+ case 28: goto st28;
+ case 29: goto st29;
+ case 30: goto st30;
+ case 31: goto st31;
+ case 32: goto st32;
+ case 33: goto st33;
+ case 34: goto st34;
+ case 101: goto st101;
+ case 35: goto st35;
+ case 36: goto st36;
+ case 37: goto st37;
+ case 38: goto st38;
+ case 39: goto st39;
+ case 40: goto st40;
+ case 41: goto st41;
+ case 42: goto st42;
+ case 43: goto st43;
+ case 44: goto st44;
+ case 45: goto st45;
+ case 46: goto st46;
+ case 47: goto st47;
+ case 48: goto st48;
+ case 49: goto st49;
+ case 50: goto st50;
+ case 51: goto st51;
+ case 52: goto st52;
+ case 53: goto st53;
+ case 54: goto st54;
+ case 55: goto st55;
+ case 56: goto st56;
+ case 57: goto st57;
+ case 58: goto st58;
+ case 59: goto st59;
+ case 60: goto st60;
+ case 61: goto st61;
+ case 62: goto st62;
+ case 63: goto st63;
+ case 64: goto st64;
+ case 65: goto st65;
+ case 66: goto st66;
+ case 67: goto st67;
+ case 68: goto st68;
+ case 69: goto st69;
+ case 70: goto st70;
+ case 71: goto st71;
+ case 72: goto st72;
+ case 73: goto st73;
+ case 74: goto st74;
+ case 75: goto st75;
+ case 76: goto st76;
+ case 77: goto st77;
+ case 78: goto st78;
+ case 79: goto st79;
+ case 80: goto st80;
+ case 81: goto st81;
+ case 82: goto st82;
+ case 83: goto st83;
+ case 84: goto st84;
+ case 85: goto st85;
+ case 86: goto st86;
+ case 87: goto st87;
+ case 88: goto st88;
+ case 89: goto st89;
+ case 90: goto st90;
+ case 91: goto st91;
+ case 92: goto st92;
+ case 93: goto st93;
+ case 94: goto st94;
+ case 95: goto st95;
+ case 96: goto st96;
+ case 97: goto st97;
+ case 102: goto st102;
+ case 98: goto st98;
+ case 103: goto st103;
+ case 99: goto st99;
+ case 104: goto st104;
+ default: break;
+ }
+
+ if ( ++p == pe )
+ goto _test_eof;
+_resume:
+ switch ( cs )
+ {
+st100:
+ if ( ++p == pe )
+ goto _test_eof100;
+case 100:
+ if ( (*p) == 70 )
+ goto st1;
+ goto st0;
+tr101:
+#line 92 "mailbox.rl"
+ {
+ headContent.append(0);
+ cout << headContent.data << endl;
+ headContent.clear();
+ p--;
+ {cs = stack[--top];goto _again;}
+ }
+ goto st0;
+#line 226 "mailbox.cpp"
+st0:
+cs = 0;
+ goto _out;
+st1:
+ if ( ++p == pe )
+ goto _test_eof1;
+case 1:
+ if ( (*p) == 114 )
+ goto st2;
+ goto st0;
+st2:
+ if ( ++p == pe )
+ goto _test_eof2;
+case 2:
+ if ( (*p) == 111 )
+ goto st3;
+ goto st0;
+st3:
+ if ( ++p == pe )
+ goto _test_eof3;
+case 3:
+ if ( (*p) == 109 )
+ goto st4;
+ goto st0;
+st4:
+ if ( ++p == pe )
+ goto _test_eof4;
+case 4:
+ if ( (*p) == 32 )
+ goto st5;
+ goto st0;
+st5:
+ if ( ++p == pe )
+ goto _test_eof5;
+case 5:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ goto st5;
+st6:
+ if ( ++p == pe )
+ goto _test_eof6;
+case 6:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st7;
+ goto st5;
+st7:
+ if ( ++p == pe )
+ goto _test_eof7;
+case 7:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st8;
+ goto st5;
+st8:
+ if ( ++p == pe )
+ goto _test_eof8;
+case 8:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st9;
+ goto st5;
+st9:
+ if ( ++p == pe )
+ goto _test_eof9;
+case 9:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st10;
+ }
+ goto st5;
+st10:
+ if ( ++p == pe )
+ goto _test_eof10;
+case 10:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st11;
+ goto st5;
+st11:
+ if ( ++p == pe )
+ goto _test_eof11;
+case 11:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st12;
+ goto st5;
+st12:
+ if ( ++p == pe )
+ goto _test_eof12;
+case 12:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st13;
+ goto st5;
+st13:
+ if ( ++p == pe )
+ goto _test_eof13;
+case 13:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st14;
+ }
+ goto st5;
+st14:
+ if ( ++p == pe )
+ goto _test_eof14;
+case 14:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st15;
+ }
+ if ( (*p) > 57 ) {
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st11;
+ } else if ( (*p) >= 48 )
+ goto st97;
+ goto st5;
+st15:
+ if ( ++p == pe )
+ goto _test_eof15;
+case 15:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( (*p) > 57 ) {
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st7;
+ } else if ( (*p) >= 48 )
+ goto st16;
+ goto st5;
+st16:
+ if ( ++p == pe )
+ goto _test_eof16;
+case 16:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st17;
+ }
+ goto st5;
+st17:
+ if ( ++p == pe )
+ goto _test_eof17;
+case 17:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( (*p) > 57 ) {
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st7;
+ } else if ( (*p) >= 48 )
+ goto st18;
+ goto st5;
+st18:
+ if ( ++p == pe )
+ goto _test_eof18;
+case 18:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st19;
+ goto st5;
+st19:
+ if ( ++p == pe )
+ goto _test_eof19;
+case 19:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ case 58: goto st20;
+ }
+ goto st5;
+st20:
+ if ( ++p == pe )
+ goto _test_eof20;
+case 20:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st21;
+ goto st5;
+st21:
+ if ( ++p == pe )
+ goto _test_eof21;
+case 21:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st22;
+ goto st5;
+st22:
+ if ( ++p == pe )
+ goto _test_eof22;
+case 22:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st23;
+ case 58: goto st94;
+ }
+ goto st5;
+st23:
+ if ( ++p == pe )
+ goto _test_eof23;
+case 23:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ case 43: goto st24;
+ case 45: goto st24;
+ }
+ if ( (*p) > 57 ) {
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st92;
+ } else if ( (*p) >= 48 )
+ goto st84;
+ goto st5;
+st24:
+ if ( ++p == pe )
+ goto _test_eof24;
+case 24:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st25;
+ goto st5;
+st25:
+ if ( ++p == pe )
+ goto _test_eof25;
+case 25:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st26;
+ goto st5;
+st26:
+ if ( ++p == pe )
+ goto _test_eof26;
+case 26:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st27;
+ goto st5;
+st27:
+ if ( ++p == pe )
+ goto _test_eof27;
+case 27:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st28;
+ goto st5;
+st28:
+ if ( ++p == pe )
+ goto _test_eof28;
+case 28:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st29;
+ }
+ goto st5;
+st29:
+ if ( ++p == pe )
+ goto _test_eof29;
+case 29:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( (*p) > 57 ) {
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st7;
+ } else if ( (*p) >= 48 )
+ goto st30;
+ goto st5;
+st30:
+ if ( ++p == pe )
+ goto _test_eof30;
+case 30:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st31;
+ goto st5;
+st31:
+ if ( ++p == pe )
+ goto _test_eof31;
+case 31:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st32;
+ goto st5;
+st32:
+ if ( ++p == pe )
+ goto _test_eof32;
+case 32:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st33;
+ goto st5;
+st33:
+ if ( ++p == pe )
+ goto _test_eof33;
+case 33:
+ switch( (*p) ) {
+ case 10: goto st34;
+ case 32: goto st6;
+ }
+ goto st5;
+tr88:
+#line 108 "mailbox.rl"
+ {
+ headName.append(0);
+ if ( strcmp( headName.data, "From" ) == 0 ||
+ strcmp( headName.data, "To" ) == 0 ||
+ strcmp( headName.data, "Subject" ) == 0 )
+ {
+ /* Print the header name, then jump to a machine the will display
+ * the contents. */
+ cout << headName.data << ":";
+ headName.clear();
+ {stack[top++] = 34; goto st103;}
+ }
+
+ headName.clear();
+ {stack[top++] = 34; goto st102;}
+ }
+ goto st34;
+st34:
+ if ( ++p == pe )
+ goto _test_eof34;
+case 34:
+#line 603 "mailbox.cpp"
+ if ( (*p) == 10 )
+ goto tr38;
+ if ( (*p) > 57 ) {
+ if ( 59 <= (*p) && (*p) <= 126 )
+ goto tr39;
+ } else if ( (*p) >= 33 )
+ goto tr39;
+ goto st0;
+tr38:
+#line 55 "mailbox.rl"
+ { cout << endl; }
+ goto st101;
+st101:
+ if ( ++p == pe )
+ goto _test_eof101;
+case 101:
+#line 620 "mailbox.cpp"
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 70: goto st36;
+ }
+ goto st35;
+st35:
+ if ( ++p == pe )
+ goto _test_eof35;
+case 35:
+ if ( (*p) == 10 )
+ goto st101;
+ goto st35;
+st36:
+ if ( ++p == pe )
+ goto _test_eof36;
+case 36:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 114: goto st37;
+ }
+ goto st35;
+st37:
+ if ( ++p == pe )
+ goto _test_eof37;
+case 37:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 111: goto st38;
+ }
+ goto st35;
+st38:
+ if ( ++p == pe )
+ goto _test_eof38;
+case 38:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 109: goto st39;
+ }
+ goto st35;
+st39:
+ if ( ++p == pe )
+ goto _test_eof39;
+case 39:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st40;
+ }
+ goto st35;
+st40:
+ if ( ++p == pe )
+ goto _test_eof40;
+case 40:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ goto st40;
+st41:
+ if ( ++p == pe )
+ goto _test_eof41;
+case 41:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st42;
+ goto st40;
+st42:
+ if ( ++p == pe )
+ goto _test_eof42;
+case 42:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st43;
+ goto st40;
+st43:
+ if ( ++p == pe )
+ goto _test_eof43;
+case 43:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st44;
+ goto st40;
+st44:
+ if ( ++p == pe )
+ goto _test_eof44;
+case 44:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st45;
+ }
+ goto st40;
+st45:
+ if ( ++p == pe )
+ goto _test_eof45;
+case 45:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st46;
+ goto st40;
+st46:
+ if ( ++p == pe )
+ goto _test_eof46;
+case 46:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st47;
+ goto st40;
+st47:
+ if ( ++p == pe )
+ goto _test_eof47;
+case 47:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st48;
+ goto st40;
+st48:
+ if ( ++p == pe )
+ goto _test_eof48;
+case 48:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st49;
+ }
+ goto st40;
+st49:
+ if ( ++p == pe )
+ goto _test_eof49;
+case 49:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st50;
+ }
+ if ( (*p) > 57 ) {
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st46;
+ } else if ( (*p) >= 48 )
+ goto st82;
+ goto st40;
+st50:
+ if ( ++p == pe )
+ goto _test_eof50;
+case 50:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( (*p) > 57 ) {
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st42;
+ } else if ( (*p) >= 48 )
+ goto st51;
+ goto st40;
+st51:
+ if ( ++p == pe )
+ goto _test_eof51;
+case 51:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st52;
+ }
+ goto st40;
+st52:
+ if ( ++p == pe )
+ goto _test_eof52;
+case 52:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( (*p) > 57 ) {
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st42;
+ } else if ( (*p) >= 48 )
+ goto st53;
+ goto st40;
+st53:
+ if ( ++p == pe )
+ goto _test_eof53;
+case 53:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st54;
+ goto st40;
+st54:
+ if ( ++p == pe )
+ goto _test_eof54;
+case 54:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ case 58: goto st55;
+ }
+ goto st40;
+st55:
+ if ( ++p == pe )
+ goto _test_eof55;
+case 55:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st56;
+ goto st40;
+st56:
+ if ( ++p == pe )
+ goto _test_eof56;
+case 56:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st57;
+ goto st40;
+st57:
+ if ( ++p == pe )
+ goto _test_eof57;
+case 57:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st58;
+ case 58: goto st79;
+ }
+ goto st40;
+st58:
+ if ( ++p == pe )
+ goto _test_eof58;
+case 58:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ case 43: goto st59;
+ case 45: goto st59;
+ }
+ if ( (*p) > 57 ) {
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st77;
+ } else if ( (*p) >= 48 )
+ goto st69;
+ goto st40;
+st59:
+ if ( ++p == pe )
+ goto _test_eof59;
+case 59:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st60;
+ goto st40;
+st60:
+ if ( ++p == pe )
+ goto _test_eof60;
+case 60:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st61;
+ goto st40;
+st61:
+ if ( ++p == pe )
+ goto _test_eof61;
+case 61:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st62;
+ goto st40;
+st62:
+ if ( ++p == pe )
+ goto _test_eof62;
+case 62:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st63;
+ goto st40;
+st63:
+ if ( ++p == pe )
+ goto _test_eof63;
+case 63:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st64;
+ }
+ goto st40;
+st64:
+ if ( ++p == pe )
+ goto _test_eof64;
+case 64:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( (*p) > 57 ) {
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st42;
+ } else if ( (*p) >= 48 )
+ goto st65;
+ goto st40;
+st65:
+ if ( ++p == pe )
+ goto _test_eof65;
+case 65:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st66;
+ goto st40;
+st66:
+ if ( ++p == pe )
+ goto _test_eof66;
+case 66:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st67;
+ goto st40;
+st67:
+ if ( ++p == pe )
+ goto _test_eof67;
+case 67:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st68;
+ goto st40;
+st68:
+ if ( ++p == pe )
+ goto _test_eof68;
+case 68:
+ switch( (*p) ) {
+ case 10: goto st34;
+ case 32: goto st41;
+ }
+ goto st40;
+st69:
+ if ( ++p == pe )
+ goto _test_eof69;
+case 69:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st70;
+ goto st40;
+st70:
+ if ( ++p == pe )
+ goto _test_eof70;
+case 70:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st71;
+ goto st40;
+st71:
+ if ( ++p == pe )
+ goto _test_eof71;
+case 71:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st72;
+ goto st40;
+st72:
+ if ( ++p == pe )
+ goto _test_eof72;
+case 72:
+ switch( (*p) ) {
+ case 10: goto st34;
+ case 32: goto st73;
+ }
+ goto st40;
+st73:
+ if ( ++p == pe )
+ goto _test_eof73;
+case 73:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ case 43: goto st74;
+ case 45: goto st74;
+ }
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st75;
+ goto st40;
+st74:
+ if ( ++p == pe )
+ goto _test_eof74;
+case 74:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st65;
+ goto st40;
+st75:
+ if ( ++p == pe )
+ goto _test_eof75;
+case 75:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( (*p) > 90 ) {
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st43;
+ } else if ( (*p) >= 65 )
+ goto st76;
+ goto st40;
+st76:
+ if ( ++p == pe )
+ goto _test_eof76;
+case 76:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st68;
+ goto st40;
+st77:
+ if ( ++p == pe )
+ goto _test_eof77;
+case 77:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( (*p) > 90 ) {
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st43;
+ } else if ( (*p) >= 65 )
+ goto st78;
+ goto st40;
+st78:
+ if ( ++p == pe )
+ goto _test_eof78;
+case 78:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st63;
+ goto st40;
+st79:
+ if ( ++p == pe )
+ goto _test_eof79;
+case 79:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st80;
+ goto st40;
+st80:
+ if ( ++p == pe )
+ goto _test_eof80;
+case 80:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st81;
+ goto st40;
+st81:
+ if ( ++p == pe )
+ goto _test_eof81;
+case 81:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st58;
+ }
+ goto st40;
+st82:
+ if ( ++p == pe )
+ goto _test_eof82;
+case 82:
+ switch( (*p) ) {
+ case 10: goto st101;
+ case 32: goto st41;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st51;
+ goto st40;
+tr39:
+#line 52 "mailbox.rl"
+ { headName.append((*p)); }
+ goto st83;
+st83:
+ if ( ++p == pe )
+ goto _test_eof83;
+case 83:
+#line 1157 "mailbox.cpp"
+ if ( (*p) == 58 )
+ goto tr88;
+ if ( 33 <= (*p) && (*p) <= 126 )
+ goto tr39;
+ goto st0;
+st84:
+ if ( ++p == pe )
+ goto _test_eof84;
+case 84:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st85;
+ goto st5;
+st85:
+ if ( ++p == pe )
+ goto _test_eof85;
+case 85:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st86;
+ goto st5;
+st86:
+ if ( ++p == pe )
+ goto _test_eof86;
+case 86:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st87;
+ goto st5;
+st87:
+ if ( ++p == pe )
+ goto _test_eof87;
+case 87:
+ switch( (*p) ) {
+ case 10: goto st34;
+ case 32: goto st88;
+ }
+ goto st5;
+st88:
+ if ( ++p == pe )
+ goto _test_eof88;
+case 88:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ case 43: goto st89;
+ case 45: goto st89;
+ }
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st90;
+ goto st5;
+st89:
+ if ( ++p == pe )
+ goto _test_eof89;
+case 89:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st30;
+ goto st5;
+st90:
+ if ( ++p == pe )
+ goto _test_eof90;
+case 90:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( (*p) > 90 ) {
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st8;
+ } else if ( (*p) >= 65 )
+ goto st91;
+ goto st5;
+st91:
+ if ( ++p == pe )
+ goto _test_eof91;
+case 91:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st33;
+ goto st5;
+st92:
+ if ( ++p == pe )
+ goto _test_eof92;
+case 92:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( (*p) > 90 ) {
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st8;
+ } else if ( (*p) >= 65 )
+ goto st93;
+ goto st5;
+st93:
+ if ( ++p == pe )
+ goto _test_eof93;
+case 93:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 65 <= (*p) && (*p) <= 90 )
+ goto st28;
+ goto st5;
+st94:
+ if ( ++p == pe )
+ goto _test_eof94;
+case 94:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st95;
+ goto st5;
+st95:
+ if ( ++p == pe )
+ goto _test_eof95;
+case 95:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st96;
+ goto st5;
+st96:
+ if ( ++p == pe )
+ goto _test_eof96;
+case 96:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st23;
+ }
+ goto st5;
+st97:
+ if ( ++p == pe )
+ goto _test_eof97;
+case 97:
+ switch( (*p) ) {
+ case 10: goto st0;
+ case 32: goto st6;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st16;
+ goto st5;
+tr99:
+#line 86 "mailbox.rl"
+ {p--; {cs = stack[--top];goto _again;}}
+ goto st102;
+st102:
+ if ( ++p == pe )
+ goto _test_eof102;
+case 102:
+#line 1329 "mailbox.cpp"
+ if ( (*p) == 10 )
+ goto st98;
+ goto st102;
+st98:
+ if ( ++p == pe )
+ goto _test_eof98;
+case 98:
+ switch( (*p) ) {
+ case 9: goto st102;
+ case 32: goto st102;
+ }
+ goto tr99;
+tr106:
+#line 89 "mailbox.rl"
+ {headContent.append((*p));}
+ goto st103;
+tr108:
+#line 90 "mailbox.rl"
+ {headContent.append(' ');}
+#line 89 "mailbox.rl"
+ {headContent.append((*p));}
+ goto st103;
+st103:
+ if ( ++p == pe )
+ goto _test_eof103;
+case 103:
+#line 1356 "mailbox.cpp"
+ if ( (*p) == 10 )
+ goto st99;
+ goto tr106;
+st99:
+ if ( ++p == pe )
+ goto _test_eof99;
+case 99:
+ switch( (*p) ) {
+ case 9: goto st104;
+ case 32: goto st104;
+ }
+ goto tr101;
+st104:
+ if ( ++p == pe )
+ goto _test_eof104;
+case 104:
+ switch( (*p) ) {
+ case 9: goto st104;
+ case 10: goto st99;
+ case 32: goto st104;
+ }
+ goto tr108;
+ }
+ _test_eof100: cs = 100; goto _test_eof;
+ _test_eof1: cs = 1; goto _test_eof;
+ _test_eof2: cs = 2; goto _test_eof;
+ _test_eof3: cs = 3; goto _test_eof;
+ _test_eof4: cs = 4; goto _test_eof;
+ _test_eof5: cs = 5; goto _test_eof;
+ _test_eof6: cs = 6; goto _test_eof;
+ _test_eof7: cs = 7; goto _test_eof;
+ _test_eof8: cs = 8; goto _test_eof;
+ _test_eof9: cs = 9; goto _test_eof;
+ _test_eof10: cs = 10; goto _test_eof;
+ _test_eof11: cs = 11; goto _test_eof;
+ _test_eof12: cs = 12; goto _test_eof;
+ _test_eof13: cs = 13; goto _test_eof;
+ _test_eof14: cs = 14; goto _test_eof;
+ _test_eof15: cs = 15; goto _test_eof;
+ _test_eof16: cs = 16; goto _test_eof;
+ _test_eof17: cs = 17; goto _test_eof;
+ _test_eof18: cs = 18; goto _test_eof;
+ _test_eof19: cs = 19; goto _test_eof;
+ _test_eof20: cs = 20; goto _test_eof;
+ _test_eof21: cs = 21; goto _test_eof;
+ _test_eof22: cs = 22; goto _test_eof;
+ _test_eof23: cs = 23; goto _test_eof;
+ _test_eof24: cs = 24; goto _test_eof;
+ _test_eof25: cs = 25; goto _test_eof;
+ _test_eof26: cs = 26; goto _test_eof;
+ _test_eof27: cs = 27; goto _test_eof;
+ _test_eof28: cs = 28; goto _test_eof;
+ _test_eof29: cs = 29; goto _test_eof;
+ _test_eof30: cs = 30; goto _test_eof;
+ _test_eof31: cs = 31; goto _test_eof;
+ _test_eof32: cs = 32; goto _test_eof;
+ _test_eof33: cs = 33; goto _test_eof;
+ _test_eof34: cs = 34; goto _test_eof;
+ _test_eof101: cs = 101; goto _test_eof;
+ _test_eof35: cs = 35; goto _test_eof;
+ _test_eof36: cs = 36; goto _test_eof;
+ _test_eof37: cs = 37; goto _test_eof;
+ _test_eof38: cs = 38; goto _test_eof;
+ _test_eof39: cs = 39; goto _test_eof;
+ _test_eof40: cs = 40; goto _test_eof;
+ _test_eof41: cs = 41; goto _test_eof;
+ _test_eof42: cs = 42; goto _test_eof;
+ _test_eof43: cs = 43; goto _test_eof;
+ _test_eof44: cs = 44; goto _test_eof;
+ _test_eof45: cs = 45; goto _test_eof;
+ _test_eof46: cs = 46; goto _test_eof;
+ _test_eof47: cs = 47; goto _test_eof;
+ _test_eof48: cs = 48; goto _test_eof;
+ _test_eof49: cs = 49; goto _test_eof;
+ _test_eof50: cs = 50; goto _test_eof;
+ _test_eof51: cs = 51; goto _test_eof;
+ _test_eof52: cs = 52; goto _test_eof;
+ _test_eof53: cs = 53; goto _test_eof;
+ _test_eof54: cs = 54; goto _test_eof;
+ _test_eof55: cs = 55; goto _test_eof;
+ _test_eof56: cs = 56; goto _test_eof;
+ _test_eof57: cs = 57; goto _test_eof;
+ _test_eof58: cs = 58; goto _test_eof;
+ _test_eof59: cs = 59; goto _test_eof;
+ _test_eof60: cs = 60; goto _test_eof;
+ _test_eof61: cs = 61; goto _test_eof;
+ _test_eof62: cs = 62; goto _test_eof;
+ _test_eof63: cs = 63; goto _test_eof;
+ _test_eof64: cs = 64; goto _test_eof;
+ _test_eof65: cs = 65; goto _test_eof;
+ _test_eof66: cs = 66; goto _test_eof;
+ _test_eof67: cs = 67; goto _test_eof;
+ _test_eof68: cs = 68; goto _test_eof;
+ _test_eof69: cs = 69; goto _test_eof;
+ _test_eof70: cs = 70; goto _test_eof;
+ _test_eof71: cs = 71; goto _test_eof;
+ _test_eof72: cs = 72; goto _test_eof;
+ _test_eof73: cs = 73; goto _test_eof;
+ _test_eof74: cs = 74; goto _test_eof;
+ _test_eof75: cs = 75; goto _test_eof;
+ _test_eof76: cs = 76; goto _test_eof;
+ _test_eof77: cs = 77; goto _test_eof;
+ _test_eof78: cs = 78; goto _test_eof;
+ _test_eof79: cs = 79; goto _test_eof;
+ _test_eof80: cs = 80; goto _test_eof;
+ _test_eof81: cs = 81; goto _test_eof;
+ _test_eof82: cs = 82; goto _test_eof;
+ _test_eof83: cs = 83; goto _test_eof;
+ _test_eof84: cs = 84; goto _test_eof;
+ _test_eof85: cs = 85; goto _test_eof;
+ _test_eof86: cs = 86; goto _test_eof;
+ _test_eof87: cs = 87; goto _test_eof;
+ _test_eof88: cs = 88; goto _test_eof;
+ _test_eof89: cs = 89; goto _test_eof;
+ _test_eof90: cs = 90; goto _test_eof;
+ _test_eof91: cs = 91; goto _test_eof;
+ _test_eof92: cs = 92; goto _test_eof;
+ _test_eof93: cs = 93; goto _test_eof;
+ _test_eof94: cs = 94; goto _test_eof;
+ _test_eof95: cs = 95; goto _test_eof;
+ _test_eof96: cs = 96; goto _test_eof;
+ _test_eof97: cs = 97; goto _test_eof;
+ _test_eof102: cs = 102; goto _test_eof;
+ _test_eof98: cs = 98; goto _test_eof;
+ _test_eof103: cs = 103; goto _test_eof;
+ _test_eof99: cs = 99; goto _test_eof;
+ _test_eof104: cs = 104; goto _test_eof;
+
+ _test_eof: {}
+ if ( p == eof )
+ {
+ switch ( cs ) {
+ case 104:
+#line 90 "mailbox.rl"
+ {headContent.append(' ');}
+ break;
+ case 99:
+#line 92 "mailbox.rl"
+ {
+ headContent.append(0);
+ cout << headContent.data << endl;
+ headContent.clear();
+ p--;
+ {cs = stack[--top];goto _again;}
+ }
+ break;
+#line 1503 "mailbox.cpp"
+ }
+ }
+
+ _out: {}
+ }
+
+#line 154 "mailbox.rl"
+
+ if ( cs == MailboxScanner_error )
+ return -1;
+ if ( cs >= MailboxScanner_first_final )
+ return 1;
+ return 0;
+}
+
+int MailboxScanner::finish( )
+{
+ if ( cs == MailboxScanner_error )
+ return -1;
+ if ( cs >= MailboxScanner_first_final )
+ return 1;
+ return 0;
+}
+
+
+void Buffer::empty()
+{
+ if ( data != 0 ) {
+ free( data );
+
+ data = 0;
+ length = 0;
+ allocated = 0;
+ }
+}
+
+void Buffer::upAllocate( int len )
+{
+ if ( data == 0 )
+ data = (char*) malloc( len );
+ else
+ data = (char*) realloc( data, len );
+ allocated = len;
+}
+
+MailboxScanner mailbox;
+char buf[BUFSIZE];
+
+int main()
+{
+ mailbox.init();
+ while ( 1 ) {
+ int len = fread( buf, 1, BUFSIZE, stdin );
+ mailbox.execute( buf, len, len != BUFSIZE );
+ if ( len != BUFSIZE )
+ break;
+ }
+ if ( mailbox.finish() <= 0 )
+ cerr << "mailbox: error parsing input" << endl;
+ return 0;
+}
diff --git a/examples/mailbox.rl b/examples/mailbox.rl
new file mode 100644
index 0000000..94590fd
--- /dev/null
+++ b/examples/mailbox.rl
@@ -0,0 +1,207 @@
+/*
+ * Parses unix mail boxes into headers and bodies.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+using namespace std;
+
+#define BUFSIZE 2048
+
+/* A growable buffer for collecting headers. */
+struct Buffer
+{
+ Buffer() : data(0), allocated(0), length(0) { }
+ ~Buffer() { empty(); }
+
+ void append( char p ) {
+ if ( ++length > allocated )
+ upAllocate( length*2 );
+ data[length-1] = p;
+ }
+
+ void clear() { length = 0; }
+ void upAllocate( int len );
+ void empty();
+
+ char *data;
+ int allocated;
+ int length;
+};
+
+
+struct MailboxScanner
+{
+ Buffer headName;
+ Buffer headContent;
+
+ int cs, top, stack[1];
+
+ int init( );
+ int execute( const char *data, int len, bool isEof );
+ int finish( );
+};
+
+%%{
+ machine MailboxScanner;
+
+ # Buffer the header names.
+ action bufHeadName { headName.append(fc); }
+
+ # Prints a blank line after the end of the headers of each message.
+ action blankLine { cout << endl; }
+
+ # Helpers we will use in matching the date section of the from line.
+ day = /[A-Z][a-z][a-z]/;
+ month = /[A-Z][a-z][a-z]/;
+ year = /[0-9][0-9][0-9][0-9]/;
+ time = /[0-9][0-9]:[0-9][0-9]/ . ( /:[0-9][0-9]/ | '' );
+ letterZone = /[A-Z][A-Z][A-Z]/;
+ numZone = /[+\-][0-9][0-9][0-9][0-9]/;
+ zone = letterZone | numZone;
+ dayNum = /[0-9 ][0-9]/;
+
+ # These are the different formats of the date minus an obscure
+ # type that has a funny string 'remote from xxx' on the end. Taken
+ # from c-client in the imap-2000 distribution.
+ date = day . ' ' . month . ' ' . dayNum . ' ' . time . ' ' .
+ ( year | year . ' ' . zone | zone . ' ' . year );
+
+ # From lines separate messages. We will exclude fromLine from a message
+ # body line. This will cause us to stay in message line up until an
+ # entirely correct from line is matched.
+ fromLine = 'From ' . (any-'\n')* . ' ' . date . '\n';
+
+ # The types of characters that can be used as a header name.
+ hchar = print - [ :];
+
+ # Simply eat up an uninteresting header. Return at the first non-ws
+ # character following a newline.
+ consumeHeader := (
+ [^\n] |
+ '\n' [ \t] |
+ '\n' [^ \t] @{fhold; fret;}
+ )*;
+
+ action hchar {headContent.append(fc);}
+ action hspace {headContent.append(' ');}
+
+ action hfinish {
+ headContent.append(0);
+ cout << headContent.data << endl;
+ headContent.clear();
+ fhold;
+ fret;
+ }
+
+ # Display the contents of a header as it is consumed. Collapses line
+ # continuations to a single space.
+ printHeader := (
+ [^\n] @hchar |
+ ( '\n' ( [ \t]+ '\n' )* [ \t]+ ) %hspace
+ )** $!hfinish;
+
+ action onHeader
+ {
+ headName.append(0);
+ if ( strcmp( headName.data, "From" ) == 0 ||
+ strcmp( headName.data, "To" ) == 0 ||
+ strcmp( headName.data, "Subject" ) == 0 )
+ {
+ /* Print the header name, then jump to a machine the will display
+ * the contents. */
+ cout << headName.data << ":";
+ headName.clear();
+ fcall printHeader;
+ }
+
+ headName.clear();
+ fcall consumeHeader;
+ }
+
+ header = hchar+ $bufHeadName ':' @onHeader;
+
+ # Exclude fromLine from a messageLine, otherwise when encountering a
+ # fromLine we will be simultaneously matching the old message and a new
+ # message.
+ messageLine = ( [^\n]* '\n' - fromLine );
+
+ # An entire message.
+ message = ( fromLine . header* . '\n' @blankLine . messageLine* );
+
+ # File is a series of messages.
+ main := message*;
+}%%
+
+%% write data;
+
+int MailboxScanner::init( )
+{
+ %% write init;
+ return 1;
+}
+
+int MailboxScanner::execute( const char *data, int len, bool isEof )
+{
+ const char *p = data;
+ const char *pe = data + len;
+ const char *eof = isEof ? pe : 0;
+
+ %% write exec;
+
+ if ( cs == MailboxScanner_error )
+ return -1;
+ if ( cs >= MailboxScanner_first_final )
+ return 1;
+ return 0;
+}
+
+int MailboxScanner::finish( )
+{
+ if ( cs == MailboxScanner_error )
+ return -1;
+ if ( cs >= MailboxScanner_first_final )
+ return 1;
+ return 0;
+}
+
+
+void Buffer::empty()
+{
+ if ( data != 0 ) {
+ free( data );
+
+ data = 0;
+ length = 0;
+ allocated = 0;
+ }
+}
+
+void Buffer::upAllocate( int len )
+{
+ if ( data == 0 )
+ data = (char*) malloc( len );
+ else
+ data = (char*) realloc( data, len );
+ allocated = len;
+}
+
+MailboxScanner mailbox;
+char buf[BUFSIZE];
+
+int main()
+{
+ mailbox.init();
+ while ( 1 ) {
+ int len = fread( buf, 1, BUFSIZE, stdin );
+ mailbox.execute( buf, len, len != BUFSIZE );
+ if ( len != BUFSIZE )
+ break;
+ }
+ if ( mailbox.finish() <= 0 )
+ cerr << "mailbox: error parsing input" << endl;
+ return 0;
+}
diff --git a/examples/params.c b/examples/params.c
new file mode 100644
index 0000000..485e1c3
--- /dev/null
+++ b/examples/params.c
@@ -0,0 +1,374 @@
+
+#line 1 "params.rl"
+/*
+ * Parse command line arguments.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#define BUFLEN 1024
+
+struct params
+{
+ char buffer[BUFLEN+1];
+ int buflen;
+ int cs;
+};
+
+
+#line 61 "params.rl"
+
+
+
+#line 25 "params.c"
+static const int params_start = 23;
+static const int params_first_final = 23;
+static const int params_error = 0;
+
+static const int params_en_main = 23;
+
+
+#line 64 "params.rl"
+
+void params_init( struct params *fsm )
+{
+ fsm->buflen = 0;
+
+#line 39 "params.c"
+ {
+ fsm->cs = params_start;
+ }
+
+#line 69 "params.rl"
+}
+
+void params_execute( struct params *fsm, const char *data, int len )
+{
+ const char *p = data;
+ const char *pe = data + len;
+
+
+#line 53 "params.c"
+ {
+ if ( p == pe )
+ goto _test_eof;
+ switch ( fsm->cs )
+ {
+tr11:
+#line 38 "params.rl"
+ { printf("help\n"); }
+ goto st23;
+tr17:
+#line 39 "params.rl"
+ { printf("version\n"); }
+ goto st23;
+tr21:
+#line 30 "params.rl"
+ {
+ if ( fsm->buflen < BUFLEN )
+ fsm->buffer[fsm->buflen++] = 0;
+ }
+#line 42 "params.rl"
+ { printf("machine: \"%s\"\n", fsm->buffer); }
+ goto st23;
+tr25:
+#line 30 "params.rl"
+ {
+ if ( fsm->buflen < BUFLEN )
+ fsm->buffer[fsm->buflen++] = 0;
+ }
+#line 41 "params.rl"
+ { printf("spec: \"%s\"\n", fsm->buffer); }
+ goto st23;
+tr29:
+#line 30 "params.rl"
+ {
+ if ( fsm->buflen < BUFLEN )
+ fsm->buffer[fsm->buflen++] = 0;
+ }
+#line 40 "params.rl"
+ { printf("output: \"%s\"\n", fsm->buffer); }
+ goto st23;
+st23:
+ if ( ++p == pe )
+ goto _test_eof23;
+case 23:
+#line 98 "params.c"
+ if ( (*p) == 45 )
+ goto st1;
+ goto st0;
+st0:
+ fsm->cs = 0;
+ goto _out;
+st1:
+ if ( ++p == pe )
+ goto _test_eof1;
+case 1:
+ switch( (*p) ) {
+ case 45: goto st2;
+ case 63: goto st6;
+ case 72: goto st6;
+ case 77: goto st14;
+ case 83: goto st17;
+ case 104: goto st6;
+ case 111: goto st20;
+ case 118: goto st13;
+ }
+ goto st0;
+st2:
+ if ( ++p == pe )
+ goto _test_eof2;
+case 2:
+ switch( (*p) ) {
+ case 104: goto st3;
+ case 118: goto st7;
+ }
+ goto st0;
+st3:
+ if ( ++p == pe )
+ goto _test_eof3;
+case 3:
+ if ( (*p) == 101 )
+ goto st4;
+ goto st0;
+st4:
+ if ( ++p == pe )
+ goto _test_eof4;
+case 4:
+ if ( (*p) == 108 )
+ goto st5;
+ goto st0;
+st5:
+ if ( ++p == pe )
+ goto _test_eof5;
+case 5:
+ if ( (*p) == 112 )
+ goto st6;
+ goto st0;
+st6:
+ if ( ++p == pe )
+ goto _test_eof6;
+case 6:
+ if ( (*p) == 0 )
+ goto tr11;
+ goto st0;
+st7:
+ if ( ++p == pe )
+ goto _test_eof7;
+case 7:
+ if ( (*p) == 101 )
+ goto st8;
+ goto st0;
+st8:
+ if ( ++p == pe )
+ goto _test_eof8;
+case 8:
+ if ( (*p) == 114 )
+ goto st9;
+ goto st0;
+st9:
+ if ( ++p == pe )
+ goto _test_eof9;
+case 9:
+ if ( (*p) == 115 )
+ goto st10;
+ goto st0;
+st10:
+ if ( ++p == pe )
+ goto _test_eof10;
+case 10:
+ if ( (*p) == 105 )
+ goto st11;
+ goto st0;
+st11:
+ if ( ++p == pe )
+ goto _test_eof11;
+case 11:
+ if ( (*p) == 111 )
+ goto st12;
+ goto st0;
+st12:
+ if ( ++p == pe )
+ goto _test_eof12;
+case 12:
+ if ( (*p) == 110 )
+ goto st13;
+ goto st0;
+st13:
+ if ( ++p == pe )
+ goto _test_eof13;
+case 13:
+ if ( (*p) == 0 )
+ goto tr17;
+ goto st0;
+st14:
+ if ( ++p == pe )
+ goto _test_eof14;
+case 14:
+ if ( (*p) == 0 )
+ goto st16;
+ goto tr18;
+tr18:
+#line 36 "params.rl"
+ { fsm->buflen = 0; }
+#line 24 "params.rl"
+ {
+ if ( fsm->buflen < BUFLEN )
+ fsm->buffer[fsm->buflen++] = (*p);
+ }
+ goto st15;
+tr20:
+#line 24 "params.rl"
+ {
+ if ( fsm->buflen < BUFLEN )
+ fsm->buffer[fsm->buflen++] = (*p);
+ }
+ goto st15;
+st15:
+ if ( ++p == pe )
+ goto _test_eof15;
+case 15:
+#line 233 "params.c"
+ if ( (*p) == 0 )
+ goto tr21;
+ goto tr20;
+st16:
+ if ( ++p == pe )
+ goto _test_eof16;
+case 16:
+ if ( (*p) == 0 )
+ goto st0;
+ goto tr18;
+st17:
+ if ( ++p == pe )
+ goto _test_eof17;
+case 17:
+ if ( (*p) == 0 )
+ goto st19;
+ goto tr22;
+tr22:
+#line 36 "params.rl"
+ { fsm->buflen = 0; }
+#line 24 "params.rl"
+ {
+ if ( fsm->buflen < BUFLEN )
+ fsm->buffer[fsm->buflen++] = (*p);
+ }
+ goto st18;
+tr24:
+#line 24 "params.rl"
+ {
+ if ( fsm->buflen < BUFLEN )
+ fsm->buffer[fsm->buflen++] = (*p);
+ }
+ goto st18;
+st18:
+ if ( ++p == pe )
+ goto _test_eof18;
+case 18:
+#line 271 "params.c"
+ if ( (*p) == 0 )
+ goto tr25;
+ goto tr24;
+st19:
+ if ( ++p == pe )
+ goto _test_eof19;
+case 19:
+ if ( (*p) == 0 )
+ goto st0;
+ goto tr22;
+st20:
+ if ( ++p == pe )
+ goto _test_eof20;
+case 20:
+ if ( (*p) == 0 )
+ goto st22;
+ goto tr26;
+tr26:
+#line 36 "params.rl"
+ { fsm->buflen = 0; }
+#line 24 "params.rl"
+ {
+ if ( fsm->buflen < BUFLEN )
+ fsm->buffer[fsm->buflen++] = (*p);
+ }
+ goto st21;
+tr28:
+#line 24 "params.rl"
+ {
+ if ( fsm->buflen < BUFLEN )
+ fsm->buffer[fsm->buflen++] = (*p);
+ }
+ goto st21;
+st21:
+ if ( ++p == pe )
+ goto _test_eof21;
+case 21:
+#line 309 "params.c"
+ if ( (*p) == 0 )
+ goto tr29;
+ goto tr28;
+st22:
+ if ( ++p == pe )
+ goto _test_eof22;
+case 22:
+ if ( (*p) == 0 )
+ goto st0;
+ goto tr26;
+ }
+ _test_eof23: fsm->cs = 23; goto _test_eof;
+ _test_eof1: fsm->cs = 1; goto _test_eof;
+ _test_eof2: fsm->cs = 2; goto _test_eof;
+ _test_eof3: fsm->cs = 3; goto _test_eof;
+ _test_eof4: fsm->cs = 4; goto _test_eof;
+ _test_eof5: fsm->cs = 5; goto _test_eof;
+ _test_eof6: fsm->cs = 6; goto _test_eof;
+ _test_eof7: fsm->cs = 7; goto _test_eof;
+ _test_eof8: fsm->cs = 8; goto _test_eof;
+ _test_eof9: fsm->cs = 9; goto _test_eof;
+ _test_eof10: fsm->cs = 10; goto _test_eof;
+ _test_eof11: fsm->cs = 11; goto _test_eof;
+ _test_eof12: fsm->cs = 12; goto _test_eof;
+ _test_eof13: fsm->cs = 13; goto _test_eof;
+ _test_eof14: fsm->cs = 14; goto _test_eof;
+ _test_eof15: fsm->cs = 15; goto _test_eof;
+ _test_eof16: fsm->cs = 16; goto _test_eof;
+ _test_eof17: fsm->cs = 17; goto _test_eof;
+ _test_eof18: fsm->cs = 18; goto _test_eof;
+ _test_eof19: fsm->cs = 19; goto _test_eof;
+ _test_eof20: fsm->cs = 20; goto _test_eof;
+ _test_eof21: fsm->cs = 21; goto _test_eof;
+ _test_eof22: fsm->cs = 22; goto _test_eof;
+
+ _test_eof: {}
+ _out: {}
+ }
+
+#line 77 "params.rl"
+}
+
+int params_finish( struct params *fsm )
+{
+ if ( fsm->cs == params_error )
+ return -1;
+ if ( fsm->cs >= params_first_final )
+ return 1;
+ return 0;
+}
+
+#define BUFSIZE 2048
+
+int main( int argc, char **argv )
+{
+ int a;
+ struct params params;
+
+ params_init( &params );
+ for ( a = 1; a < argc; a++ )
+ params_execute( &params, argv[a], strlen(argv[a])+1 );
+ if ( params_finish( &params ) != 1 )
+ fprintf( stderr, "params: error processing arguments\n" );
+
+ return 0;
+}
diff --git a/examples/params.rl b/examples/params.rl
new file mode 100644
index 0000000..a8ffeae
--- /dev/null
+++ b/examples/params.rl
@@ -0,0 +1,102 @@
+/*
+ * Parse command line arguments.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#define BUFLEN 1024
+
+struct params
+{
+ char buffer[BUFLEN+1];
+ int buflen;
+ int cs;
+};
+
+%%{
+ machine params;
+ access fsm->;
+
+ # A buffer to collect argurments
+
+ # Append to the buffer.
+ action append {
+ if ( fsm->buflen < BUFLEN )
+ fsm->buffer[fsm->buflen++] = fc;
+ }
+
+ # Terminate a buffer.
+ action term {
+ if ( fsm->buflen < BUFLEN )
+ fsm->buffer[fsm->buflen++] = 0;
+ }
+
+ # Clear out the buffer
+ action clear { fsm->buflen = 0; }
+
+ action help { printf("help\n"); }
+ action version { printf("version\n"); }
+ action output { printf("output: \"%s\"\n", fsm->buffer); }
+ action spec { printf("spec: \"%s\"\n", fsm->buffer); }
+ action mach { printf("machine: \"%s\"\n", fsm->buffer); }
+
+ # Helpers that collect strings
+ string = [^\0]+ >clear $append %term;
+
+ # Different arguments.
+ help = ( '-h' | '-H' | '-?' | '--help' ) 0 @help;
+ version = ( '-v' | '--version' ) 0 @version;
+ output = '-o' 0? string 0 @output;
+ spec = '-S' 0? string 0 @spec;
+ mach = '-M' 0? string 0 @mach;
+
+ main := (
+ help |
+ version |
+ output |
+ spec |
+ mach
+ )*;
+}%%
+
+%% write data;
+
+void params_init( struct params *fsm )
+{
+ fsm->buflen = 0;
+ %% write init;
+}
+
+void params_execute( struct params *fsm, const char *data, int len )
+{
+ const char *p = data;
+ const char *pe = data + len;
+
+ %% write exec;
+}
+
+int params_finish( struct params *fsm )
+{
+ if ( fsm->cs == params_error )
+ return -1;
+ if ( fsm->cs >= params_first_final )
+ return 1;
+ return 0;
+}
+
+#define BUFSIZE 2048
+
+int main( int argc, char **argv )
+{
+ int a;
+ struct params params;
+
+ params_init( &params );
+ for ( a = 1; a < argc; a++ )
+ params_execute( &params, argv[a], strlen(argv[a])+1 );
+ if ( params_finish( &params ) != 1 )
+ fprintf( stderr, "params: error processing arguments\n" );
+
+ return 0;
+}
diff --git a/examples/pullscan.c b/examples/pullscan.c
new file mode 100644
index 0000000..a72ca2f
--- /dev/null
+++ b/examples/pullscan.c
@@ -0,0 +1,294 @@
+
+#line 1 "pullscan.rl"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define BUFSIZE 4096
+
+typedef struct _Scanner {
+ /* Scanner state. */
+ int cs;
+ int act;
+ int have;
+ int curline;
+ char *ts;
+ char *te;
+ char *p;
+ char *pe;
+ char *eof;
+ FILE *file;
+ int done;
+
+ /* Token data */
+ char *data;
+ int len;
+ int value;
+
+ char buf[BUFSIZE];
+} Scanner;
+
+
+
+#line 34 "pullscan.c"
+static const int Scanner_start = 2;
+static const int Scanner_first_final = 2;
+static const int Scanner_error = -1;
+
+static const int Scanner_en_main = 2;
+
+
+#line 33 "pullscan.rl"
+
+
+void scan_init( Scanner *s, FILE *file )
+{
+ memset (s, '\0', sizeof(Scanner));
+ s->curline = 1;
+ s->file = file;
+ s->eof = 0;
+
+#line 52 "pullscan.c"
+ {
+ s->cs = Scanner_start;
+ s->ts = 0;
+ s->te = 0;
+ s->act = 0;
+ }
+
+#line 42 "pullscan.rl"
+}
+
+#define TK_NO_TOKEN (-1)
+#define TK_ERR 128
+#define TK_EOF 129
+#define TK_Identifier 130
+#define TK_Number 131
+#define TK_String 132
+
+#define ret_tok( _tok ) token = _tok; s->data = s->ts
+
+int scan( Scanner *s )
+{
+ int token = TK_NO_TOKEN;
+ int space, readlen;
+
+ while ( 1 ) {
+ if ( s->p == s->pe ) {
+ printf("scanner: need more data\n");
+
+ if ( s->ts == 0 )
+ s->have = 0;
+ else {
+ /* There is data that needs to be shifted over. */
+ printf("scanner: buffer broken mid token\n");
+ s->have = s->pe - s->ts;
+ memmove( s->buf, s->ts, s->have );
+ s->te -= (s->ts-s->buf);
+ s->ts = s->buf;
+ }
+
+ s->p = s->buf + s->have;
+ space = BUFSIZE - s->have;
+
+ if ( space == 0 ) {
+ /* We filled up the buffer trying to scan a token. */
+ printf("scanner: out of buffer space\n");
+ return TK_ERR;
+ }
+
+ if ( s->done ) {
+ printf("scanner: end of file\n");
+ s->p[0] = 0;
+ readlen = 1;
+ }
+ else {
+ readlen = fread( s->p, 1, space, s->file );
+ if ( readlen < space )
+ s->done = 1;
+ }
+
+ s->pe = s->p + readlen;
+ }
+
+
+#line 116 "pullscan.c"
+ {
+ if ( ( s->p) == ( s->pe) )
+ goto _test_eof;
+ switch ( s->cs )
+ {
+tr0:
+#line 125 "pullscan.rl"
+ {{( s->p) = (( s->te))-1;}{ ret_tok( *s->p ); {( s->p)++; s->cs = 2; goto _out;} }}
+ goto st2;
+tr2:
+#line 113 "pullscan.rl"
+ { s->te = ( s->p)+1;{ ret_tok( TK_String ); {( s->p)++; s->cs = 2; goto _out;} }}
+ goto st2;
+tr4:
+#line 125 "pullscan.rl"
+ { s->te = ( s->p)+1;{ ret_tok( *s->p ); {( s->p)++; s->cs = 2; goto _out;} }}
+ goto st2;
+tr5:
+#line 121 "pullscan.rl"
+ { s->te = ( s->p)+1;{ ret_tok( TK_EOF ); {( s->p)++; s->cs = 2; goto _out;} }}
+ goto st2;
+tr6:
+#line 110 "pullscan.rl"
+ { s->te = ( s->p)+1;}
+ goto st2;
+tr10:
+#line 125 "pullscan.rl"
+ { s->te = ( s->p);( s->p)--;{ ret_tok( *s->p ); {( s->p)++; s->cs = 2; goto _out;} }}
+ goto st2;
+tr11:
+#line 117 "pullscan.rl"
+ { s->te = ( s->p);( s->p)--;{ ret_tok( TK_Number ); {( s->p)++; s->cs = 2; goto _out;} }}
+ goto st2;
+tr12:
+#line 107 "pullscan.rl"
+ { s->te = ( s->p);( s->p)--;{ ret_tok( TK_Identifier ); {( s->p)++; s->cs = 2; goto _out;} }}
+ goto st2;
+st2:
+#line 1 "NONE"
+ { s->ts = 0;}
+ if ( ++( s->p) == ( s->pe) )
+ goto _test_eof2;
+case 2:
+#line 1 "NONE"
+ { s->ts = ( s->p);}
+#line 162 "pullscan.c"
+ switch( (*( s->p)) ) {
+ case 0: goto tr5;
+ case 32: goto tr6;
+ case 34: goto tr7;
+ case 95: goto st5;
+ }
+ if ( (*( s->p)) < 48 ) {
+ if ( 9 <= (*( s->p)) && (*( s->p)) <= 10 )
+ goto tr6;
+ } else if ( (*( s->p)) > 57 ) {
+ if ( (*( s->p)) > 90 ) {
+ if ( 97 <= (*( s->p)) && (*( s->p)) <= 122 )
+ goto st5;
+ } else if ( (*( s->p)) >= 65 )
+ goto st5;
+ } else
+ goto st4;
+ goto tr4;
+tr7:
+#line 1 "NONE"
+ { s->te = ( s->p)+1;}
+ goto st3;
+st3:
+ if ( ++( s->p) == ( s->pe) )
+ goto _test_eof3;
+case 3:
+#line 189 "pullscan.c"
+ switch( (*( s->p)) ) {
+ case 34: goto tr2;
+ case 92: goto st1;
+ }
+ goto st0;
+st0:
+ if ( ++( s->p) == ( s->pe) )
+ goto _test_eof0;
+case 0:
+ switch( (*( s->p)) ) {
+ case 34: goto tr2;
+ case 92: goto st1;
+ }
+ goto st0;
+st1:
+ if ( ++( s->p) == ( s->pe) )
+ goto _test_eof1;
+case 1:
+ goto st0;
+st4:
+ if ( ++( s->p) == ( s->pe) )
+ goto _test_eof4;
+case 4:
+ if ( 48 <= (*( s->p)) && (*( s->p)) <= 57 )
+ goto st4;
+ goto tr11;
+st5:
+ if ( ++( s->p) == ( s->pe) )
+ goto _test_eof5;
+case 5:
+ if ( (*( s->p)) == 95 )
+ goto st5;
+ if ( (*( s->p)) < 65 ) {
+ if ( 48 <= (*( s->p)) && (*( s->p)) <= 57 )
+ goto st5;
+ } else if ( (*( s->p)) > 90 ) {
+ if ( 97 <= (*( s->p)) && (*( s->p)) <= 122 )
+ goto st5;
+ } else
+ goto st5;
+ goto tr12;
+ }
+ _test_eof2: s->cs = 2; goto _test_eof;
+ _test_eof3: s->cs = 3; goto _test_eof;
+ _test_eof0: s->cs = 0; goto _test_eof;
+ _test_eof1: s->cs = 1; goto _test_eof;
+ _test_eof4: s->cs = 4; goto _test_eof;
+ _test_eof5: s->cs = 5; goto _test_eof;
+
+ _test_eof: {}
+ if ( ( s->p) == ( s->eof) )
+ {
+ switch ( s->cs ) {
+ case 3: goto tr10;
+ case 0: goto tr0;
+ case 1: goto tr0;
+ case 4: goto tr11;
+ case 5: goto tr12;
+ }
+ }
+
+ _out: {}
+ }
+
+#line 130 "pullscan.rl"
+
+
+ if ( s->cs == Scanner_error )
+ return TK_ERR;
+
+ if ( token != TK_NO_TOKEN ) {
+ s->len = s->p - s->data;
+ return token;
+ }
+ }
+}
+
+
+int main (int argc, char** argv)
+{
+ Scanner ss;
+ int tok;
+
+ scan_init(&ss, stdin);
+
+ while ( 1 ) {
+ tok = scan (&ss);
+ if ( tok == TK_EOF ) {
+ printf ("parser: EOF\n");
+ break;
+ }
+ else if ( tok == TK_ERR ) {
+ printf ("parser: ERR\n");
+ break;
+ }
+ else {
+ printf ("parser: %d \"", tok);
+ fwrite ( ss.data, 1, ss.len, stdout );
+ printf ("\"\n" );
+ }
+ }
+
+ return 0;
+}
+
+
diff --git a/examples/pullscan.rl b/examples/pullscan.rl
new file mode 100644
index 0000000..d9e8a57
--- /dev/null
+++ b/examples/pullscan.rl
@@ -0,0 +1,170 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define BUFSIZE 4096
+
+typedef struct _Scanner {
+ /* Scanner state. */
+ int cs;
+ int act;
+ int have;
+ int curline;
+ char *ts;
+ char *te;
+ char *p;
+ char *pe;
+ char *eof;
+ FILE *file;
+ int done;
+
+ /* Token data */
+ char *data;
+ int len;
+ int value;
+
+ char buf[BUFSIZE];
+} Scanner;
+
+
+%%{
+ machine Scanner;
+ write data;
+}%%
+
+void scan_init( Scanner *s, FILE *file )
+{
+ memset (s, '\0', sizeof(Scanner));
+ s->curline = 1;
+ s->file = file;
+ s->eof = 0;
+ %% write init;
+}
+
+#define TK_NO_TOKEN (-1)
+#define TK_ERR 128
+#define TK_EOF 129
+#define TK_Identifier 130
+#define TK_Number 131
+#define TK_String 132
+
+#define ret_tok( _tok ) token = _tok; s->data = s->ts
+
+int scan( Scanner *s )
+{
+ int token = TK_NO_TOKEN;
+ int space, readlen;
+
+ while ( 1 ) {
+ if ( s->p == s->pe ) {
+ printf("scanner: need more data\n");
+
+ if ( s->ts == 0 )
+ s->have = 0;
+ else {
+ /* There is data that needs to be shifted over. */
+ printf("scanner: buffer broken mid token\n");
+ s->have = s->pe - s->ts;
+ memmove( s->buf, s->ts, s->have );
+ s->te -= (s->ts-s->buf);
+ s->ts = s->buf;
+ }
+
+ s->p = s->buf + s->have;
+ space = BUFSIZE - s->have;
+
+ if ( space == 0 ) {
+ /* We filled up the buffer trying to scan a token. */
+ printf("scanner: out of buffer space\n");
+ return TK_ERR;
+ }
+
+ if ( s->done ) {
+ printf("scanner: end of file\n");
+ s->p[0] = 0;
+ readlen = 1;
+ }
+ else {
+ readlen = fread( s->p, 1, space, s->file );
+ if ( readlen < space )
+ s->done = 1;
+ }
+
+ s->pe = s->p + readlen;
+ }
+
+ %%{
+ machine Scanner;
+ access s->;
+ variable p s->p;
+ variable pe s->pe;
+ variable eof s->eof;
+
+ main := |*
+
+ # Identifiers
+ ( [a-zA-Z_] [a-zA-Z0-9_]* ) =>
+ { ret_tok( TK_Identifier ); fbreak; };
+
+ # Whitespace
+ [ \t\n];
+
+ '"' ( [^\\"] | '\\' any ) * '"' =>
+ { ret_tok( TK_String ); fbreak; };
+
+ # Number
+ digit+ =>
+ { ret_tok( TK_Number ); fbreak; };
+
+ # EOF
+ 0 =>
+ { ret_tok( TK_EOF ); fbreak; };
+
+ # Anything else
+ any =>
+ { ret_tok( *s->p ); fbreak; };
+
+ *|;
+
+ write exec;
+ }%%
+
+ if ( s->cs == Scanner_error )
+ return TK_ERR;
+
+ if ( token != TK_NO_TOKEN ) {
+ s->len = s->p - s->data;
+ return token;
+ }
+ }
+}
+
+
+int main (int argc, char** argv)
+{
+ Scanner ss;
+ int tok;
+
+ scan_init(&ss, stdin);
+
+ while ( 1 ) {
+ tok = scan (&ss);
+ if ( tok == TK_EOF ) {
+ printf ("parser: EOF\n");
+ break;
+ }
+ else if ( tok == TK_ERR ) {
+ printf ("parser: ERR\n");
+ break;
+ }
+ else {
+ printf ("parser: %d \"", tok);
+ fwrite ( ss.data, 1, ss.len, stdout );
+ printf ("\"\n" );
+ }
+ }
+
+ return 0;
+}
+
+
diff --git a/examples/rlscan.cpp b/examples/rlscan.cpp
new file mode 100644
index 0000000..1c428f8
--- /dev/null
+++ b/examples/rlscan.cpp
@@ -0,0 +1,1055 @@
+
+#line 1 "rlscan.rl"
+/*
+ * Lexes Ragel input files.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+using namespace std;
+
+void escapeXML( char *data )
+{
+ while ( *data != 0 ) {
+ switch ( *data ) {
+ case '<': cout << "&lt;"; break;
+ case '>': cout << "&gt;"; break;
+ case '&': cout << "&amp;"; break;
+ default: cout << *data; break;
+ }
+ data += 1;
+ }
+}
+
+void escapeXML( char c )
+{
+ switch ( c ) {
+ case '<': cout << "&lt;"; break;
+ case '>': cout << "&gt;"; break;
+ case '&': cout << "&amp;"; break;
+ default: cout << c; break;
+ }
+}
+
+void escapeXML( char *data, int len )
+{
+ for ( char *end = data + len; data != end; data++ ) {
+ switch ( *data ) {
+ case '<': cout << "&lt;"; break;
+ case '>': cout << "&gt;"; break;
+ case '&': cout << "&amp;"; break;
+ default: cout << *data; break;
+ }
+ }
+}
+
+inline void write( const char *data )
+{
+ cout << data;
+}
+
+inline void write( char c )
+{
+ cout << c;
+}
+
+inline void write( char *data, int len )
+{
+ cout.write( data, len );
+}
+
+
+
+#line 237 "rlscan.rl"
+
+
+
+#line 71 "rlscan.cpp"
+static const int RagelScan_start = 24;
+static const int RagelScan_error = 0;
+
+static const int RagelScan_en_c_comment = 6;
+static const int RagelScan_en_ilscan = 31;
+static const int RagelScan_en_rlscan = 35;
+static const int RagelScan_en_main = 24;
+
+
+#line 240 "rlscan.rl"
+
+#define BUFSIZE 2048
+
+int main()
+{
+ std::ios::sync_with_stdio(false);
+
+ int cs, act;
+ char *ts, *te;
+ int stack[1], top;
+
+ static char inbuf[BUFSIZE];
+ bool single_line = false;
+ int inline_depth = 0;
+
+
+#line 98 "rlscan.cpp"
+ {
+ cs = RagelScan_start;
+ top = 0;
+ ts = 0;
+ te = 0;
+ act = 0;
+ }
+
+#line 256 "rlscan.rl"
+
+ bool done = false;
+ int have = 0;
+ while ( !done ) {
+ /* How much space is in the buffer? */
+ int space = BUFSIZE - have;
+ if ( space == 0 ) {
+ /* Buffer is full. */
+ cerr << "TOKEN TOO BIG" << endl;
+ exit(1);
+ }
+
+ /* Read in a block. */
+ char *p = inbuf + have;
+ cin.read( p, space );
+ int len = cin.gcount();
+ char *pe = p + len;
+ char *eof = 0;
+
+ /* Check for EOF. */
+ if ( len == 0 ) {
+ eof = pe;
+ done = true;
+ }
+
+
+#line 134 "rlscan.cpp"
+ {
+ if ( p == pe )
+ goto _test_eof;
+ goto _resume;
+
+_again:
+ switch ( cs ) {
+ case 24: goto st24;
+ case 25: goto st25;
+ case 1: goto st1;
+ case 2: goto st2;
+ case 26: goto st26;
+ case 27: goto st27;
+ case 28: goto st28;
+ case 3: goto st3;
+ case 4: goto st4;
+ case 29: goto st29;
+ case 5: goto st5;
+ case 6: goto st6;
+ case 0: goto st0;
+ case 7: goto st7;
+ case 30: goto st30;
+ case 31: goto st31;
+ case 32: goto st32;
+ case 8: goto st8;
+ case 9: goto st9;
+ case 33: goto st33;
+ case 10: goto st10;
+ case 11: goto st11;
+ case 34: goto st34;
+ case 12: goto st12;
+ case 35: goto st35;
+ case 36: goto st36;
+ case 13: goto st13;
+ case 14: goto st14;
+ case 37: goto st37;
+ case 15: goto st15;
+ case 38: goto st38;
+ case 16: goto st16;
+ case 17: goto st17;
+ case 39: goto st39;
+ case 18: goto st18;
+ case 19: goto st19;
+ case 40: goto st40;
+ case 41: goto st41;
+ case 20: goto st20;
+ case 42: goto st42;
+ case 43: goto st43;
+ case 44: goto st44;
+ case 21: goto st21;
+ case 22: goto st22;
+ case 45: goto st45;
+ case 23: goto st23;
+ default: break;
+ }
+
+ if ( ++p == pe )
+ goto _test_eof;
+_resume:
+ switch ( cs )
+ {
+tr0:
+#line 230 "rlscan.rl"
+ {{p = ((te))-1;}{
+ escapeXML( *ts );
+ }}
+ goto st24;
+tr2:
+#line 79 "rlscan.rl"
+ {te = p+1;{
+ escapeXML( ts, te-ts );
+ }}
+ goto st24;
+tr5:
+#line 79 "rlscan.rl"
+ {te = p+1;{
+ escapeXML( ts, te-ts );
+ }}
+ goto st24;
+tr8:
+#line 79 "rlscan.rl"
+ {te = p+1;{
+ escapeXML( ts, te-ts );
+ }}
+ goto st24;
+tr40:
+#line 230 "rlscan.rl"
+ {te = p+1;{
+ escapeXML( *ts );
+ }}
+ goto st24;
+tr41:
+#line 235 "rlscan.rl"
+ {te = p+1;}
+ goto st24;
+tr46:
+#line 230 "rlscan.rl"
+ {te = p;p--;{
+ escapeXML( *ts );
+ }}
+ goto st24;
+tr48:
+#line 224 "rlscan.rl"
+ {te = p;p--;{
+ write( "<section>\n" );
+ single_line = true;
+ {goto st35;}
+ }}
+ goto st24;
+tr49:
+#line 218 "rlscan.rl"
+ {te = p+1;{
+ write( "<section>\n" );
+ single_line = false;
+ {goto st35;}
+ }}
+ goto st24;
+tr50:
+#line 211 "rlscan.rl"
+ {te = p+1;{
+ escapeXML( ts, te-ts );
+ {stack[top++] = 24; goto st6;}
+ }}
+ goto st24;
+st24:
+#line 1 "NONE"
+ {ts = 0;}
+ if ( ++p == pe )
+ goto _test_eof24;
+case 24:
+#line 1 "NONE"
+ {ts = p;}
+#line 267 "rlscan.cpp"
+ switch( (*p) ) {
+ case 0: goto tr41;
+ case 34: goto tr42;
+ case 37: goto st26;
+ case 39: goto tr44;
+ case 47: goto tr45;
+ }
+ goto tr40;
+tr42:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st25;
+st25:
+ if ( ++p == pe )
+ goto _test_eof25;
+case 25:
+#line 284 "rlscan.cpp"
+ switch( (*p) ) {
+ case 34: goto tr2;
+ case 92: goto st2;
+ }
+ goto st1;
+st1:
+ if ( ++p == pe )
+ goto _test_eof1;
+case 1:
+ switch( (*p) ) {
+ case 34: goto tr2;
+ case 92: goto st2;
+ }
+ goto st1;
+st2:
+ if ( ++p == pe )
+ goto _test_eof2;
+case 2:
+ goto st1;
+st26:
+ if ( ++p == pe )
+ goto _test_eof26;
+case 26:
+ if ( (*p) == 37 )
+ goto st27;
+ goto tr46;
+st27:
+ if ( ++p == pe )
+ goto _test_eof27;
+case 27:
+ if ( (*p) == 123 )
+ goto tr49;
+ goto tr48;
+tr44:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st28;
+st28:
+ if ( ++p == pe )
+ goto _test_eof28;
+case 28:
+#line 326 "rlscan.cpp"
+ switch( (*p) ) {
+ case 39: goto tr5;
+ case 92: goto st4;
+ }
+ goto st3;
+st3:
+ if ( ++p == pe )
+ goto _test_eof3;
+case 3:
+ switch( (*p) ) {
+ case 39: goto tr5;
+ case 92: goto st4;
+ }
+ goto st3;
+st4:
+ if ( ++p == pe )
+ goto _test_eof4;
+case 4:
+ goto st3;
+tr45:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st29;
+st29:
+ if ( ++p == pe )
+ goto _test_eof29;
+case 29:
+#line 354 "rlscan.cpp"
+ switch( (*p) ) {
+ case 42: goto tr50;
+ case 47: goto st5;
+ }
+ goto tr46;
+st5:
+ if ( ++p == pe )
+ goto _test_eof5;
+case 5:
+ if ( (*p) == 10 )
+ goto tr8;
+ goto st5;
+tr9:
+#line 76 "rlscan.rl"
+ { escapeXML( (*p) ); }
+ goto st6;
+st6:
+#line 1 "NONE"
+ {ts = 0;}
+ if ( ++p == pe )
+ goto _test_eof6;
+case 6:
+#line 377 "rlscan.cpp"
+ switch( (*p) ) {
+ case 0: goto st0;
+ case 42: goto tr11;
+ }
+ goto tr9;
+st0:
+cs = 0;
+ goto _out;
+tr11:
+#line 76 "rlscan.rl"
+ { escapeXML( (*p) ); }
+ goto st7;
+st7:
+ if ( ++p == pe )
+ goto _test_eof7;
+case 7:
+#line 394 "rlscan.cpp"
+ switch( (*p) ) {
+ case 0: goto st0;
+ case 42: goto tr11;
+ case 47: goto tr12;
+ }
+ goto tr9;
+tr12:
+#line 76 "rlscan.rl"
+ { escapeXML( (*p) ); }
+#line 77 "rlscan.rl"
+ { {cs = stack[--top];goto _again;} }
+ goto st30;
+st30:
+ if ( ++p == pe )
+ goto _test_eof30;
+case 30:
+#line 411 "rlscan.cpp"
+ goto st0;
+tr13:
+#line 112 "rlscan.rl"
+ {{p = ((te))-1;}{ escapeXML( *ts ); }}
+ goto st31;
+tr15:
+#line 79 "rlscan.rl"
+ {te = p+1;{
+ escapeXML( ts, te-ts );
+ }}
+ goto st31;
+tr18:
+#line 79 "rlscan.rl"
+ {te = p+1;{
+ escapeXML( ts, te-ts );
+ }}
+ goto st31;
+tr21:
+#line 79 "rlscan.rl"
+ {te = p+1;{
+ escapeXML( ts, te-ts );
+ }}
+ goto st31;
+tr51:
+#line 112 "rlscan.rl"
+ {te = p+1;{ escapeXML( *ts ); }}
+ goto st31;
+tr55:
+#line 97 "rlscan.rl"
+ {te = p+1;{
+ write( '{' );
+ inline_depth += 1;
+ }}
+ goto st31;
+tr56:
+#line 102 "rlscan.rl"
+ {te = p+1;{
+ write( '}' );
+ /* If dropping down to the last } then return
+ * to ragel code. */
+ if ( --inline_depth == 0 ) {
+ write( "</inline>\n" );
+ {goto st35;}
+ }
+ }}
+ goto st31;
+tr57:
+#line 112 "rlscan.rl"
+ {te = p;p--;{ escapeXML( *ts ); }}
+ goto st31;
+tr58:
+#line 91 "rlscan.rl"
+ {te = p+1;{
+ write( "/*" );
+ {stack[top++] = 31; goto st6;}
+ }}
+ goto st31;
+st31:
+#line 1 "NONE"
+ {ts = 0;}
+ if ( ++p == pe )
+ goto _test_eof31;
+case 31:
+#line 1 "NONE"
+ {ts = p;}
+#line 477 "rlscan.cpp"
+ switch( (*p) ) {
+ case 0: goto st0;
+ case 34: goto tr52;
+ case 39: goto tr53;
+ case 47: goto tr54;
+ case 123: goto tr55;
+ case 125: goto tr56;
+ }
+ goto tr51;
+tr52:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st32;
+st32:
+ if ( ++p == pe )
+ goto _test_eof32;
+case 32:
+#line 495 "rlscan.cpp"
+ switch( (*p) ) {
+ case 34: goto tr15;
+ case 92: goto st9;
+ }
+ goto st8;
+st8:
+ if ( ++p == pe )
+ goto _test_eof8;
+case 8:
+ switch( (*p) ) {
+ case 34: goto tr15;
+ case 92: goto st9;
+ }
+ goto st8;
+st9:
+ if ( ++p == pe )
+ goto _test_eof9;
+case 9:
+ goto st8;
+tr53:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st33;
+st33:
+ if ( ++p == pe )
+ goto _test_eof33;
+case 33:
+#line 523 "rlscan.cpp"
+ switch( (*p) ) {
+ case 39: goto tr18;
+ case 92: goto st11;
+ }
+ goto st10;
+st10:
+ if ( ++p == pe )
+ goto _test_eof10;
+case 10:
+ switch( (*p) ) {
+ case 39: goto tr18;
+ case 92: goto st11;
+ }
+ goto st10;
+st11:
+ if ( ++p == pe )
+ goto _test_eof11;
+case 11:
+ goto st10;
+tr54:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st34;
+st34:
+ if ( ++p == pe )
+ goto _test_eof34;
+case 34:
+#line 551 "rlscan.cpp"
+ switch( (*p) ) {
+ case 42: goto tr58;
+ case 47: goto st12;
+ }
+ goto tr57;
+st12:
+ if ( ++p == pe )
+ goto _test_eof12;
+case 12:
+ if ( (*p) == 10 )
+ goto tr21;
+ goto st12;
+tr22:
+#line 193 "rlscan.rl"
+ {{p = ((te))-1;}{
+ write( "<symbol>" );
+ escapeXML( (*p) );
+ write( "</symbol>\n" );
+ }}
+ goto st35;
+tr24:
+#line 166 "rlscan.rl"
+ {te = p+1;{
+ write( "<double_lit>" );
+ escapeXML( ts, te-ts );
+ write( "</double_lit>\n" );
+ }}
+ goto st35;
+tr27:
+#line 156 "rlscan.rl"
+ {te = p+1;}
+ goto st35;
+tr29:
+#line 159 "rlscan.rl"
+ {te = p+1;{
+ write( "<single_lit>" );
+ escapeXML( ts, te-ts );
+ write( "</single_lit>\n" );
+ }}
+ goto st35;
+tr32:
+#line 180 "rlscan.rl"
+ {te = p+1;{
+ write( "<re_lit>" );
+ escapeXML( ts, te-ts );
+ write( "</re_lit>\n" );
+ }}
+ goto st35;
+tr34:
+#line 142 "rlscan.rl"
+ {{p = ((te))-1;}{
+ write( "<int>" );
+ write( ts, te-ts );
+ write( "</int>\n" );
+ }}
+ goto st35;
+tr38:
+#line 173 "rlscan.rl"
+ {te = p+1;{
+ write( "<or_lit>" );
+ escapeXML( ts, te-ts );
+ write( "</or_lit>\n" );
+ }}
+ goto st35;
+tr39:
+#line 120 "rlscan.rl"
+ {te = p+1;{
+ if ( !single_line ) {
+ write( "</section>\n" );
+ {goto st24;}
+ }
+ }}
+ goto st35;
+tr59:
+#line 199 "rlscan.rl"
+ {te = p+1;}
+ goto st35;
+tr60:
+#line 127 "rlscan.rl"
+ {te = p+1;{
+ if ( single_line ) {
+ write( "</section>\n" );
+ {goto st24;}
+ }
+ }}
+ goto st35;
+tr61:
+#line 193 "rlscan.rl"
+ {te = p+1;{
+ write( "<symbol>" );
+ escapeXML( (*p) );
+ write( "</symbol>\n" );
+ }}
+ goto st35;
+tr70:
+#line 187 "rlscan.rl"
+ {te = p+1;{
+ inline_depth = 1;
+ write( "<inline>{" );
+ {goto st31;}
+ }}
+ goto st35;
+tr72:
+#line 193 "rlscan.rl"
+ {te = p;p--;{
+ write( "<symbol>" );
+ escapeXML( (*p) );
+ write( "</symbol>\n" );
+ }}
+ goto st35;
+tr73:
+#line 142 "rlscan.rl"
+ {te = p;p--;{
+ write( "<int>" );
+ write( ts, te-ts );
+ write( "</int>\n" );
+ }}
+ goto st35;
+tr75:
+#line 149 "rlscan.rl"
+ {te = p;p--;{
+ write( "<hex>" );
+ write( ts, te-ts );
+ write( "</hex>\n" );
+ }}
+ goto st35;
+tr76:
+#line 135 "rlscan.rl"
+ {te = p;p--;{
+ write( "<word>" );
+ write( ts, te-ts );
+ write( "</word>\n" );
+ }}
+ goto st35;
+st35:
+#line 1 "NONE"
+ {ts = 0;}
+ if ( ++p == pe )
+ goto _test_eof35;
+case 35:
+#line 1 "NONE"
+ {ts = p;}
+#line 694 "rlscan.cpp"
+ switch( (*p) ) {
+ case 0: goto st0;
+ case 10: goto tr60;
+ case 34: goto tr62;
+ case 35: goto tr63;
+ case 39: goto tr64;
+ case 47: goto tr65;
+ case 48: goto tr66;
+ case 91: goto tr69;
+ case 95: goto st43;
+ case 123: goto tr70;
+ case 125: goto tr71;
+ }
+ if ( (*p) < 65 ) {
+ if ( (*p) < 49 ) {
+ if ( 33 <= (*p) && (*p) <= 46 )
+ goto tr61;
+ } else if ( (*p) > 57 ) {
+ if ( 58 <= (*p) && (*p) <= 64 )
+ goto tr61;
+ } else
+ goto st41;
+ } else if ( (*p) > 90 ) {
+ if ( (*p) < 97 ) {
+ if ( 92 <= (*p) && (*p) <= 96 )
+ goto tr61;
+ } else if ( (*p) > 122 ) {
+ if ( 124 <= (*p) && (*p) <= 126 )
+ goto tr61;
+ } else
+ goto st43;
+ } else
+ goto st43;
+ goto tr59;
+tr62:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st36;
+st36:
+ if ( ++p == pe )
+ goto _test_eof36;
+case 36:
+#line 737 "rlscan.cpp"
+ switch( (*p) ) {
+ case 34: goto tr24;
+ case 92: goto st14;
+ }
+ goto st13;
+st13:
+ if ( ++p == pe )
+ goto _test_eof13;
+case 13:
+ switch( (*p) ) {
+ case 34: goto tr24;
+ case 92: goto st14;
+ }
+ goto st13;
+st14:
+ if ( ++p == pe )
+ goto _test_eof14;
+case 14:
+ goto st13;
+tr63:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st37;
+st37:
+ if ( ++p == pe )
+ goto _test_eof37;
+case 37:
+#line 765 "rlscan.cpp"
+ if ( (*p) == 10 )
+ goto tr27;
+ goto st15;
+st15:
+ if ( ++p == pe )
+ goto _test_eof15;
+case 15:
+ if ( (*p) == 10 )
+ goto tr27;
+ goto st15;
+tr64:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st38;
+st38:
+ if ( ++p == pe )
+ goto _test_eof38;
+case 38:
+#line 784 "rlscan.cpp"
+ switch( (*p) ) {
+ case 39: goto tr29;
+ case 92: goto st17;
+ }
+ goto st16;
+st16:
+ if ( ++p == pe )
+ goto _test_eof16;
+case 16:
+ switch( (*p) ) {
+ case 39: goto tr29;
+ case 92: goto st17;
+ }
+ goto st16;
+st17:
+ if ( ++p == pe )
+ goto _test_eof17;
+case 17:
+ goto st16;
+tr65:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st39;
+st39:
+ if ( ++p == pe )
+ goto _test_eof39;
+case 39:
+#line 812 "rlscan.cpp"
+ switch( (*p) ) {
+ case 47: goto tr32;
+ case 92: goto st19;
+ }
+ goto st18;
+st18:
+ if ( ++p == pe )
+ goto _test_eof18;
+case 18:
+ switch( (*p) ) {
+ case 47: goto tr32;
+ case 92: goto st19;
+ }
+ goto st18;
+st19:
+ if ( ++p == pe )
+ goto _test_eof19;
+case 19:
+ goto st18;
+tr66:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st40;
+st40:
+ if ( ++p == pe )
+ goto _test_eof40;
+case 40:
+#line 840 "rlscan.cpp"
+ if ( (*p) == 120 )
+ goto st20;
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st41;
+ goto tr73;
+st41:
+ if ( ++p == pe )
+ goto _test_eof41;
+case 41:
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st41;
+ goto tr73;
+st20:
+ if ( ++p == pe )
+ goto _test_eof20;
+case 20:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st42;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st42;
+ } else
+ goto st42;
+ goto tr34;
+st42:
+ if ( ++p == pe )
+ goto _test_eof42;
+case 42:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st42;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st42;
+ } else
+ goto st42;
+ goto tr75;
+st43:
+ if ( ++p == pe )
+ goto _test_eof43;
+case 43:
+ if ( (*p) == 95 )
+ goto st43;
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st43;
+ } else if ( (*p) > 90 ) {
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st43;
+ } else
+ goto st43;
+ goto tr76;
+tr69:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st44;
+st44:
+ if ( ++p == pe )
+ goto _test_eof44;
+case 44:
+#line 902 "rlscan.cpp"
+ switch( (*p) ) {
+ case 92: goto st22;
+ case 93: goto tr38;
+ }
+ goto st21;
+st21:
+ if ( ++p == pe )
+ goto _test_eof21;
+case 21:
+ switch( (*p) ) {
+ case 92: goto st22;
+ case 93: goto tr38;
+ }
+ goto st21;
+st22:
+ if ( ++p == pe )
+ goto _test_eof22;
+case 22:
+ goto st21;
+tr71:
+#line 1 "NONE"
+ {te = p+1;}
+ goto st45;
+st45:
+ if ( ++p == pe )
+ goto _test_eof45;
+case 45:
+#line 930 "rlscan.cpp"
+ if ( (*p) == 37 )
+ goto st23;
+ goto tr72;
+st23:
+ if ( ++p == pe )
+ goto _test_eof23;
+case 23:
+ if ( (*p) == 37 )
+ goto tr39;
+ goto tr22;
+ }
+ _test_eof24: cs = 24; goto _test_eof;
+ _test_eof25: cs = 25; goto _test_eof;
+ _test_eof1: cs = 1; goto _test_eof;
+ _test_eof2: cs = 2; goto _test_eof;
+ _test_eof26: cs = 26; goto _test_eof;
+ _test_eof27: cs = 27; goto _test_eof;
+ _test_eof28: cs = 28; goto _test_eof;
+ _test_eof3: cs = 3; goto _test_eof;
+ _test_eof4: cs = 4; goto _test_eof;
+ _test_eof29: cs = 29; goto _test_eof;
+ _test_eof5: cs = 5; goto _test_eof;
+ _test_eof6: cs = 6; goto _test_eof;
+ _test_eof7: cs = 7; goto _test_eof;
+ _test_eof30: cs = 30; goto _test_eof;
+ _test_eof31: cs = 31; goto _test_eof;
+ _test_eof32: cs = 32; goto _test_eof;
+ _test_eof8: cs = 8; goto _test_eof;
+ _test_eof9: cs = 9; goto _test_eof;
+ _test_eof33: cs = 33; goto _test_eof;
+ _test_eof10: cs = 10; goto _test_eof;
+ _test_eof11: cs = 11; goto _test_eof;
+ _test_eof34: cs = 34; goto _test_eof;
+ _test_eof12: cs = 12; goto _test_eof;
+ _test_eof35: cs = 35; goto _test_eof;
+ _test_eof36: cs = 36; goto _test_eof;
+ _test_eof13: cs = 13; goto _test_eof;
+ _test_eof14: cs = 14; goto _test_eof;
+ _test_eof37: cs = 37; goto _test_eof;
+ _test_eof15: cs = 15; goto _test_eof;
+ _test_eof38: cs = 38; goto _test_eof;
+ _test_eof16: cs = 16; goto _test_eof;
+ _test_eof17: cs = 17; goto _test_eof;
+ _test_eof39: cs = 39; goto _test_eof;
+ _test_eof18: cs = 18; goto _test_eof;
+ _test_eof19: cs = 19; goto _test_eof;
+ _test_eof40: cs = 40; goto _test_eof;
+ _test_eof41: cs = 41; goto _test_eof;
+ _test_eof20: cs = 20; goto _test_eof;
+ _test_eof42: cs = 42; goto _test_eof;
+ _test_eof43: cs = 43; goto _test_eof;
+ _test_eof44: cs = 44; goto _test_eof;
+ _test_eof21: cs = 21; goto _test_eof;
+ _test_eof22: cs = 22; goto _test_eof;
+ _test_eof45: cs = 45; goto _test_eof;
+ _test_eof23: cs = 23; goto _test_eof;
+
+ _test_eof: {}
+ if ( p == eof )
+ {
+ switch ( cs ) {
+ case 25: goto tr46;
+ case 1: goto tr0;
+ case 2: goto tr0;
+ case 26: goto tr46;
+ case 27: goto tr48;
+ case 28: goto tr46;
+ case 3: goto tr0;
+ case 4: goto tr0;
+ case 29: goto tr46;
+ case 5: goto tr0;
+ case 32: goto tr57;
+ case 8: goto tr13;
+ case 9: goto tr13;
+ case 33: goto tr57;
+ case 10: goto tr13;
+ case 11: goto tr13;
+ case 34: goto tr57;
+ case 12: goto tr13;
+ case 36: goto tr72;
+ case 13: goto tr22;
+ case 14: goto tr22;
+ case 37: goto tr72;
+ case 15: goto tr22;
+ case 38: goto tr72;
+ case 16: goto tr22;
+ case 17: goto tr22;
+ case 39: goto tr72;
+ case 18: goto tr22;
+ case 19: goto tr22;
+ case 40: goto tr73;
+ case 41: goto tr73;
+ case 20: goto tr34;
+ case 42: goto tr75;
+ case 43: goto tr76;
+ case 44: goto tr72;
+ case 21: goto tr22;
+ case 22: goto tr22;
+ case 45: goto tr72;
+ case 23: goto tr22;
+ }
+ }
+
+ _out: {}
+ }
+
+#line 282 "rlscan.rl"
+
+ if ( cs == RagelScan_error ) {
+ /* Machine failed before finding a token. */
+ cerr << "PARSE ERROR" << endl;
+ exit(1);
+ }
+
+ if ( ts == 0 )
+ have = 0;
+ else {
+ /* There is a prefix to preserve, shift it over. */
+ have = pe - ts;
+ memmove( inbuf, ts, have );
+ te = inbuf + (te-ts);
+ ts = inbuf;
+ }
+ }
+ return 0;
+}
diff --git a/examples/rlscan.rl b/examples/rlscan.rl
new file mode 100644
index 0000000..d4d4bf9
--- /dev/null
+++ b/examples/rlscan.rl
@@ -0,0 +1,300 @@
+/*
+ * Lexes Ragel input files.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+using namespace std;
+
+void escapeXML( char *data )
+{
+ while ( *data != 0 ) {
+ switch ( *data ) {
+ case '<': cout << "&lt;"; break;
+ case '>': cout << "&gt;"; break;
+ case '&': cout << "&amp;"; break;
+ default: cout << *data; break;
+ }
+ data += 1;
+ }
+}
+
+void escapeXML( char c )
+{
+ switch ( c ) {
+ case '<': cout << "&lt;"; break;
+ case '>': cout << "&gt;"; break;
+ case '&': cout << "&amp;"; break;
+ default: cout << c; break;
+ }
+}
+
+void escapeXML( char *data, int len )
+{
+ for ( char *end = data + len; data != end; data++ ) {
+ switch ( *data ) {
+ case '<': cout << "&lt;"; break;
+ case '>': cout << "&gt;"; break;
+ case '&': cout << "&amp;"; break;
+ default: cout << *data; break;
+ }
+ }
+}
+
+inline void write( const char *data )
+{
+ cout << data;
+}
+
+inline void write( char c )
+{
+ cout << c;
+}
+
+inline void write( char *data, int len )
+{
+ cout.write( data, len );
+}
+
+
+%%{
+ machine RagelScan;
+
+ word = [a-zA-Z_][a-zA-Z_0-9]*;
+ integer = [0-9]+;
+ hex = '0x' [0-9a-fA-F] [0-9a-fA-F]*;
+
+ default = ^0;
+ EOF = 0;
+
+ # Handles comments in outside code and inline blocks.
+ c_comment :=
+ ( default* :>> '*/' )
+ ${ escapeXML( fc ); }
+ @{ fret; };
+
+ action emit {
+ escapeXML( ts, te-ts );
+ }
+
+ #
+ # Inline action code
+ #
+
+ ilscan := |*
+
+ "'" ( [^'\\] | /\\./ )* "'" => emit;
+ '"' ( [^"\\] | /\\./ )* '"' => emit;
+ '/*' {
+ write( "/*" );
+ fcall c_comment;
+ };
+ '//' [^\n]* '\n' => emit;
+
+ '{' {
+ write( '{' );
+ inline_depth += 1;
+ };
+
+ '}' {
+ write( '}' );
+ /* If dropping down to the last } then return
+ * to ragel code. */
+ if ( --inline_depth == 0 ) {
+ write( "</inline>\n" );
+ fgoto rlscan;
+ }
+ };
+
+ default => { escapeXML( *ts ); };
+ *|;
+
+ #
+ # Ragel Tokens
+ #
+
+ rlscan := |*
+ '}%%' {
+ if ( !single_line ) {
+ write( "</section>\n" );
+ fgoto main;
+ }
+ };
+
+ '\n' {
+ if ( single_line ) {
+ write( "</section>\n" );
+ fgoto main;
+ }
+ };
+
+ # Word
+ word {
+ write( "<word>" );
+ write( ts, te-ts );
+ write( "</word>\n" );
+ };
+
+ # Decimal integer.
+ integer {
+ write( "<int>" );
+ write( ts, te-ts );
+ write( "</int>\n" );
+ };
+
+ # Hexidecimal integer.
+ hex {
+ write( "<hex>" );
+ write( ts, te-ts );
+ write( "</hex>\n" );
+ };
+
+ # Consume comments.
+ '#' [^\n]* '\n';
+
+ # Single literal string.
+ "'" ( [^'\\] | /\\./ )* "'" {
+ write( "<single_lit>" );
+ escapeXML( ts, te-ts );
+ write( "</single_lit>\n" );
+ };
+
+ # Double literal string.
+ '"' ( [^"\\] | /\\./ )* '"' {
+ write( "<double_lit>" );
+ escapeXML( ts, te-ts );
+ write( "</double_lit>\n" );
+ };
+
+ # Or literal.
+ '[' ( [^\]\\] | /\\./ )* ']' {
+ write( "<or_lit>" );
+ escapeXML( ts, te-ts );
+ write( "</or_lit>\n" );
+ };
+
+ # Regex Literal.
+ '/' ( [^/\\] | /\\./ ) * '/' {
+ write( "<re_lit>" );
+ escapeXML( ts, te-ts );
+ write( "</re_lit>\n" );
+ };
+
+ # Open an inline block
+ '{' {
+ inline_depth = 1;
+ write( "<inline>{" );
+ fgoto ilscan;
+ };
+
+ punct {
+ write( "<symbol>" );
+ escapeXML( fc );
+ write( "</symbol>\n" );
+ };
+
+ default;
+ *|;
+
+ #
+ # Outside code.
+ #
+
+ main := |*
+
+ "'" ( [^'\\] | /\\./ )* "'" => emit;
+ '"' ( [^"\\] | /\\./ )* '"' => emit;
+
+ '/*' {
+ escapeXML( ts, te-ts );
+ fcall c_comment;
+ };
+
+ '//' [^\n]* '\n' => emit;
+
+ '%%{' {
+ write( "<section>\n" );
+ single_line = false;
+ fgoto rlscan;
+ };
+
+ '%%' {
+ write( "<section>\n" );
+ single_line = true;
+ fgoto rlscan;
+ };
+
+ default {
+ escapeXML( *ts );
+ };
+
+ # EOF.
+ EOF;
+ *|;
+}%%
+
+%% write data nofinal;
+
+#define BUFSIZE 2048
+
+int main()
+{
+ std::ios::sync_with_stdio(false);
+
+ int cs, act;
+ char *ts, *te;
+ int stack[1], top;
+
+ static char inbuf[BUFSIZE];
+ bool single_line = false;
+ int inline_depth = 0;
+
+ %% write init;
+
+ bool done = false;
+ int have = 0;
+ while ( !done ) {
+ /* How much space is in the buffer? */
+ int space = BUFSIZE - have;
+ if ( space == 0 ) {
+ /* Buffer is full. */
+ cerr << "TOKEN TOO BIG" << endl;
+ exit(1);
+ }
+
+ /* Read in a block. */
+ char *p = inbuf + have;
+ cin.read( p, space );
+ int len = cin.gcount();
+ char *pe = p + len;
+ char *eof = 0;
+
+ /* Check for EOF. */
+ if ( len == 0 ) {
+ eof = pe;
+ done = true;
+ }
+
+ %% write exec;
+
+ if ( cs == RagelScan_error ) {
+ /* Machine failed before finding a token. */
+ cerr << "PARSE ERROR" << endl;
+ exit(1);
+ }
+
+ if ( ts == 0 )
+ have = 0;
+ else {
+ /* There is a prefix to preserve, shift it over. */
+ have = pe - ts;
+ memmove( inbuf, ts, have );
+ te = inbuf + (te-ts);
+ ts = inbuf;
+ }
+ }
+ return 0;
+}
diff --git a/examples/statechart.cpp b/examples/statechart.cpp
new file mode 100644
index 0000000..afe3b9c
--- /dev/null
+++ b/examples/statechart.cpp
@@ -0,0 +1,187 @@
+
+#line 1 "statechart.rl"
+/*
+ * Demonstrate the use of labels, the epsilon operator, and the join operator
+ * for creating machines using the named state and transition list paradigm.
+ * This implementes the same machine as the atoi example.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+using namespace std;
+
+struct StateChart
+{
+ bool neg;
+ int val;
+ int cs;
+
+ int init( );
+ int execute( const char *data, int len );
+ int finish( );
+};
+
+
+#line 66 "statechart.rl"
+
+
+
+#line 33 "statechart.cpp"
+static const int StateChart_start = 3;
+static const int StateChart_first_final = 3;
+static const int StateChart_error = 0;
+
+static const int StateChart_en_main = 3;
+
+
+#line 69 "statechart.rl"
+
+int StateChart::init( )
+{
+ neg = false;
+ val = false;
+
+#line 48 "statechart.cpp"
+ {
+ cs = StateChart_start;
+ }
+
+#line 75 "statechart.rl"
+ return 1;
+}
+
+int StateChart::execute( const char *data, int len )
+{
+ const char *p = data;
+ const char *pe = data + len;
+
+
+#line 63 "statechart.cpp"
+ {
+ if ( p == pe )
+ goto _test_eof;
+ switch ( cs )
+ {
+tr2:
+#line 41 "statechart.rl"
+ {
+ if ( neg )
+ val = -1 * val;
+ }
+#line 65 "statechart.rl"
+ { cout << val << endl; }
+ goto st3;
+st3:
+ if ( ++p == pe )
+ goto _test_eof3;
+case 3:
+#line 82 "statechart.cpp"
+ switch( (*p) ) {
+ case 43: goto tr3;
+ case 45: goto tr4;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr5;
+ goto st0;
+st0:
+cs = 0;
+ goto _out;
+tr3:
+#line 28 "statechart.rl"
+ {
+ neg = false;
+ val = 0;
+ }
+ goto st1;
+tr4:
+#line 28 "statechart.rl"
+ {
+ neg = false;
+ val = 0;
+ }
+#line 33 "statechart.rl"
+ {
+ neg = true;
+ }
+ goto st1;
+st1:
+ if ( ++p == pe )
+ goto _test_eof1;
+case 1:
+#line 115 "statechart.cpp"
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr0;
+ goto st0;
+tr0:
+#line 37 "statechart.rl"
+ {
+ val = val * 10 + ((*p) - '0');
+ }
+ goto st2;
+tr5:
+#line 28 "statechart.rl"
+ {
+ neg = false;
+ val = 0;
+ }
+#line 37 "statechart.rl"
+ {
+ val = val * 10 + ((*p) - '0');
+ }
+ goto st2;
+st2:
+ if ( ++p == pe )
+ goto _test_eof2;
+case 2:
+#line 140 "statechart.cpp"
+ if ( (*p) == 10 )
+ goto tr2;
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr0;
+ goto st0;
+ }
+ _test_eof3: cs = 3; goto _test_eof;
+ _test_eof1: cs = 1; goto _test_eof;
+ _test_eof2: cs = 2; goto _test_eof;
+
+ _test_eof: {}
+ _out: {}
+ }
+
+#line 84 "statechart.rl"
+
+ if ( cs == StateChart_error )
+ return -1;
+ if ( cs >= StateChart_first_final )
+ return 1;
+ return 0;
+}
+
+int StateChart::finish( )
+{
+ if ( cs == StateChart_error )
+ return -1;
+ if ( cs >= StateChart_first_final )
+ return 1;
+ return 0;
+}
+
+
+#define BUFSIZE 1024
+
+int main()
+{
+ char buf[BUFSIZE];
+
+ StateChart atoi;
+ atoi.init();
+ while ( fgets( buf, sizeof(buf), stdin ) != 0 ) {
+ atoi.execute( buf, strlen(buf) );
+ }
+ if ( atoi.finish() <= 0 )
+ cerr << "statechart: error: parsing input" << endl;
+ return 0;
+}
diff --git a/examples/statechart.rl b/examples/statechart.rl
new file mode 100644
index 0000000..a04471b
--- /dev/null
+++ b/examples/statechart.rl
@@ -0,0 +1,116 @@
+/*
+ * Demonstrate the use of labels, the epsilon operator, and the join operator
+ * for creating machines using the named state and transition list paradigm.
+ * This implementes the same machine as the atoi example.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+using namespace std;
+
+struct StateChart
+{
+ bool neg;
+ int val;
+ int cs;
+
+ int init( );
+ int execute( const char *data, int len );
+ int finish( );
+};
+
+%%{
+ machine StateChart;
+
+ action begin {
+ neg = false;
+ val = 0;
+ }
+
+ action see_neg {
+ neg = true;
+ }
+
+ action add_digit {
+ val = val * 10 + (fc - '0');
+ }
+
+ action finish {
+ if ( neg )
+ val = -1 * val;
+ }
+
+ atoi = (
+ start: (
+ '-' @see_neg ->om_num |
+ '+' ->om_num |
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # One or more nums.
+ om_num: (
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # Zero ore more nums.
+ more_nums: (
+ [0-9] @add_digit ->more_nums |
+ '' -> final
+ )
+ ) >begin %finish;
+
+ main := ( atoi '\n' @{ cout << val << endl; } )*;
+}%%
+
+%% write data;
+
+int StateChart::init( )
+{
+ neg = false;
+ val = false;
+ %% write init;
+ return 1;
+}
+
+int StateChart::execute( const char *data, int len )
+{
+ const char *p = data;
+ const char *pe = data + len;
+
+ %% write exec;
+
+ if ( cs == StateChart_error )
+ return -1;
+ if ( cs >= StateChart_first_final )
+ return 1;
+ return 0;
+}
+
+int StateChart::finish( )
+{
+ if ( cs == StateChart_error )
+ return -1;
+ if ( cs >= StateChart_first_final )
+ return 1;
+ return 0;
+}
+
+
+#define BUFSIZE 1024
+
+int main()
+{
+ char buf[BUFSIZE];
+
+ StateChart atoi;
+ atoi.init();
+ while ( fgets( buf, sizeof(buf), stdin ) != 0 ) {
+ atoi.execute( buf, strlen(buf) );
+ }
+ if ( atoi.finish() <= 0 )
+ cerr << "statechart: error: parsing input" << endl;
+ return 0;
+}