├── .gitignore ├── AUTHORS ├── COPYING ├── CREDITS ├── ChangeLog ├── Makefile.am ├── README ├── TODO ├── aapl ├── .gitignore ├── COPYING ├── Makefile.am ├── README ├── avlbasic.h ├── avlcommon.h ├── avlibasic.h ├── avlikeyless.h ├── avlimap.h ├── avlimel.h ├── avlimelkey.h ├── avliset.h ├── avlitree.h ├── avlkeyless.h ├── avlmap.h ├── avlmel.h ├── avlmelkey.h ├── avlset.h ├── avltree.h ├── bstcommon.h ├── bstmap.h ├── bstset.h ├── bsttable.h ├── bubblesort.h ├── compare.h ├── dlcommon.h ├── dlist.h ├── dlistmel.h ├── dlistval.h ├── insertsort.h ├── mergesort.h ├── quicksort.h ├── resize.h ├── sbstmap.h ├── sbstset.h ├── sbsttable.h ├── svector.h ├── table.h └── vector.h ├── autogen.sh ├── configure.in ├── contrib ├── .gitignore ├── Makefile.am ├── ragel.m4 ├── ragel.make └── unicode2ragel.rb ├── doc ├── .gitignore ├── Makefile.am ├── RELEASE_NOTES_V2 ├── RELEASE_NOTES_V3 ├── RELEASE_NOTES_V4 ├── RELEASE_NOTES_V5 ├── RELEASE_NOTES_V6 ├── bmconcat.fig ├── bmnull.fig ├── bmnum.fig ├── bmor.fig ├── bmrange.fig ├── bmregex.fig ├── comments1.fig ├── comments2.fig ├── conds1.fig ├── conds2.fig ├── dropdown.fig ├── entryguard.fig ├── exaction.fig ├── exallact.fig ├── exconcat.fig ├── exdoneact.fig ├── exinter.fig ├── exnegate.fig ├── exoption.fig ├── exor.fig ├── exoutact1.fig ├── exoutact2.fig ├── explus.fig ├── exstact.fig ├── exstar.fig ├── exstrongsubtr.fig ├── exsubtr.fig ├── extract.awk ├── finguard.fig ├── fixbackbox.awk ├── genfigs.sh ├── leftguard.fig ├── lines1.fig ├── lines2.fig ├── lmkleene.fig ├── opconcat.fig ├── opor.fig ├── opstar.fig ├── ragel-guide.tex ├── ragel.1.in ├── smallscanner.fig └── stembed.fig ├── examples ├── .gitignore ├── Makefile.am ├── README ├── atoi.rl ├── awkemu.rl ├── awkequiv.awk ├── clang.rl ├── concurrent.rl ├── cppscan.lex ├── cppscan.rec ├── cppscan.rl ├── format.rl ├── go │ ├── .gitignore │ ├── Makefile │ ├── README │ ├── atoi.rl │ ├── rpn.rl │ ├── url.rl │ └── url_authority.rl ├── gotocallret.rl ├── mailbox.rl ├── ocaml │ ├── .gitignore │ ├── Makefile │ ├── README │ ├── atoi.rl │ ├── clang.rl │ ├── cond.rl │ ├── gotocallret.rl │ ├── rpn.rl │ ├── scan1.rl │ ├── scan2.rl │ ├── t.ml │ ├── test.ml │ ├── url.rl │ └── url_authority.rl ├── params.rl ├── pullscan.rl ├── rlscan.rl ├── rust │ ├── .gitignore │ ├── Makefile │ ├── README │ ├── atoi.rl │ ├── clang.rl │ ├── concurrent.rl │ ├── gotocallret.rl │ ├── rpn.rl │ ├── scan1.rl │ ├── scan2.rl │ ├── url.rl │ └── url_authority.rl ├── statechart.rl └── uri.rl ├── ragel-d.vim ├── ragel-java.vim ├── ragel-m.vim ├── ragel.vim ├── ragel ├── .gitignore ├── Makefile.am ├── buffer.h ├── cdcodegen.cpp ├── cdcodegen.h ├── cdfflat.cpp ├── cdfflat.h ├── cdfgoto.cpp ├── cdfgoto.h ├── cdflat.cpp ├── cdflat.h ├── cdftable.cpp ├── cdftable.h ├── cdgoto.cpp ├── cdgoto.h ├── cdipgoto.cpp ├── cdipgoto.h ├── cdsplit.cpp ├── cdsplit.h ├── cdtable.cpp ├── cdtable.h ├── common.cpp ├── common.h ├── cscodegen.cpp ├── cscodegen.h ├── csfflat.cpp ├── csfflat.h ├── csfgoto.cpp ├── csfgoto.h ├── csflat.cpp ├── csflat.h ├── csftable.cpp ├── csftable.h ├── csgoto.cpp ├── csgoto.h ├── csipgoto.cpp ├── csipgoto.h ├── cssplit.cpp ├── cssplit.h ├── cstable.cpp ├── cstable.h ├── dotcodegen.cpp ├── dotcodegen.h ├── fsmap.cpp ├── fsmattach.cpp ├── fsmbase.cpp ├── fsmgraph.cpp ├── fsmgraph.h ├── fsmmin.cpp ├── fsmstate.cpp ├── gendata.cpp ├── gendata.h ├── gocodegen.cpp ├── gocodegen.h ├── gofflat.cpp ├── gofflat.h ├── gofgoto.cpp ├── gofgoto.h ├── goflat.cpp ├── goflat.h ├── goftable.cpp ├── goftable.h ├── gogoto.cpp ├── gogoto.h ├── goipgoto.cpp ├── goipgoto.h ├── gotable.cpp ├── gotable.h ├── gotablish.cpp ├── gotablish.h ├── inputdata.cpp ├── inputdata.h ├── javacodegen.cpp ├── javacodegen.h ├── main.cpp ├── mlcodegen.cpp ├── mlcodegen.h ├── mlfflat.cpp ├── mlfflat.h ├── mlflat.cpp ├── mlflat.h ├── mlftable.cpp ├── mlftable.h ├── mlgoto.cpp ├── mlgoto.h ├── mltable.cpp ├── mltable.h ├── parsedata.cpp ├── parsedata.h ├── parsetree.cpp ├── parsetree.h ├── pcheck.h ├── ragel.h ├── rbxgoto.cpp ├── rbxgoto.h ├── redfsm.cpp ├── redfsm.h ├── rlparse.kh ├── rlparse.kl ├── rlscan.h ├── rlscan.rl ├── rubycodegen.cpp ├── rubycodegen.h ├── rubyfflat.cpp ├── rubyfflat.h ├── rubyflat.cpp ├── rubyflat.h ├── rubyftable.cpp ├── rubyftable.h ├── rubytable.cpp ├── rubytable.h ├── rustcodegen.cc ├── rustcodegen.h ├── xmlcodegen.cpp ├── xmlcodegen.h ├── xmlparse.kh ├── xmlparse.kl ├── xmlscan.rl └── xmltags.gperf └── test ├── .gitignore ├── Makefile.am ├── README ├── atoi1.rl ├── atoi2.rl ├── atoi3.rl ├── awkemu.rl ├── builtin.rl ├── call1.rl ├── call2.rl ├── call3.rl ├── checkeofact.txl ├── clang1.rl ├── clang2.rl ├── clang3.rl ├── clang4.rl ├── cond1.rl ├── cond2.rl ├── cond3.rl ├── cond4.rl ├── cond5.rl ├── cond6.rl ├── cond7.rl ├── cppscan1.h ├── cppscan1.rl ├── cppscan2.rl ├── cppscan3.rl ├── cppscan4.rl ├── cppscan5.rl ├── cppscan6.rl ├── element1.rl ├── element2.rl ├── element3.rl ├── eofact.h ├── eofact.rl ├── erract1.rl ├── erract2.rl ├── erract3.rl ├── erract4.rl ├── erract5.rl ├── erract6.rl ├── erract7.rl ├── erract8.rl ├── erract9.rl ├── export1.rl ├── export2.rl ├── export3.rl ├── export4.rl ├── fnext1.rl ├── forder1.rl ├── forder2.rl ├── forder3.rl ├── gotocallret1.rl ├── gotocallret2.rl ├── high1.rl ├── high2.rl ├── high3.rl ├── import1.rl ├── include1.rl ├── include2.rl ├── java1.rl ├── java2.rl ├── keller1.rl ├── langtrans_c.sh ├── langtrans_c.txl ├── langtrans_csharp.sh ├── langtrans_csharp.txl ├── langtrans_d.sh ├── langtrans_d.txl ├── langtrans_go.sh ├── langtrans_go.txl ├── langtrans_java.sh ├── langtrans_java.txl ├── langtrans_ruby.sh ├── langtrans_ruby.txl ├── lmgoto.rl ├── mailbox1.h ├── mailbox1.rl ├── mailbox2.rl ├── mailbox3.rl ├── minimize1.rl ├── patact.rl ├── range.rl ├── recdescent1.rl ├── recdescent2.rl ├── recdescent3.rl ├── repetition.rl ├── rlscan.rl ├── ruby1.rl ├── runtests.in ├── scan1.rl ├── scan2.rl ├── scan3.rl ├── scan4.rl ├── stateact1.rl ├── statechart1.rl ├── strings1.rl ├── strings2.h ├── strings2.rl ├── testcase.txl ├── tokstart1.rl ├── union.rl ├── xml.rl └── xmlcommon.rl /.gitignore: -------------------------------------------------------------------------------- 1 | /config.log 2 | /config.h 3 | /config.cache 4 | /config.status 5 | /Makefile 6 | /Makefile.in 7 | /configure 8 | /depcomp 9 | /missing 10 | /install-sh 11 | /aclocal.m4 12 | /autom4te.cache 13 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | See CREDITS. 2 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | 2 | Ragel State Machine Compiler -- CREDITS 3 | ======================================= 4 | 5 | 6 | * Ragel was designed and written by Adrian Thurston . 7 | 8 | Many others have helped out along the way. My apolgies to anyone who has been 9 | missed. 10 | 11 | * Many thanks to Arbor Networks for supporting development of Ragel. 12 | 13 | * Objective-C output and valuable feedback contributed by Erich Ocean. 14 | 15 | * D output and many great ideas contributed by Alan West. 16 | 17 | * Conditionals inspired by David Helder. 18 | 19 | * Java code generation contributions, bug reports, fixes, test cases 20 | and suggestions from Colin Fleming. 21 | 22 | * Useful discussions and bug reports due to Carlos Antunes. 23 | 24 | * Ruby code generation contributed by Victor Hugo Borja. 25 | 26 | * C# code generation contributed by Daniel Tang. 27 | 28 | * Go code generation contributed by Justine Tunney. Significantly expanded by 29 | Anton Ageev 30 | 31 | * D2 patch from Johannes Pfau. 32 | 33 | * OCaml patch from ygrek. 34 | 35 | * Feedback, Packaging, and Fixes provided by: 36 | 37 | Bob Tennent, Robert Lemmen, Tobias Jahn, Cris Bailiff, Buddy Betts, 38 | Scott Dixon, Steven Handerson, Michael Somos, Bob Paddock, Istvan Buki, 39 | David Drai, Matthias Rahlf, Zinx Verituse, Markus W. Weissmann, 40 | Marc Liyanage, Erich Ocean, Alan West, Steven Kibbler, Laurent Boulard, 41 | Jon Oberheide, David Helder, Lexington Luthor, Jason Jobe, Colin Fleming, 42 | Carlos Antunes, Steve Horne, Matt Mower, Josef Goettgens, Zed Shaw, 43 | Marcus Rueckert, Jeremy Hinegardner, Aaron Campbell, Josh Purinton, 44 | Judson Lester, Barry Arthur, Tim Potter, Ryan Phelps, David Waite, 45 | Kenny MacDermid, MenTaLguY, Manoj Rajagopalan, Tim Chklovski, 46 | Mikkel Fahnøe Jørgensen, Andrei Polushin, Evan Phoenix, David Balmain, 47 | Ross Thomas, Mitchell Foral, John D. Mitchell, Diego 'Flameeyes' Pettenò, 48 | Jose Quinteiro, William Morgan, _why, Iñaki Baz Castillo, Attila Sztupák, 49 | Ismael Luceno, Josh Stern, Denis Naumov, Anton Ageev, Kamil Klimkiewicz 50 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | SUBDIRS = ragel doc 3 | DIST_SUBDIRS = $(SUBDIRS) aapl contrib examples test 4 | 5 | dist_doc_DATA = CREDITS ChangeLog 6 | EXTRA_DIST = ragel.vim 7 | 8 | # This file is checked for by the configure script and its existence causes the 9 | # parsers and the manual to not be built when the distribution is built. 10 | dist-hook: 11 | ( \ 12 | echo "#!/bin/sh"; \ 13 | echo ""; \ 14 | echo "# Change to yes to enable building of parsers or manual. Reconfigure"; \ 15 | echo "# afterwards."; \ 16 | echo "build_parsers=no;"; \ 17 | echo "build_manual=no;"; \ 18 | ) > $(distdir)/DIST 19 | 20 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | Ragel State Machine Compiler -- README 3 | ====================================== 4 | 5 | 1. Build Requirements 6 | --------------------- 7 | 8 | * Make 9 | * g++ 10 | 11 | If you would like to modify Ragel and need to build Ragel's scanners and 12 | parsers from the specifications then set "build_parsers=yes" the DIST file and 13 | reconfigure. This variable is normally set to "no" in the distribution tarballs 14 | and "yes" in version control. You will need the following programs: 15 | 16 | * ragel (the most recent version) 17 | * kelbt (the most recent version) 18 | 19 | To build the user guide set "build_manual=yes" in the DIST file and 20 | reconfigure. You will need the following extra programs: 21 | 22 | * fig2dev 23 | * pdflatex 24 | 25 | 2. Compilation and Installation 26 | ------------------------------- 27 | 28 | Ragel uses autoconf and automake. 29 | 30 | $ ./configure --prefix=PREFIX 31 | $ make 32 | $ make install 33 | -------------------------------------------------------------------------------- /aapl/.gitignore: -------------------------------------------------------------------------------- 1 | /Makefile.in 2 | /Makefile 3 | -------------------------------------------------------------------------------- /aapl/Makefile.am: -------------------------------------------------------------------------------- 1 | noinst_HEADERS = \ 2 | avlbasic.h avlimel.h avlmap.h bstcommon.h compare.h insertsort.h \ 3 | sbstset.h avlcommon.h avlimelkey.h avlmel.h bstmap.h dlcommon.h \ 4 | mergesort.h sbsttable.h avlibasic.h avliset.h avlmelkey.h bstset.h \ 5 | dlist.h quicksort.h svector.h avlikeyless.h avlitree.h avlset.h \ 6 | bsttable.h dlistmel.h resize.h table.h avlimap.h avlkeyless.h avltree.h \ 7 | bubblesort.h dlistval.h sbstmap.h vector.h 8 | 9 | EXTRA_DIST = README COPYING 10 | 11 | -------------------------------------------------------------------------------- /aapl/README: -------------------------------------------------------------------------------- 1 | This directory contains the Aapl source distribution. For the 2 | documentation, build scripts, test programs, ChangeLog, etc. get the 3 | aapldev package. 4 | 5 | AaplDev and other information about Aapl is available from 6 | http://www.elude.ca/aapl/ 7 | -------------------------------------------------------------------------------- /aapl/avlbasic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002 Adrian Thurston 3 | */ 4 | 5 | /* This file is part of Aapl. 6 | * 7 | * Aapl is free software; you can redistribute it and/or modify it under the 8 | * terms of the GNU Lesser General Public License as published by the Free 9 | * Software Foundation; either version 2.1 of the License, or (at your option) 10 | * any later version. 11 | * 12 | * Aapl is distributed in the hope that it will be useful, but WITHOUT ANY 13 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 15 | * more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Aapl; if not, write to the Free Software Foundation, Inc., 59 19 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #ifndef _AAPL_AVLBASIC_H 23 | #define _AAPL_AVLBASIC_H 24 | 25 | #include "compare.h" 26 | 27 | /** 28 | * \addtogroup avltree 29 | * @{ 30 | */ 31 | 32 | /** 33 | * \class AvlBasic 34 | * \brief AVL Tree in which the entire element structure is the key. 35 | * 36 | * AvlBasic is an AVL tree that does not distinguish between the element that 37 | * it contains and the key. The entire element structure is the key that is 38 | * used to compare the relative ordering of elements. This is similar to the 39 | * BstSet structure. 40 | * 41 | * AvlBasic does not assume ownership of elements in the tree. Items must be 42 | * explicitly de-allocated. 43 | */ 44 | 45 | /*@}*/ 46 | 47 | #define BASE_EL(name) name 48 | #define BASEKEY(name) name 49 | #define AVLMEL_CLASSDEF class Element, class Compare 50 | #define AVLMEL_TEMPDEF class Element, class Compare 51 | #define AVLMEL_TEMPUSE Element, Compare 52 | #define AvlTree AvlBasic 53 | #define AVL_BASIC 54 | 55 | #include "avlcommon.h" 56 | 57 | #undef BASE_EL 58 | #undef BASEKEY 59 | #undef AVLMEL_CLASSDEF 60 | #undef AVLMEL_TEMPDEF 61 | #undef AVLMEL_TEMPUSE 62 | #undef AvlTree 63 | #undef AVL_BASIC 64 | 65 | #endif /* _AAPL_AVLBASIC_H */ 66 | -------------------------------------------------------------------------------- /aapl/avlibasic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002 Adrian Thurston 3 | */ 4 | 5 | /* This file is part of Aapl. 6 | * 7 | * Aapl is free software; you can redistribute it and/or modify it under the 8 | * terms of the GNU Lesser General Public License as published by the Free 9 | * Software Foundation; either version 2.1 of the License, or (at your option) 10 | * any later version. 11 | * 12 | * Aapl is distributed in the hope that it will be useful, but WITHOUT ANY 13 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 15 | * more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Aapl; if not, write to the Free Software Foundation, Inc., 59 19 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #ifndef _AAPL_AVLIBASIC_H 23 | #define _AAPL_AVLIBASIC_H 24 | 25 | #include "compare.h" 26 | 27 | /** 28 | * \addtogroup avlitree 29 | * @{ 30 | */ 31 | 32 | /** 33 | * \class AvliBasic 34 | * \brief Linked AVL Tree in which the entire element structure is the key. 35 | * 36 | * AvliBasic is a linked AVL tree that does not distinguish between the 37 | * element that it contains and the key. The entire element structure is the 38 | * key that is used to compare the relative ordering of elements. This is 39 | * similar to the BstSet structure. 40 | * 41 | * AvliBasic does not assume ownership of elements in the tree. Items must be 42 | * explicitly de-allocated. 43 | */ 44 | 45 | /*@}*/ 46 | 47 | #define BASE_EL(name) name 48 | #define BASEKEY(name) name 49 | #define AVLMEL_CLASSDEF class Element, class Compare 50 | #define AVLMEL_TEMPDEF class Element, class Compare 51 | #define AVLMEL_TEMPUSE Element, Compare 52 | #define AvlTree AvliBasic 53 | #define AVL_BASIC 54 | #define WALKABLE 55 | 56 | #include "avlcommon.h" 57 | 58 | #undef BASE_EL 59 | #undef BASEKEY 60 | #undef AVLMEL_CLASSDEF 61 | #undef AVLMEL_TEMPDEF 62 | #undef AVLMEL_TEMPUSE 63 | #undef AvlTree 64 | #undef AVL_BASIC 65 | #undef WALKABLE 66 | 67 | #endif /* _AAPL_AVLIBASIC_H */ 68 | -------------------------------------------------------------------------------- /aapl/avlikeyless.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002, 2003 Adrian Thurston 3 | */ 4 | 5 | /* This file is part of Aapl. 6 | * 7 | * Aapl is free software; you can redistribute it and/or modify it under the 8 | * terms of the GNU Lesser General Public License as published by the Free 9 | * Software Foundation; either version 2.1 of the License, or (at your option) 10 | * any later version. 11 | * 12 | * Aapl is distributed in the hope that it will be useful, but WITHOUT ANY 13 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 15 | * more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Aapl; if not, write to the Free Software Foundation, Inc., 59 19 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #ifndef _AAPL_AVLIKEYLESS_H 23 | #define _AAPL_AVLIKEYLESS_H 24 | 25 | #include "compare.h" 26 | #include "dlistmel.h" 27 | 28 | /** 29 | * \addtogroup avlitree 30 | * @{ 31 | */ 32 | 33 | /** 34 | * \class AvliKeyless 35 | * \brief Linked AVL tree that has no insert/find/remove functions that take a 36 | * key. 37 | * 38 | * AvliKeyless is an implementation of the AVL tree rebalancing functionality 39 | * only. It provides the common code for the tiny AVL tree implementations. 40 | */ 41 | 42 | /*@}*/ 43 | 44 | #define BASE_EL(name) name 45 | #define BASELIST DListMel< Element, AvliTreeEl > 46 | #define AVLMEL_CLASSDEF class Element 47 | #define AVLMEL_TEMPDEF class Element 48 | #define AVLMEL_TEMPUSE Element 49 | #define AvlTree AvliKeyless 50 | #define WALKABLE 51 | #define AVL_KEYLESS 52 | 53 | #include "avlcommon.h" 54 | 55 | #undef BASE_EL 56 | #undef BASELIST 57 | #undef AVLMEL_CLASSDEF 58 | #undef AVLMEL_TEMPDEF 59 | #undef AVLMEL_TEMPUSE 60 | #undef AvlTree 61 | #undef WALKABLE 62 | #undef AVL_KEYLESS 63 | 64 | #endif /* _AAPL_AVLIKEYLESS_H */ 65 | -------------------------------------------------------------------------------- /aapl/avliset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002 Adrian Thurston 3 | */ 4 | 5 | /* This file is part of Aapl. 6 | * 7 | * Aapl is free software; you can redistribute it and/or modify it under the 8 | * terms of the GNU Lesser General Public License as published by the Free 9 | * Software Foundation; either version 2.1 of the License, or (at your option) 10 | * any later version. 11 | * 12 | * Aapl is distributed in the hope that it will be useful, but WITHOUT ANY 13 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 15 | * more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Aapl; if not, write to the Free Software Foundation, Inc., 59 19 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #ifndef _AAPL_AVLISET_H 23 | #define _AAPL_AVLISET_H 24 | 25 | #include "compare.h" 26 | #include "dlist.h" 27 | 28 | /** 29 | * \addtogroup avlitree 30 | * @{ 31 | */ 32 | 33 | /** 34 | * \class AvliSet 35 | * \brief Linked Key-only oriented tree. 36 | * 37 | * AvliSet stores only keys in elements that are managed by the tree. AvliSet 38 | * requires that a Key type and a class containing a compare() routine 39 | * for Key be given. Items are inserted with just a key value. 40 | * 41 | * AvliSet assumes all elements in the tree are allocated on the heap and are 42 | * to be managed by the tree. This means that the class destructor will delete 43 | * the contents of the tree. A deep copy will cause existing elements to be 44 | * deleted first. 45 | * 46 | * \include ex_avliset.cpp 47 | */ 48 | 49 | /*@}*/ 50 | 51 | #define AVLTREE_SET 52 | #define BASE_EL(name) name 53 | #define BASEKEY(name) name 54 | #define BASELIST DList< AvliSetEl > 55 | #define AVLMEL_CLASSDEF class Key, class Compare = CmpOrd 56 | #define AVLMEL_TEMPDEF class Key, class Compare 57 | #define AVLMEL_TEMPUSE Key, Compare 58 | #define AvlTree AvliSet 59 | #define Element AvliSetEl 60 | #define WALKABLE 61 | 62 | #include "avlcommon.h" 63 | 64 | #undef AVLTREE_SET 65 | #undef BASE_EL 66 | #undef BASEKEY 67 | #undef BASELIST 68 | #undef AVLMEL_CLASSDEF 69 | #undef AVLMEL_TEMPDEF 70 | #undef AVLMEL_TEMPUSE 71 | #undef AvlTree 72 | #undef Element 73 | #undef WALKABLE 74 | 75 | #endif /* _AAPL_AVLISET_H */ 76 | -------------------------------------------------------------------------------- /aapl/avlkeyless.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002, 2003 Adrian Thurston 3 | */ 4 | 5 | /* This file is part of Aapl. 6 | * 7 | * Aapl is free software; you can redistribute it and/or modify it under the 8 | * terms of the GNU Lesser General Public License as published by the Free 9 | * Software Foundation; either version 2.1 of the License, or (at your option) 10 | * any later version. 11 | * 12 | * Aapl is distributed in the hope that it will be useful, but WITHOUT ANY 13 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 15 | * more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Aapl; if not, write to the Free Software Foundation, Inc., 59 19 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #ifndef _AAPL_AVLKEYLESS_H 23 | #define _AAPL_AVLKEYLESS_H 24 | 25 | #include "compare.h" 26 | 27 | /** 28 | * \addtogroup avltree 29 | * @{ 30 | */ 31 | 32 | /** 33 | * \class AvlKeyless 34 | * \brief AVL tree that has no insert/find/remove functions that take a key. 35 | * 36 | * AvlKeyless is an implementation of the AVL tree rebalancing functionality 37 | * only. It provides the common code for the tiny AVL tree implementations. 38 | */ 39 | 40 | /*@}*/ 41 | 42 | #define BASE_EL(name) name 43 | #define AVLMEL_CLASSDEF class Element 44 | #define AVLMEL_TEMPDEF class Element 45 | #define AVLMEL_TEMPUSE Element 46 | #define AvlTree AvlKeyless 47 | #define AVL_KEYLESS 48 | 49 | #include "avlcommon.h" 50 | 51 | #undef BASE_EL 52 | #undef AVLMEL_CLASSDEF 53 | #undef AVLMEL_TEMPDEF 54 | #undef AVLMEL_TEMPUSE 55 | #undef AvlTree 56 | #undef AVL_KEYLESS 57 | 58 | #endif /* _AAPL_AVLKEYLESS_H */ 59 | -------------------------------------------------------------------------------- /aapl/avlmap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002 Adrian Thurston 3 | */ 4 | 5 | /* This file is part of Aapl. 6 | * 7 | * Aapl is free software; you can redistribute it and/or modify it under the 8 | * terms of the GNU Lesser General Public License as published by the Free 9 | * Software Foundation; either version 2.1 of the License, or (at your option) 10 | * any later version. 11 | * 12 | * Aapl is distributed in the hope that it will be useful, but WITHOUT ANY 13 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 15 | * more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Aapl; if not, write to the Free Software Foundation, Inc., 59 19 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #ifndef _AAPL_AVLMAP_H 23 | #define _AAPL_AVLMAP_H 24 | 25 | #include "compare.h" 26 | 27 | /** 28 | * \addtogroup avltree 29 | * @{ 30 | */ 31 | 32 | /** 33 | * \class AvlMap 34 | * \brief Key and value oriented AVL tree. 35 | * 36 | * AvlMap stores key and value pairs in elements that managed by the tree. It 37 | * is intendend to be similar to map template found in the STL. AvlMap 38 | * requires that a Key type, a Value type, and a class containing a compare() 39 | * routine for Key be given. Items can be inserted with just a key or with a 40 | * key and value pair. 41 | * 42 | * AvlMap assumes all elements in the tree are allocated on the heap and are 43 | * to be managed by the tree. This means that the class destructor will delete 44 | * the contents of the tree. A deep copy will cause existing elements to be 45 | * deleted first. 46 | * 47 | * \include ex_avlmap.cpp 48 | */ 49 | 50 | /*@}*/ 51 | 52 | #define AVLTREE_MAP 53 | #define BASE_EL(name) name 54 | #define BASEKEY(name) name 55 | #define AVLMEL_CLASSDEF class Key, class Value, class Compare = CmpOrd 56 | #define AVLMEL_TEMPDEF class Key, class Value, class Compare 57 | #define AVLMEL_TEMPUSE Key, Value, Compare 58 | #define AvlTree AvlMap 59 | #define Element AvlMapEl 60 | 61 | #include "avlcommon.h" 62 | 63 | #undef AVLTREE_MAP 64 | #undef BASE_EL 65 | #undef BASEKEY 66 | #undef AVLMEL_CLASSDEF 67 | #undef AVLMEL_TEMPDEF 68 | #undef AVLMEL_TEMPUSE 69 | #undef AvlTree 70 | #undef Element 71 | 72 | 73 | 74 | #endif /* _AAPL_AVLMAP_H */ 75 | -------------------------------------------------------------------------------- /aapl/avlset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002 Adrian Thurston 3 | */ 4 | 5 | /* This file is part of Aapl. 6 | * 7 | * Aapl is free software; you can redistribute it and/or modify it under the 8 | * terms of the GNU Lesser General Public License as published by the Free 9 | * Software Foundation; either version 2.1 of the License, or (at your option) 10 | * any later version. 11 | * 12 | * Aapl is distributed in the hope that it will be useful, but WITHOUT ANY 13 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 15 | * more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Aapl; if not, write to the Free Software Foundation, Inc., 59 19 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #ifndef _AAPL_AVLSET_H 23 | #define _AAPL_AVLSET_H 24 | 25 | #include "compare.h" 26 | 27 | /** 28 | * \addtogroup avltree 29 | * @{ 30 | */ 31 | 32 | /** 33 | * \class AvlSet 34 | * \brief Key-only oriented tree. 35 | * 36 | * AvlSet stores only keys in elements that are managed by the tree. AvlSet 37 | * requires that a Key type and a class containing a compare() routine 38 | * for Key be given. Items are inserted with just a key value. 39 | * 40 | * AvlSet assumes all elements in the tree are allocated on the heap and are 41 | * to be managed by the tree. This means that the class destructor will delete 42 | * the contents of the tree. A deep copy will cause existing elements to be 43 | * deleted first. 44 | * 45 | * \include ex_avlset.cpp 46 | */ 47 | 48 | /*@}*/ 49 | 50 | #define AVLTREE_SET 51 | #define BASE_EL(name) name 52 | #define BASEKEY(name) name 53 | #define AVLMEL_CLASSDEF class Key, class Compare = CmpOrd 54 | #define AVLMEL_TEMPDEF class Key, class Compare 55 | #define AVLMEL_TEMPUSE Key, Compare 56 | #define AvlTree AvlSet 57 | #define Element AvlSetEl 58 | 59 | #include "avlcommon.h" 60 | 61 | #undef AVLTREE_SET 62 | #undef BASE_EL 63 | #undef BASEKEY 64 | #undef AVLMEL_CLASSDEF 65 | #undef AVLMEL_TEMPDEF 66 | #undef AVLMEL_TEMPUSE 67 | #undef AvlTree 68 | #undef Element 69 | 70 | #endif /* _AAPL_AVLSET_H */ 71 | -------------------------------------------------------------------------------- /aapl/dlist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2001 Adrian Thurston 3 | */ 4 | 5 | /* This file is part of Aapl. 6 | * 7 | * Aapl is free software; you can redistribute it and/or modify it under the 8 | * terms of the GNU Lesser General Public License as published by the Free 9 | * Software Foundation; either version 2.1 of the License, or (at your option) 10 | * any later version. 11 | * 12 | * Aapl is distributed in the hope that it will be useful, but WITHOUT ANY 13 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 15 | * more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Aapl; if not, write to the Free Software Foundation, Inc., 59 19 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #ifndef _AAPL_DLIST_H 23 | #define _AAPL_DLIST_H 24 | 25 | #define BASE_EL(name) name 26 | #define DLMEL_TEMPDEF class Element 27 | #define DLMEL_TEMPUSE Element 28 | #define DList DList 29 | 30 | /** 31 | * \addtogroup dlist 32 | * @{ 33 | */ 34 | 35 | /** 36 | * \class DList 37 | * \brief Basic doubly linked list. 38 | * 39 | * DList is the standard by-structure list type. This class requires the 40 | * programmer to declare a list element type that has the necessary next and 41 | * previous pointers in it. This can be achieved by inheriting from the 42 | * DListEl class or by simply adding next and previous pointers directly into 43 | * the list element class. 44 | * 45 | * DList does not assume ownership of elements in the list. If the elements 46 | * are known to reside on the heap, the provided empty() routine can be used to 47 | * delete all elements, however the destructor will not call this routine, it 48 | * will simply abandon all the elements. It is up to the programmer to 49 | * explicitly de-allocate items when necessary. 50 | * 51 | * \include ex_dlist.cpp 52 | */ 53 | 54 | /*@}*/ 55 | 56 | #include "dlcommon.h" 57 | 58 | #undef BASE_EL 59 | #undef DLMEL_TEMPDEF 60 | #undef DLMEL_TEMPUSE 61 | #undef DList 62 | 63 | #endif /* _AAPL_DLIST_H */ 64 | 65 | -------------------------------------------------------------------------------- /aapl/dlistval.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002 Adrian Thurston 3 | */ 4 | 5 | /* This file is part of Aapl. 6 | * 7 | * Aapl is free software; you can redistribute it and/or modify it under the 8 | * terms of the GNU Lesser General Public License as published by the Free 9 | * Software Foundation; either version 2.1 of the License, or (at your option) 10 | * any later version. 11 | * 12 | * Aapl is distributed in the hope that it will be useful, but WITHOUT ANY 13 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 15 | * more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Aapl; if not, write to the Free Software Foundation, Inc., 59 19 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #ifndef _AAPL_DLISTVAL_H 23 | #define _AAPL_DLISTVAL_H 24 | 25 | /** 26 | * \addtogroup dlist 27 | * @{ 28 | */ 29 | 30 | /** 31 | * \class DListVal 32 | * \brief By-value doubly linked list. 33 | * 34 | * This class is a doubly linked list that does not require a list element 35 | * type to be declared. The user instead gives a type that is to be stored in 36 | * the list element. When inserting a new data item, the value is copied into 37 | * a newly allocated element. This list is inteded to behave and be utilized 38 | * like the list template found in the STL. 39 | * 40 | * DListVal is different from the other lists in that it allocates elements 41 | * itself. The raw element insert interface is still exposed for convenience, 42 | * however, the list assumes all elements in the list are allocated on the 43 | * heap and are to be managed by the list. The destructor WILL delete the 44 | * contents of the list. If the list is ever copied in from another list, the 45 | * existing contents are deleted first. This is in contrast to DList and 46 | * DListMel, which will never delete their contents to allow for statically 47 | * allocated elements. 48 | * 49 | * \include ex_dlistval.cpp 50 | */ 51 | 52 | /*@}*/ 53 | 54 | #define BASE_EL(name) name 55 | #define DLMEL_TEMPDEF class T 56 | #define DLMEL_TEMPUSE T 57 | #define DList DListVal 58 | #define Element DListValEl 59 | #define DOUBLELIST_VALUE 60 | 61 | #include "dlcommon.h" 62 | 63 | #undef BASE_EL 64 | #undef DLMEL_TEMPDEF 65 | #undef DLMEL_TEMPUSE 66 | #undef DList 67 | #undef Element 68 | #undef DOUBLELIST_VALUE 69 | 70 | #endif /* _AAPL_DLISTVAL_H */ 71 | 72 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | 4 | aclocal 5 | autoheader 6 | automake --foreign --add-missing 7 | autoconf 8 | -------------------------------------------------------------------------------- /contrib/.gitignore: -------------------------------------------------------------------------------- 1 | /Makefile.in 2 | /Makefile 3 | -------------------------------------------------------------------------------- /contrib/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | EXTRA_DIST = ragel.make ragel.m4 unicode2ragel.rb 3 | -------------------------------------------------------------------------------- /contrib/ragel.m4: -------------------------------------------------------------------------------- 1 | dnl Check for presence of the Ragel State Machine generator. 2 | dnl 3 | dnl This macro checks for the presence of the ragel tool in the system, 4 | dnl and whether the ragel tool is absolutely needed for a complete 5 | dnl build. 6 | dnl 7 | dnl To check for the need for Ragel, you have to provide the relative 8 | dnl path of a source file generated through Ragel: if the file is 9 | dnl present in the source tree, a missing ragel command will not cause 10 | dnl the configure to abort. 11 | 12 | AC_DEFUN([_RAGEL_VARS], [ 13 | AC_ARG_VAR([RAGEL], [Ragel generator command]) 14 | AC_ARG_VAR([RAGELFLAGS], [Ragel generator flags]) 15 | ]) 16 | 17 | AC_DEFUN([CHECK_RAGEL], [ 18 | AC_REQUIRE([_RAGEL_VARS]) 19 | AC_CHECK_PROG([RAGEL], [ragel], [ragel], [no]) 20 | 21 | dnl We set RAGEL to false so that it would execute the "false" 22 | dnl command if needed. 23 | AS_IF([test x"$RAGEL" = x"no"], 24 | [RAGEL=false], 25 | AS_IF([test x"$2" != "x"], 26 | [ragel_version=`$RAGEL --version | sed -n -e '1s:.*version \(@<:@0-9@:>@\.@<:@0-9@:>@\) .*:\1:p'` 27 | ragel_version_compare=`echo $ragel_version | tr -d .` 28 | ragel_wanted_version=`echo $2 | tr -d .` 29 | AS_IF([test $ragel_version_compare -lt $ragel_wanted_version], 30 | [AC_MSG_WARN([Found Ragel $ragel_version but Ragel $2 requested]) 31 | RAGEL=false 32 | ]) 33 | ])) 34 | 35 | dnl Only test the need if not found 36 | AS_IF([test x"$RAGEL" = x"false"], [ 37 | AC_MSG_CHECKING([whether we need ragel to regenerate sources]) 38 | AS_IF([test -a "${srcdir}/$1"], [ragel_needed=no], [ragel_needed=yes]) 39 | AC_MSG_RESULT([$ragel_needed]) 40 | 41 | AS_IF([test x"$ragel_needed" = x"yes"], 42 | [AC_MSG_ERROR([dnl 43 | You need Ragel to build from development sources. 44 | You can find Ragel at http://www.complang.org/ragel/dnl 45 | ])]) 46 | ]) 47 | ]) 48 | 49 | AC_DEFUN([CHECK_RAGEL_AM], [ 50 | CHECK_RAGEL([$1], [$2]) 51 | 52 | AM_CONDITIONAL([HAVE_RAGEL], [test x"$RAGEL" != x"false"]) 53 | ]) 54 | -------------------------------------------------------------------------------- /contrib/ragel.make: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | 3 | SUFFIXES = .rl 4 | 5 | .rl.c: 6 | $(RAGEL) $(RAGELFLAGS) -C $< -o $@ 7 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | /Makefile 2 | /Makefile.in 3 | /version.tex 4 | /ragel-guide.aux 5 | /ragel-guide.dvi 6 | /ragel-guide.log 7 | /ragel-guide.pdf 8 | /ragel-guide.out 9 | /ragel-guide.toc 10 | /ragel.1 11 | /exstact.pdf 12 | /explus.pdf 13 | /exallact.pdf 14 | /exstar.pdf 15 | /opconcat.pdf 16 | /exaction.pdf 17 | /exor.pdf 18 | /lmkleene.pdf 19 | /entryguard.pdf 20 | /bmor.pdf 21 | /finguard.pdf 22 | /bmnum.pdf 23 | /exinter.pdf 24 | /exallpri.pdf 25 | /stembed.pdf 26 | /exsubtr.pdf 27 | /exconcat.pdf 28 | /opstar.pdf 29 | /bmrange.pdf 30 | /opor.pdf 31 | /bmconcat.pdf 32 | /bmnull.pdf 33 | /bmregex.pdf 34 | /exstrongsubtr.pdf 35 | /exdonepri.pdf 36 | /exnegate.pdf 37 | /exfinact.pdf 38 | /exoption.pdf 39 | /exoutact1.pdf 40 | /exoutact2.pdf 41 | /lmkleene.pdf 42 | /ChangeLog.gz 43 | /smallscanner.pdf 44 | /lines1.pdf 45 | /lines2.pdf 46 | /comments1.pdf 47 | /comments2.pdf 48 | /leftguard.pdf 49 | /exdoneact.pdf 50 | /dropdown.pdf 51 | /conds1.pdf 52 | /conds2.pdf 53 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2001-2007 Adrian Thurston 3 | # 4 | 5 | # This file is part of Ragel. 6 | # 7 | # Ragel is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Ragel is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Ragel; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | 21 | man_MANS = ragel.1 22 | 23 | EXTRA_DIST = ragel-guide.tex \ 24 | bmconcat.fig bmregex.fig dropdown.fig exdoneact.fig \ 25 | exoutact1.fig exstrongsubtr.fig lines2.fig smallscanner.fig bmnull.fig \ 26 | comments1.fig entryguard.fig exinter.fig exoutact2.fig exsubtr.fig \ 27 | lmkleene.fig stembed.fig bmnum.fig comments2.fig exaction.fig \ 28 | exnegate.fig explus.fig finguard.fig opconcat.fig bmor.fig conds1.fig \ 29 | exallact.fig exoption.fig exstact.fig leftguard.fig opor.fig \ 30 | bmrange.fig conds2.fig exconcat.fig exor.fig exstar.fig lines1.fig \ 31 | opstar.fig 32 | 33 | if BUILD_MANUAL 34 | 35 | dist_doc_DATA = ragel-guide.pdf 36 | 37 | .fig.pdf: 38 | fig2dev -L pdf $< $@ 39 | 40 | .tex.pdf: 41 | pdflatex -interaction=nonstopmode $< >/dev/null 42 | pdflatex -interaction=nonstopmode $< >/dev/null 43 | pdflatex -interaction=nonstopmode $< >/dev/null 44 | 45 | version.tex: Makefile 46 | echo '|def|version{$(PACKAGE_VERSION)}' | tr '|' '\\' > version.tex 47 | echo '|def|pubdate{$(PUBDATE)}' | tr '|' '\\' >> version.tex 48 | 49 | ragel-guide.pdf: version.tex 50 | 51 | ragel-guide.pdf: bmconcat.pdf bmregex.pdf dropdown.pdf exdoneact.pdf \ 52 | exoutact1.pdf exstrongsubtr.pdf lines2.pdf smallscanner.pdf bmnull.pdf \ 53 | comments1.pdf entryguard.pdf exinter.pdf exoutact2.pdf exsubtr.pdf \ 54 | lmkleene.pdf stembed.pdf bmnum.pdf comments2.pdf exaction.pdf \ 55 | exnegate.pdf explus.pdf finguard.pdf opconcat.pdf bmor.pdf conds1.pdf \ 56 | exallact.pdf exoption.pdf exstact.pdf leftguard.pdf opor.pdf \ 57 | bmrange.pdf conds2.pdf exconcat.pdf exor.pdf exstar.pdf lines1.pdf \ 58 | opstar.pdf 59 | 60 | endif 61 | -------------------------------------------------------------------------------- /doc/RELEASE_NOTES_V3: -------------------------------------------------------------------------------- 1 | Porting Ragel Version 2 Programs to Version 3 2 | ============================================= 3 | 4 | 1. Replace all instances of *p in action code with the keyword fc. 5 | 6 | 2. Replace all instances of : used to set actions or priorities with @. 7 | 8 | 3. Wrap named priorities in parentheses so they are of the form @(name,1). 9 | -------------------------------------------------------------------------------- /doc/bmnull.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 2 | Portrait 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | # Generated by dot version 2.2.1 (Fri Sep 30 13:22:44 UTC 2005) 10 | # For: (age) Adrian Thurston 11 | # Title: bmnull 12 | # Pages: 1 13 | 1200 2 14 | 0 32 #d2d2d2 15 | # ENTRY 16 | 1 1 0 1 0 0 0 0 20 0.000 0 0.0000 33 2550 33 33 33 2550 66 2583 17 | # 0 18 | 1 1 0 1 0 32 0 0 -1 0.000 0 0.0000 1400 2550 383 383 1400 2550 1783 2933 19 | 1 1 0 1 0 32 0 0 -1 0.000 0 0.0000 1400 2550 450 450 1400 2550 1850 3000 20 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 1400 2633 0\001 21 | # ENTRY -> 0 22 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 23 | 66 2550 132 2550 225 2550 341 2550 474 2550 617 2550 766 2550 24 | 0 1 1 1 1 1 0 25 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 26 | 766 2483 933 2550 766 2600 766 2483 27 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 500 2500 IN\001 28 | # end of FIG file 29 | -------------------------------------------------------------------------------- /doc/bmnum.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 2 | Portrait 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | # Generated by dot version 2.2.1 (Fri Sep 30 13:22:44 UTC 2005) 10 | # For: (age) Adrian Thurston 11 | # Title: bmnum 12 | # Pages: 1 13 | 1200 2 14 | 0 32 #d2d2d2 15 | # ENTRY 16 | 1 1 0 1 0 0 0 0 20 0.000 0 0.0000 33 2550 33 33 33 2550 66 2583 17 | # 0 18 | 1 1 0 1 0 32 0 0 -1 0.000 0 0.0000 1333 2550 383 383 1333 2550 1716 2933 19 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 1333 2633 0\001 20 | # ENTRY -> 0 21 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 22 | 66 2550 139 2550 237 2550 354 2550 485 2550 624 2550 766 2550 23 | 0 1 1 1 1 1 0 24 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 25 | 766 2483 933 2550 766 2600 766 2483 26 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 500 2500 IN\001 27 | # 1 28 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 3066 2550 383 383 3066 2550 3449 2933 29 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 3066 2550 450 450 3066 2550 3516 3000 30 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 3066 2633 1\001 31 | # 0 -> 1 32 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 33 | 1733 2550 1838 2550 1951 2550 2070 2550 2192 2550 2314 2550 2433 2550 34 | 0 1 1 1 1 1 0 35 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 36 | 2433 2483 2600 2550 2433 2600 2433 2483 37 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 2166 2500 42\001 38 | # end of FIG file 39 | -------------------------------------------------------------------------------- /doc/bmor.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 2 | Portrait 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | # Generated by dot version 2.2.1 (Fri Sep 30 13:22:44 UTC 2005) 10 | # For: (age) Adrian Thurston 11 | # Title: bmor 12 | # Pages: 1 13 | 1200 2 14 | 0 32 #d2d2d2 15 | # ENTRY 16 | 1 1 0 1 0 0 0 0 20 0.000 0 0.0000 33 2550 33 33 33 2550 66 2583 17 | # 0 18 | 1 1 0 1 0 32 0 0 -1 0.000 0 0.0000 1333 2550 383 383 1333 2550 1716 2933 19 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 1333 2633 0\001 20 | # ENTRY -> 0 21 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 22 | 66 2550 139 2550 237 2550 354 2550 485 2550 624 2550 766 2550 23 | 0 1 1 1 1 1 0 24 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 25 | 766 2483 933 2550 766 2600 766 2483 26 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 500 2500 IN\001 27 | # 1 28 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 3933 2550 383 383 3933 2550 4316 2933 29 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 3933 2550 450 450 3933 2550 4383 3000 30 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 3933 2633 1\001 31 | # 0 -> 1 32 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 33 | 1733 2550 1960 2550 2217 2550 2491 2550 2771 2550 3045 2550 3300 2550 34 | 0 1 1 1 1 1 0 35 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 36 | 3300 2483 3466 2550 3300 2600 3300 2483 37 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 2600 2500 'e', 'h', 'l', 'o'\001 38 | # end of FIG file 39 | -------------------------------------------------------------------------------- /doc/bmrange.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 2 | Portrait 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | # Generated by dot version 2.2.1 (Fri Sep 30 13:22:44 UTC 2005) 10 | # For: (age) Adrian Thurston 11 | # Title: bmrange 12 | # Pages: 1 13 | 1200 2 14 | 0 32 #d2d2d2 15 | # ENTRY 16 | 1 1 0 1 0 0 0 0 20 0.000 0 0.0000 33 2550 33 33 33 2550 66 2583 17 | # 0 18 | 1 1 0 1 0 32 0 0 -1 0.000 0 0.0000 1333 2550 383 383 1333 2550 1716 2933 19 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 1333 2633 0\001 20 | # ENTRY -> 0 21 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 22 | 66 2550 139 2550 237 2550 354 2550 485 2550 624 2550 766 2550 23 | 0 1 1 1 1 1 0 24 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 25 | 766 2483 933 2550 766 2600 766 2483 26 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 500 2500 IN\001 27 | # 1 28 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 3333 2550 383 383 3333 2550 3716 2933 29 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 3333 2550 450 450 3333 2550 3783 3000 30 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 3333 2633 1\001 31 | # 0 -> 1 32 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 33 | 1733 2550 1881 2550 2039 2550 2204 2550 2371 2550 2538 2550 2700 2550 34 | 0 1 1 1 1 1 0 35 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 36 | 2700 2483 2866 2550 2700 2600 2700 2483 37 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 2300 2500 'a'..'z'\001 38 | # end of FIG file 39 | -------------------------------------------------------------------------------- /doc/exaction.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 2 | # Generated by Graphviz version 2.12 (Tue Sep 4 16:56:48 UTC 2007) 3 | # For: (thurston) Adrian Thurston,,, 4 | # Title: exaction 5 | # Pages: 1 6 | Portrait 7 | Center 8 | Inches 9 | Letter 10 | 100.00 11 | Single 12 | -2 13 | 1200 2 14 | 0 32 #d3d3d3 15 | 2 3 0 1 7 7 2 0 20 0.0 0 0 0 0 0 5 16 | 0 2460 0 0 8680 0 8680 2460 0 2460 17 | # ENTRY 18 | 1 1 0 1 0 0 1 0 20 0.000 0 0.0000 120 720 40 -40 120 720 160 680 19 | # 1 20 | 1 1 0 1 0 7 1 0 -1 0.000 0 0.0000 1640 720 420 -430 1640 720 2060 290 21 | 4 1 0 1 0 0 14.0 0.0000 4 0.0 0.0 1640 800 1\001 22 | # ENTRY->1 23 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 24 | 160 720 247 720 364 720 505 720 662 720 829 720 1000 720 25 | 0 1 1 1 1 1 0 26 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 27 | 1000 650 1200 720 1000 790 1000 650 28 | 4 1 0 0 0 0 14.0 0.0000 4 0.0 0.0 680 600 IN\001 29 | # 3 30 | 1 1 0 1 0 7 1 0 -1 0.000 0 0.0000 8080 720 422 -430 8080 720 8502 290 31 | 1 1 0 1 0 7 1 0 -1 0.000 0 0.0000 8080 720 500 -510 8080 720 8580 210 32 | 4 1 0 1 0 0 14.0 0.0000 4 0.0 0.0 8080 800 3\001 33 | # 1->3 34 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 19 35 | 2060 620 2121 610 2185 600 2250 590 2315 580 2379 570 2440 560 3383 488 4150 465 4828 480 5504 521 6265 579 7200 640 7229 641 7255 645 7280 650 7305 655 7331 659 7360 660 36 | 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 37 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 38 | 7368 590 7560 680 7354 730 7368 590 39 | 4 1 0 0 0 0 14.0 0.0000 4 0.0 0.0 4980 360 '\\n' / A, C, N\001 40 | # 2 41 | 1 1 0 1 0 7 1 0 -1 0.000 0 0.0000 4980 1960 420 -430 4980 1960 5400 1530 42 | 4 1 0 1 0 0 14.0 0.0000 4 0.0 0.0 4980 2040 2\001 43 | # 1->2 44 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 45 | 2040 860 2376 985 2767 1133 3188 1293 3613 1454 4019 1607 4380 1740 46 | 0 1 1 1 1 1 0 47 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 48 | 4409 1675 4580 1800 4368 1810 4409 1675 49 | 4 1 0 0 0 0 14.0 0.0000 4 0.0 0.0 3160 920 'a'..'z' / A, B\001 50 | # 2->3 51 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 52 | 5380 1800 5669 1681 6002 1547 6363 1405 6731 1259 7090 1116 7420 980 53 | 0 1 1 1 1 1 0 54 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 55 | 7389 917 7600 900 7446 1045 7389 917 56 | 4 1 0 0 0 0 14.0 0.0000 4 0.0 0.0 6640 1000 '\\n' / C, N\001 57 | # 2->2 58 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 13 59 | 4580 1780 4432 1645 4368 1509 4390 1383 4499 1278 4695 1206 4980 1180 5220 1199 5401 1250 5523 1328 5586 1423 5592 1530 5540 1640 60 | 0 1 1 1 1 1 1 1 1 1 1 1 0 61 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 62 | 5577 1701 5380 1780 5484 1596 5577 1701 63 | 4 1 0 0 0 0 14.0 0.0000 4 0.0 0.0 4980 1060 'a'..'z' / B\001 64 | # end of FIG file 65 | -------------------------------------------------------------------------------- /doc/exallact.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 2 | Portrait 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | # Generated by dot version 2.2.1 (Fri Sep 30 13:22:44 UTC 2005) 10 | # For: (age) Adrian Thurston 11 | # Title: exallact 12 | # Pages: 1 13 | 1200 2 14 | 0 32 #d2d2d2 15 | # ENTRY 16 | 1 1 0 1 0 0 0 0 20 0.000 0 0.0000 33 2550 33 33 33 2550 66 2583 17 | # 0 18 | 1 1 0 1 0 32 0 0 -1 0.000 0 0.0000 1333 2550 383 383 1333 2550 1716 2933 19 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 1333 2633 0\001 20 | # ENTRY -> 0 21 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 22 | 66 2550 139 2550 237 2550 354 2550 485 2550 624 2550 766 2550 23 | 0 1 1 1 1 1 0 24 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 25 | 766 2483 933 2550 766 2600 766 2483 26 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 500 2500 IN\001 27 | # 2 28 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 5733 2550 383 383 5733 2550 6116 2933 29 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 5733 2550 450 450 5733 2550 6183 3000 30 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 5733 2633 2\001 31 | # 1 32 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 3366 2550 383 383 3366 2550 3749 2933 33 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 3366 2633 1\001 34 | # 0 -> 1 35 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 36 | 1733 2550 1893 2550 2069 2550 2254 2550 2441 2550 2626 2550 2800 2550 37 | 0 1 1 1 1 1 0 38 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 39 | 2800 2483 2966 2550 2800 2600 2800 2483 40 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 2350 2500 'm' / A\001 41 | # 1 -> 2 42 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 43 | 3766 2550 3962 2550 4179 2550 4408 2550 4643 2550 4876 2550 5100 2550 44 | 0 1 1 1 1 1 0 45 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 46 | 5100 2483 5266 2550 5100 2600 5100 2483 47 | 4 1 0 0 0 0 14.0 0.0000 2 0.0 0.0 4516 2500 '1'..'2' / A\001 48 | # end of FIG file 49 | -------------------------------------------------------------------------------- /doc/exdoneact.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5-alpha5 2 | Portrait 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | # Generated by dot version 2.2.1 (Fri Sep 30 13:22:44 UTC 2005) 10 | # For: (age) Adrian Thurston 11 | # Title: exdoneact 12 | # Pages: 1 13 | 1200 2 14 | 0 32 #d2d2d2 15 | # ENTRY 16 | 1 1 0 1 0 0 0 0 20 0.000 0 0.0000 33 3550 33 33 33 3550 66 3583 17 | # 0 18 | 1 1 0 1 0 32 0 0 -1 0.000 0 0.0000 1333 3550 383 383 1333 3550 1716 3933 19 | # 1 20 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 3333 3550 383 383 3333 3550 3716 3933 21 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 3333 3550 450 450 3333 3550 3783 4000 22 | 2 3 0 1 0 0 0 0 20 0.000 0 0 0 0 0 4 23 | 766 3483 933 3550 766 3600 766 3483 24 | 2 3 0 1 0 0 0 0 20 0.000 0 0 0 0 0 4 25 | 2700 3483 2866 3550 2700 3600 2700 3483 26 | 2 3 0 1 0 0 0 0 20 0.000 0 0 0 0 0 4 27 | 1100 3100 1066 3266 1000 3100 1100 3100 28 | 2 2 0 0 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 29 | -270 2610 3915 2610 3915 4140 -270 4140 -270 2610 30 | # ENTRY -> 0 31 | 3 4 0 1 0 0 0 0 -1 0.000 0 0 0 7 32 | 66 3550 139 3550 237 3550 354 3550 485 3550 624 3550 33 | 766 3550 34 | 0.000 1.000 1.000 1.000 1.000 1.000 0.000 35 | # 0 -> 1 36 | 3 4 0 1 0 0 0 0 -1 0.000 0 0 0 7 37 | 1733 3550 1881 3550 2039 3550 2204 3550 2371 3550 2538 3550 38 | 2700 3550 39 | 0.000 1.000 1.000 1.000 1.000 1.000 0.000 40 | # 0 -> 0 41 | 3 4 0 1 0 0 0 0 -1 0.000 0 0 0 13 42 | 1600 3266 1620 3167 1616 3074 1585 2991 1528 2925 1444 2882 43 | 1333 2866 1249 2874 1182 2897 1129 2933 1090 2980 1064 3036 44 | 1050 3100 45 | 0.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 46 | 1.000 1.000 1.000 1.000 0.000 47 | 4 1 0 0 0 0 14 0.0000 2 150 120 1333 3633 0\001 48 | 4 1 0 0 0 0 14 0.0000 2 150 255 500 3500 IN\001 49 | 4 1 0 0 0 0 14 0.0000 2 165 120 3333 3633 1\001 50 | 4 1 0 0 0 0 14 0.0000 2 150 510 2300 3500 ' ' / A\001 51 | 4 1 0 0 0 0 14 0.0000 2 150 510 1333 2816 'a'..'z'\001 52 | -------------------------------------------------------------------------------- /doc/exnegate.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5-alpha5 2 | Portrait 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | # Generated by dot version 2.2.1 (Fri Sep 30 13:22:44 UTC 2005) 10 | # For: (age) Adrian Thurston 11 | # Title: exnegate 12 | # Pages: 1 13 | 1200 2 14 | 0 32 #d2d2d2 15 | # ENTRY 16 | 1 1 0 1 0 0 0 0 20 0.000 0 0.0000 33 3683 33 33 33 3683 66 3716 17 | # 0 18 | 1 1 0 1 0 32 0 0 -1 0.000 0 0.0000 1400 3683 383 383 1400 3683 1783 4066 19 | 1 1 0 1 0 32 0 0 -1 0.000 0 0.0000 1400 3683 450 450 1400 3683 1850 4133 20 | # 1 21 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 4400 3683 383 383 4400 3683 4783 4066 22 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 4400 3683 450 450 4400 3683 4850 4133 23 | 2 3 0 1 0 0 0 0 20 0.000 0 0 0 0 0 4 24 | 766 3616 933 3683 766 3733 766 3616 25 | 2 3 0 1 0 0 0 0 20 0.000 0 0 0 0 0 4 26 | 3766 3616 3933 3683 3766 3733 3766 3616 27 | 2 3 0 1 0 0 0 0 20 0.000 0 0 0 0 0 4 28 | 4116 3183 4083 3350 4016 3183 4116 3183 29 | 2 2 0 0 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 30 | 4950 2655 -90 2655 -90 4230 4950 4230 4950 2655 31 | # ENTRY -> 0 32 | 3 4 0 1 0 0 0 0 -1 0.000 0 0 0 7 33 | 66 3683 132 3683 225 3683 341 3683 474 3683 617 3683 34 | 766 3683 35 | 0.000 1.000 1.000 1.000 1.000 1.000 0.000 36 | # 0 -> 1 37 | 3 4 0 1 0 0 0 0 -1 0.000 0 0 0 7 38 | 1866 3683 2147 3683 2462 3683 2797 3683 3137 3683 3465 3683 39 | 3766 3683 40 | 0.000 1.000 1.000 1.000 1.000 1.000 0.000 41 | # 1 -> 1 42 | 3 4 0 1 0 0 0 0 -1 0.000 0 0 0 13 43 | 4716 3350 4741 3243 4734 3145 4695 3060 4626 2993 4527 2949 44 | 4400 2933 4305 2941 4224 2964 4158 3002 4108 3051 4077 3112 45 | 4066 3183 46 | 0.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 47 | 1.000 1.000 1.000 1.000 0.000 48 | 4 1 0 0 0 0 14 0.0000 2 150 120 1400 3766 0\001 49 | 4 1 0 0 0 0 14 0.0000 2 150 255 500 3633 IN\001 50 | 4 1 0 0 0 0 14 0.0000 2 165 120 4400 3766 1\001 51 | 4 1 0 0 0 0 14 0.0000 2 195 1455 2900 3633 -128..'/', ':'..127\001 52 | 4 1 0 0 0 0 14 0.0000 2 150 465 4400 2883 DEF\001 53 | -------------------------------------------------------------------------------- /doc/exoutact1.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5-alpha5 2 | Portrait 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | # Generated by dot version 2.2.1 (Fri Sep 30 13:22:44 UTC 2005) 10 | # For: (age) Adrian Thurston 11 | # Title: exoutact1 12 | # Pages: 1 13 | 1200 2 14 | 0 32 #d2d2d2 15 | # ENTRY 16 | 1 1 0 1 0 0 0 0 20 0.000 0 0.0000 33 3550 33 33 33 3550 66 3583 17 | # 0 18 | 1 1 0 1 0 32 0 0 -1 0.000 0 0.0000 1333 3550 383 383 1333 3550 1716 3933 19 | # 2 20 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 5333 3550 383 383 5333 3550 5716 3933 21 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 5333 3550 450 450 5333 3550 5783 4000 22 | # 1 23 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 3266 3550 383 383 3266 3550 3649 3933 24 | 2 3 0 1 0 0 0 0 20 0.000 0 0 0 0 0 4 25 | 766 3483 933 3550 766 3600 766 3483 26 | 2 3 0 1 0 0 0 0 20 0.000 0 0 0 0 0 4 27 | 2700 3483 2866 3550 2700 3600 2700 3483 28 | 2 3 0 1 0 0 0 0 20 0.000 0 0 0 0 0 4 29 | 4700 3483 4866 3550 4700 3600 4700 3483 30 | 2 3 0 1 0 0 0 0 20 0.000 0 0 0 0 0 4 31 | 3033 3100 3000 3266 2933 3100 3033 3100 32 | 2 2 0 0 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 33 | -135 2610 5895 2610 5895 4140 -135 4140 -135 2610 34 | # ENTRY -> 0 35 | 3 4 0 1 0 0 0 0 -1 0.000 0 0 0 7 36 | 66 3550 139 3550 237 3550 354 3550 485 3550 624 3550 37 | 766 3550 38 | 0.000 1.000 1.000 1.000 1.000 1.000 0.000 39 | # 0 -> 1 40 | 3 4 0 1 0 0 0 0 -1 0.000 0 0 0 7 41 | 1733 3550 1881 3550 2039 3550 2204 3550 2371 3550 2538 3550 42 | 2700 3550 43 | 0.000 1.000 1.000 1.000 1.000 1.000 0.000 44 | # 1 -> 2 45 | 3 4 0 1 0 0 0 0 -1 0.000 0 0 0 7 46 | 3666 3550 3824 3550 3993 3550 4170 3550 4350 3550 4528 3550 47 | 4700 3550 48 | 0.000 1.000 1.000 1.000 1.000 1.000 0.000 49 | # 1 -> 1 50 | 3 4 0 1 0 0 0 0 -1 0.000 0 0 0 13 51 | 3533 3266 3554 3167 3549 3074 3518 2991 3461 2925 3377 2882 52 | 3266 2866 3183 2874 3115 2897 3062 2933 3023 2980 2997 3036 53 | 2983 3100 54 | 0.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 55 | 1.000 1.000 1.000 1.000 0.000 56 | 4 1 0 0 0 0 14 0.0000 2 150 120 1333 3633 0\001 57 | 4 1 0 0 0 0 14 0.0000 2 150 255 500 3500 IN\001 58 | 4 1 0 0 0 0 14 0.0000 2 150 120 5333 3633 2\001 59 | 4 1 0 0 0 0 14 0.0000 2 165 120 3266 3633 1\001 60 | 4 1 0 0 0 0 14 0.0000 2 150 510 2300 3500 'a'..'z'\001 61 | 4 1 0 0 0 0 14 0.0000 2 165 600 4266 3500 10 / A\001 62 | 4 1 0 0 0 0 14 0.0000 2 150 510 3266 2816 'a'..'z'\001 63 | -------------------------------------------------------------------------------- /doc/explus.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5-alpha5 2 | Portrait 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | # Generated by dot version 2.2.1 (Fri Sep 30 13:22:44 UTC 2005) 10 | # For: (age) Adrian Thurston 11 | # Title: explus 12 | # Pages: 1 13 | 1200 2 14 | 0 32 #d2d2d2 15 | # ENTRY 16 | 1 1 0 1 0 0 0 0 20 0.000 0 0.0000 33 3683 33 33 33 3683 66 3716 17 | # 0 18 | 1 1 0 1 0 32 0 0 -1 0.000 0 0.0000 1333 3683 383 383 1333 3683 1716 4066 19 | # 1 20 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 4700 3683 383 383 4700 3683 5083 4066 21 | 1 1 0 1 0 0 0 0 -1 0.000 0 0.0000 4700 3683 450 450 4700 3683 5150 4133 22 | 2 3 0 1 0 0 0 0 20 0.000 0 0 0 0 0 4 23 | 766 3616 933 3683 766 3733 766 3616 24 | 2 3 0 1 0 0 0 0 20 0.000 0 0 0 0 0 4 25 | 4416 3183 4383 3350 4316 3183 4416 3183 26 | 2 3 0 1 0 0 0 0 20 0.000 0 0 0 0 0 4 27 | 4066 3616 4233 3683 4066 3733 4066 3616 28 | 2 2 0 0 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 29 | 5850 2655 -90 2655 -90 4230 5850 4230 5850 2655 30 | # ENTRY -> 0 31 | 3 4 0 1 0 0 0 0 -1 0.000 0 0 0 7 32 | 66 3683 139 3683 237 3683 354 3683 485 3683 624 3683 33 | 766 3683 34 | 0.000 1.000 1.000 1.000 1.000 1.000 0.000 35 | # 1 -> 1 36 | 3 4 0 1 0 0 0 0 -1 0.000 0 0 0 13 37 | 5016 3350 5041 3243 5034 3145 4995 3060 4926 2993 4827 2949 38 | 4700 2933 4605 2941 4524 2964 4458 3002 4408 3051 4377 3112 39 | 4366 3183 40 | 0.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 41 | 1.000 1.000 1.000 1.000 0.000 42 | # 0 -> 1 43 | 3 4 0 1 0 0 0 0 -1 0.000 0 0 0 7 44 | 1733 3683 2055 3683 2438 3683 2856 3683 3283 3683 3695 3683 45 | 4066 3683 46 | 0.000 1.000 1.000 1.000 1.000 1.000 0.000 47 | 4 1 0 0 0 0 14 0.0000 2 150 120 1333 3766 0\001 48 | 4 1 0 0 0 0 14 0.0000 2 150 255 500 3633 IN\001 49 | 4 1 0 0 0 0 14 0.0000 2 165 120 4700 3766 1\001 50 | 4 1 0 0 0 0 14 0.0000 2 180 1920 4700 2883 '0'..'9', 'A'..'Z', 'a'..'z'\001 51 | 4 1 0 0 0 0 14 0.0000 2 180 1920 2983 3633 '0'..'9', 'A'..'Z', 'a'..'z'\001 52 | -------------------------------------------------------------------------------- /doc/exstact.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 2 | # Generated by Graphviz version 2.12 (Tue Sep 4 16:56:48 UTC 2007) 3 | # For: (thurston) Adrian Thurston,,, 4 | # Title: exstact 5 | # Pages: 1 6 | Portrait 7 | Center 8 | Inches 9 | Letter 10 | 100.00 11 | Single 12 | -2 13 | 1200 2 14 | 0 32 #d3d3d3 15 | 2 3 0 1 7 7 2 0 20 0.0 0 0 0 0 0 5 16 | 0 2340 0 0 6920 0 6920 2340 0 2340 17 | # ENTRY 18 | 1 1 0 1 0 0 1 0 20 0.000 0 0.0000 120 600 40 -40 120 600 160 560 19 | # 1 20 | 1 1 0 1 0 7 1 0 -1 0.000 0 0.0000 1640 600 420 -430 1640 600 2060 170 21 | 4 1 0 1 0 0 14.0 0.0000 4 0.0 0.0 1640 680 1\001 22 | # ENTRY->1 23 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 24 | 160 600 247 600 364 600 505 600 662 600 829 600 1000 600 25 | 0 1 1 1 1 1 0 26 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 27 | 1000 530 1200 600 1000 670 1000 530 28 | 4 1 0 0 0 0 14.0 0.0000 4 0.0 0.0 680 480 IN\001 29 | # 3 30 | 1 1 0 1 0 7 1 0 -1 0.000 0 0.0000 6320 600 422 -430 6320 600 6742 170 31 | 1 1 0 1 0 7 1 0 -1 0.000 0 0.0000 6320 600 500 -510 6320 600 6820 90 32 | 4 1 0 1 0 0 14.0 0.0000 4 0.0 0.0 6320 680 3\001 33 | # 1->3 34 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 19 35 | 2080 560 2140 551 2200 545 2260 540 2320 535 2380 529 2440 520 2902 495 3277 479 3608 470 3936 468 4306 472 4760 480 4901 490 5044 500 5188 510 5329 520 5467 530 5600 540 36 | 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 37 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 38 | 5608 470 5800 560 5594 610 5608 470 39 | 4 1 0 0 0 0 14.0 0.0000 4 0.0 0.0 4320 360 SP / A\001 40 | # 2 41 | 1 1 0 1 0 7 1 0 -1 0.000 0 0.0000 4320 1840 420 -430 4320 1840 4740 1410 42 | 4 1 0 1 0 0 14.0 0.0000 4 0.0 0.0 4320 1920 2\001 43 | # 1->2 44 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 45 | 2020 780 2273 899 2560 1032 2868 1173 3180 1315 3483 1453 3760 1580 46 | 0 1 1 1 1 1 0 47 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 48 | 3786 1515 3940 1660 3729 1643 3786 1515 49 | 4 1 0 0 0 0 14.0 0.0000 4 0.0 0.0 2980 880 'a'..'z' / A\001 50 | # 2->3 51 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 7 52 | 4680 1620 4829 1525 4993 1423 5168 1315 5347 1204 5526 1091 5700 980 53 | 0 1 1 1 1 1 0 54 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 55 | 5671 916 5880 880 5739 1038 5671 916 56 | 4 1 0 0 0 0 14.0 0.0000 4 0.0 0.0 5280 1080 SP\001 57 | # 2->2 58 | 3 4 0 1 0 0 0 0 -1 0.0 0 0 0 13 59 | 4020 1540 3970 1421 3960 1309 3990 1210 4060 1131 4170 1079 4320 1060 4430 1070 4520 1097 4590 1140 4640 1196 4670 1264 4680 1340 60 | 0 1 1 1 1 1 1 1 1 1 1 1 0 61 | 2 3 0 1 0 0 0 0 20 0.0 0 0 0 0 0 4 62 | 4745 1369 4620 1540 4610 1328 4745 1369 63 | 4 1 0 0 0 0 14.0 0.0000 4 0.0 0.0 4320 940 'a'..'z'\001 64 | # end of FIG file 65 | -------------------------------------------------------------------------------- /doc/extract.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/awk 2 | # 3 | 4 | BEGIN { 5 | in_generate = 0; 6 | in_verbatim = 0; 7 | return_val = 1; 8 | } 9 | 10 | /^% GENERATE: *[a-z0-9A-Z_\.\-]+ *$/ && $3 == exname { 11 | in_generate = 1; 12 | return_val = 0; 13 | next; 14 | } 15 | 16 | /^% END GENERATE$/ { 17 | in_generate = 0; 18 | next; 19 | } 20 | 21 | in_generate && /\\begin\{verbatim\}/ { 22 | in_generate = 0; 23 | in_verbatim = 1; 24 | next; 25 | } 26 | 27 | in_verbatim && /\\end\{verbatim\}/ { 28 | in_generate = 1; 29 | in_verbatim = 0; 30 | next; 31 | } 32 | 33 | in_generate && /^%/ { 34 | print substr( $0, 2 ); 35 | } 36 | 37 | in_verbatim { 38 | print $0; 39 | } 40 | 41 | END { exit return_val; } 42 | -------------------------------------------------------------------------------- /doc/fixbackbox.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/awk 2 | # 3 | 4 | NF == 16 && $16 == 5 { 5 | $7 = 1 6 | print $0 7 | next; 8 | } 9 | 10 | { print $0; } 11 | -------------------------------------------------------------------------------- /doc/genfigs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | 4 | input=ragel-guide.tex 5 | 6 | for fig; do 7 | if awk -f extract.awk -vexname=$fig $input > /dev/null; then 8 | echo generating ${fig}.dot 9 | opt=`awk -f extract.awk -vexname=$fig $input | 10 | sed '/^ *OPT:/s/^.*: *//p;d'` 11 | awk -f extract.awk -vexname=$fig $input > ${fig}.rl 12 | ../ragel/ragel -V -p ${fig}.rl > ${fig}.dot 13 | else 14 | echo "$0: internal error: figure $fig not found in $input" >&2 15 | exit 1 16 | fi 17 | done 18 | 19 | -------------------------------------------------------------------------------- /doc/opconcat.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5-alpha5 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 585 630 135 135 585 630 720 630 11 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1215 810 90 90 1215 810 1305 810 12 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1215 810 135 135 1215 810 1350 810 13 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1215 450 135 135 1215 450 1350 450 14 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1215 450 90 90 1215 450 1305 450 15 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 2340 630 135 135 2340 630 2475 630 16 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 2970 450 90 90 2970 450 3060 450 17 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 2970 450 135 135 2970 450 3105 450 18 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 2970 810 135 135 2970 810 3105 810 19 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 2970 810 90 90 2970 810 3060 810 20 | 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 21 | 1 1 1.00 45.00 60.00 22 | 1350 450 2205 585 23 | 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 24 | 1 1 1.00 45.00 60.00 25 | 1350 810 2205 675 26 | 3 1 0 1 0 7 50 0 -1 0.000 0 0 0 8 27 | 225 630 495 270 1125 180 1485 270 1530 630 1485 990 28 | 1125 1080 495 990 29 | 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 30 | 3 1 0 1 0 7 50 0 -1 0.000 0 0 0 8 31 | 1980 630 2250 270 2880 180 3240 270 3285 630 3240 990 32 | 2880 1080 2250 990 33 | 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 34 | 3 0 0 1 0 7 50 0 -1 0.000 0 1 0 6 35 | 1 1 1.00 45.00 60.00 36 | 45 675 135 540 225 810 315 630 360 630 450 630 37 | 0.000 1.000 1.000 1.000 1.000 0.000 38 | 4 0 0 50 0 32 10 0.0000 4 90 75 1710 450 e\001 39 | 4 0 0 50 0 32 10 0.0000 4 90 75 1710 900 e\001 40 | -------------------------------------------------------------------------------- /doc/opor.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5-alpha5 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 585 945 135 135 585 945 720 945 11 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1215 450 135 135 1215 450 1350 450 12 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1845 630 135 135 1845 630 1980 630 13 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1845 630 90 90 1845 630 1935 630 14 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1845 270 135 135 1845 270 1980 270 15 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1845 270 90 90 1845 270 1935 270 16 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1845 1260 90 90 1845 1260 1935 1260 17 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1845 1260 135 135 1845 1260 1980 1260 18 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1215 1440 135 135 1215 1440 1350 1440 19 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1845 1620 90 90 1845 1620 1935 1620 20 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1845 1620 135 135 1845 1620 1980 1620 21 | 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 22 | 1 1 1.00 45.00 60.00 23 | 675 1035 1125 1350 24 | 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 25 | 1 1 1.00 45.00 60.00 26 | 675 855 1125 540 27 | 3 1 0 1 0 7 50 0 -1 0.000 0 0 0 8 28 | 855 1440 1125 1080 1755 990 2115 1080 2160 1440 2115 1800 29 | 1755 1890 1125 1800 30 | 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 31 | 3 1 0 1 0 7 50 0 -1 0.000 0 0 0 8 32 | 855 450 1125 90 1755 0 2115 90 2160 450 2115 810 33 | 1755 900 1125 810 34 | 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 35 | 3 0 0 1 0 7 50 0 -1 0.000 0 1 0 6 36 | 1 1 1.00 45.00 60.00 37 | 45 990 135 855 225 1125 315 945 360 945 450 945 38 | 0.000 1.000 1.000 1.000 1.000 0.000 39 | 4 0 0 50 0 32 10 0.0000 4 90 75 720 1260 e\001 40 | 4 0 0 50 0 32 10 0.0000 4 90 75 720 720 e\001 41 | -------------------------------------------------------------------------------- /doc/opstar.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5-alpha5 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 945 675 135 135 945 675 1080 675 11 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1149 58 90 90 1149 58 1239 58 12 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1149 58 135 135 1149 58 1284 58 13 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1620 495 135 135 1620 495 1755 495 14 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 2250 315 90 90 2250 315 2340 315 15 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 2250 315 135 135 2250 315 2385 315 16 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 2250 675 135 135 2250 675 2385 675 17 | 1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 2250 675 90 90 2250 675 2340 675 18 | 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 19 | 1 1 1.00 45.00 60.00 20 | 1080 630 1485 540 21 | 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 22 | 1 1 1.00 45.00 60.00 23 | 973 543 1103 203 24 | 3 1 0 1 0 7 50 0 -1 0.000 0 0 0 8 25 | 1260 495 1530 135 2160 45 2520 135 2565 495 2520 855 26 | 2160 945 1530 855 27 | 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 28 | 3 0 0 1 0 7 50 0 -1 0.000 0 1 0 6 29 | 1 1 1.00 45.00 60.00 30 | 2385 360 2700 630 2700 1215 1980 1395 1260 1125 978 801 31 | 0.000 1.000 1.000 1.000 1.000 0.000 32 | 3 0 0 1 0 7 50 0 -1 0.000 0 1 0 6 33 | 1 1 1.00 45.00 60.00 34 | 405 720 495 585 585 855 675 675 720 675 810 675 35 | 0.000 1.000 1.000 1.000 1.000 0.000 36 | 3 0 0 1 0 7 50 0 -1 0.000 0 1 0 6 37 | 1 1 1.00 45.00 60.00 38 | 2385 720 2520 855 2475 1125 1935 1215 1395 1035 1067 730 39 | 0.000 1.000 1.000 1.000 1.000 0.000 40 | 4 0 0 50 0 32 10 0.0000 4 90 75 1845 1125 e\001 41 | 4 0 0 50 0 32 10 0.0000 4 90 75 1845 1440 e\001 42 | 4 0 0 50 0 32 10 0.0000 4 90 75 1156 549 e\001 43 | 4 0 0 50 0 32 10 0.0000 4 90 75 896 442 e\001 44 | -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- 1 | /Makefile.in 2 | /Makefile 3 | /concurrent 4 | /rlscan 5 | /clang 6 | /statechart 7 | /gotocallret 8 | /pullscan 9 | /cppscan 10 | /format 11 | /awkemu 12 | /mailbox 13 | /atoi 14 | /params 15 | /statechart.cpp 16 | /gotocallret.cpp 17 | /clang.c 18 | /cppscan.cpp 19 | /mailbox.cpp 20 | /atoi.cpp 21 | /pullscan.c 22 | /concurrent.cpp 23 | /rlscan.cpp 24 | /params.c 25 | /format.c 26 | /awkemu.c 27 | /.deps 28 | -------------------------------------------------------------------------------- /examples/README: -------------------------------------------------------------------------------- 1 | 2 | Ragel State Machine Compiler -- Examples 3 | ======================================== 4 | 5 | atoi -- Converts a string to an integer. 6 | 7 | awkemu -- Perfoms the basic parsing that the awk program perfoms on input. 8 | The awk equivalent to awkemu is in awkemu/awkequiv.awk 9 | 10 | clang -- A scanner for a simple C like language. It breaks input up into 11 | words, numbers, strings and symbols and strips out whitespace 12 | and comments. It is a suitable template for writing a parser 13 | that finds a sequence of tokens. 14 | 15 | concurrent -- Demonstrates the ability of ragel to produce parsers that 16 | perform independent tasks concurrently. 17 | 18 | cppscan -- A C++ scanner that uses the longest match scanning method. This 19 | example differs from other examples of scanning. Each run of the 20 | state machine matches one token. This method results in a 21 | smaller state machine since the final kleene star is omitted and 22 | therefore every state does not need to get all the transitions 23 | of the start state. 24 | 25 | format -- Partial printf implementation. 26 | 27 | gotocallret -- Demonstrate the use of fgoto, fcall and fret. 28 | 29 | mailbox -- Parses unix mailbox files. It breaks files into messages, and 30 | messages into headers and body. It demonstrates Ragel's ability 31 | to make parsers for structured file formats. 32 | 33 | params -- Parses command line arguements. 34 | 35 | rlscan -- Lexes Ragel input files. 36 | 37 | statechart -- Demonstrate the use of labels, the epsilon operator, and the 38 | join operator for creating machines using the named state and 39 | transition list paradigm. This implementes the same machine as 40 | the atoi example. 41 | -------------------------------------------------------------------------------- /examples/atoi.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * Convert a string to an integer. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | %%{ 10 | machine atoi; 11 | write data; 12 | }%% 13 | 14 | long long atoi( char *str ) 15 | { 16 | char *p = str, *pe = str + strlen( str ); 17 | int cs; 18 | long long val = 0; 19 | bool neg = false; 20 | 21 | %%{ 22 | action see_neg { 23 | neg = true; 24 | } 25 | 26 | action add_digit { 27 | val = val * 10 + (fc - '0'); 28 | } 29 | 30 | main := 31 | ( '-'@see_neg | '+' )? ( digit @add_digit )+ 32 | '\n'; 33 | 34 | # Initialize and execute. 35 | write init; 36 | write exec; 37 | }%% 38 | 39 | if ( neg ) 40 | val = -1 * val; 41 | 42 | if ( cs < atoi_first_final ) 43 | fprintf( stderr, "atoi: there was an error\n" ); 44 | 45 | return val; 46 | }; 47 | 48 | 49 | #define BUFSIZE 1024 50 | 51 | int main() 52 | { 53 | char buf[BUFSIZE]; 54 | while ( fgets( buf, sizeof(buf), stdin ) != 0 ) { 55 | long long value = atoi( buf ); 56 | printf( "%lld\n", value ); 57 | } 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /examples/awkequiv.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/awk -f 2 | # 3 | 4 | 5 | { 6 | print "endline(" NF "): " $0 7 | for ( i = 1; i <= NF; i++ ) { 8 | print " word: " $i 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/go/.gitignore: -------------------------------------------------------------------------------- 1 | /*.go 2 | /*.dot 3 | /atoi 4 | /rpn 5 | /url 6 | -------------------------------------------------------------------------------- /examples/go/Makefile: -------------------------------------------------------------------------------- 1 | ragel = ragel 2 | 3 | check: atoi rpn url 4 | ./atoi 5 | ./rpn 6 | ./url 7 | @echo PASS 8 | 9 | graph: atoi.dot rpn.dot url.dot url_authority.dot 10 | xdot atoi.dot 11 | xdot rpn.dot 12 | xdot url.dot 13 | xdot url_authority.dot 14 | 15 | atoi: atoi.go 16 | atoi.go: atoi.rl 17 | atoi.dot: atoi.rl 18 | 19 | rpn: rpn.go 20 | rpn.go: rpn.rl 21 | rpn.dot: rpn.rl 22 | 23 | url: url.go url_authority.go 24 | url.go: url.rl 25 | url.dot: url.rl 26 | url_authority.go: url_authority.rl 27 | url_authority.dot: url_authority.rl 28 | 29 | clean: ; rm -f *.go *.dot atoi rpn url 30 | %: %.go ; go build -o $@ $^ 31 | %.go: %.rl ; $(ragel) -Z -G2 -o $@ $< 32 | %.dot: %.rl ; $(ragel) -V -Z -p -o $@ $< 33 | -------------------------------------------------------------------------------- /examples/go/README: -------------------------------------------------------------------------------- 1 | .. -*-rst-*- 2 | 3 | Ragel Examples for Go 4 | ===================== 5 | 6 | These examples serve the following purposes: 7 | 8 | - Help you learn Ragel 9 | - Test the correctness of the code I wrote for Ragel 10 | - Benchmark Ragel's performance on your machine 11 | - And hopefully give you some code you can steal ;] 12 | 13 | To get started you should first ``make install`` ragel. Then navigate 14 | to this directory and run:: 15 | 16 | make 17 | 18 | To automatically compile/test/benchmark these examples. 19 | 20 | The following examples are provided: 21 | 22 | - atoi.rl: Convert string to integer (very simple) 23 | - rpn.rl: Reverse polish notation calculator (simple) 24 | - url.rl: Very fast and robust HTTP/SIP URL parser (very complicated) 25 | 26 | To see graphviz diagrams of the state machines generated by Ragel in 27 | these examples, run the following commands:: 28 | 29 | sudo apt-get install xdot 30 | make graph 31 | 32 | Those diagrams (along with the pdf manual) are super important for 33 | troubleshooting and simplifying your Ragel code. 34 | 35 | I truly hope these examples help you in your personal and professional 36 | endeavors. If you have any questions my email is: jtunney@gmail.com 37 | -------------------------------------------------------------------------------- /examples/go/atoi.rl: -------------------------------------------------------------------------------- 1 | // -*-go-*- 2 | // 3 | // Convert a string to an integer. 4 | // 5 | // To compile: 6 | // 7 | // ragel -Z -T0 -o atoi.go atoi.rl 8 | // go build -o atoi atoi.go 9 | // ./atoi 10 | // 11 | // To show a diagram of your state machine: 12 | // 13 | // ragel -V -Z -p -o atoi.dot atoi.rl 14 | // xdot atoi.dot 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | "fmt" 22 | ) 23 | 24 | %%{ 25 | machine atoi; 26 | write data; 27 | }%% 28 | 29 | func atoi(data string) (val int) { 30 | cs, p, pe := 0, 0, len(data) 31 | neg := false 32 | 33 | %%{ 34 | action see_neg { neg = true } 35 | action add_digit { val = val * 10 + (int(fc) - '0') } 36 | 37 | main := 38 | ( '-'@see_neg | '+' )? ( digit @add_digit )+ 39 | '\n'? 40 | ; 41 | 42 | write init; 43 | write exec; 44 | }%% 45 | 46 | if neg { 47 | val = -1 * val; 48 | } 49 | 50 | if cs < atoi_first_final { 51 | fmt.Println("atoi: there was an error:", cs, "<", atoi_first_final) 52 | fmt.Println(data) 53 | for i := 0; i < p; i++ { 54 | fmt.Print(" ") 55 | } 56 | fmt.Println("^") 57 | } 58 | 59 | return val 60 | } 61 | 62 | ////////////////////////////////////////////////////////////////////// 63 | 64 | type atoiTest struct { 65 | s string 66 | v int 67 | } 68 | 69 | var atoiTests = []atoiTest{ 70 | atoiTest{"7", 7}, 71 | atoiTest{"666", 666}, 72 | atoiTest{"-666", -666}, 73 | atoiTest{"+666", 666}, 74 | atoiTest{"1234567890", 1234567890}, 75 | atoiTest{"+1234567890\n", 1234567890}, 76 | // atoiTest{"+ 1234567890", 1234567890}, // i will fail 77 | } 78 | 79 | func main() { 80 | res := 0 81 | for _, test := range atoiTests { 82 | res := atoi(test.s) 83 | if res != test.v { 84 | fmt.Fprintf(os.Stderr, "FAIL atoi(%#v) != %#v\n", test.s, test.v) 85 | res = 1 86 | } 87 | } 88 | os.Exit(res) 89 | } 90 | -------------------------------------------------------------------------------- /examples/gotocallret.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * Demonstrate the use of goto, call and return. This machine expects either a 3 | * lower case char or a digit as a command then a space followed by the command 4 | * arg. If the command is a char, then the arg must be an a string of chars. 5 | * If the command is a digit, then the arg must be a string of digits. This 6 | * choice is determined by action code, rather than though transition 7 | * desitinations. 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | 17 | struct GotoCallRet 18 | { 19 | char comm; 20 | int cs, top, stack[32]; 21 | 22 | int init( ); 23 | int execute( const char *data, int len, bool isEof ); 24 | int finish( ); 25 | }; 26 | 27 | %%{ 28 | machine GotoCallRet; 29 | 30 | # Error machine, consumes to end of 31 | # line, then starts the main line over. 32 | garble_line := ( 33 | (any-'\n')*'\n' 34 | ) >{cout << "error: garbling line" << endl;} @{fgoto main;}; 35 | 36 | # Look for a string of alphas or of digits, 37 | # on anything else, hold the character and return. 38 | alp_comm := alpha+ $!{fhold;fret;}; 39 | dig_comm := digit+ $!{fhold;fret;}; 40 | 41 | # Choose which to machine to call into based on the command. 42 | action comm_arg { 43 | if ( comm >= 'a' ) 44 | fcall alp_comm; 45 | else 46 | fcall dig_comm; 47 | } 48 | 49 | # Specifies command string. Note that the arg is left out. 50 | command = ( 51 | [a-z0-9] @{comm = fc;} ' ' @comm_arg '\n' 52 | ) @{cout << "correct command" << endl;}; 53 | 54 | # Any number of commands. If there is an 55 | # error anywhere, garble the line. 56 | main := command* $!{fhold;fgoto garble_line;}; 57 | }%% 58 | 59 | %% write data; 60 | 61 | int GotoCallRet::init( ) 62 | { 63 | %% write init; 64 | return 1; 65 | } 66 | 67 | int GotoCallRet::execute( const char *data, int len, bool isEof ) 68 | { 69 | const char *p = data; 70 | const char *pe = data + len; 71 | const char *eof = isEof ? pe : 0; 72 | 73 | %% write exec; 74 | if ( cs == GotoCallRet_error ) 75 | return -1; 76 | if ( cs >= GotoCallRet_first_final ) 77 | return 1; 78 | return 0; 79 | } 80 | 81 | #define BUFSIZE 1024 82 | 83 | int main() 84 | { 85 | char buf[BUFSIZE]; 86 | 87 | GotoCallRet gcr; 88 | gcr.init(); 89 | while ( fgets( buf, sizeof(buf), stdin ) != 0 ) 90 | gcr.execute( buf, strlen(buf), false ); 91 | 92 | gcr.execute( 0, 0, true ); 93 | if ( gcr.cs < GotoCallRet_first_final ) 94 | cerr << "gotocallret: error: parsing input" << endl; 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /examples/ocaml/.gitignore: -------------------------------------------------------------------------------- 1 | /atoi 2 | /clang 3 | /gotocallret 4 | /rpn 5 | /scan1 6 | /scan2 7 | /url 8 | /*.cmi 9 | /*.cmx 10 | /*.ml 11 | -------------------------------------------------------------------------------- /examples/ocaml/Makefile: -------------------------------------------------------------------------------- 1 | 2 | .SUFFIXES: 3 | 4 | RAGEL = ../../ragel/ragel 5 | MODE = -G0 6 | 7 | all: url rpn atoi clang gotocallret scan1 scan2 8 | 9 | url: url.rl 10 | $(RAGEL) $(MODE) -O url.rl -o url.ml 11 | $(RAGEL) $(MODE) -O url_authority.rl -o url_authority.ml 12 | ocamlopt -g unix.cmxa url_authority.ml url.ml -o url 13 | 14 | cond: cond.rl 15 | $(RAGEL) $(MODE) -O -o cond.ml cond.rl 16 | ocamlopt -g unix.cmxa -o cond cond.ml 17 | 18 | rpn: rpn.rl 19 | $(RAGEL) $(MODE) -O -o rpn.ml rpn.rl 20 | ocamlopt -g unix.cmxa -o rpn t.ml rpn.ml 21 | 22 | atoi: atoi.rl 23 | $(RAGEL) $(MODE) -O -o atoi.ml atoi.rl 24 | ocamlopt -g unix.cmxa -o atoi t.ml atoi.ml 25 | 26 | clang: clang.rl 27 | $(RAGEL) $(MODE) -O -o clang.ml clang.rl 28 | ocamlopt -g unix.cmxa -o clang t.ml clang.ml 29 | 30 | gotocallret: gotocallret.rl 31 | $(RAGEL) $(MODE) -O -o gotocallret.ml gotocallret.rl 32 | ocamlopt -g unix.cmxa -o gotocallret t.ml gotocallret.ml 33 | 34 | scan1: scan1.rl 35 | $(RAGEL) $(MODE) -O -o scan1.ml scan1.rl 36 | ocamlopt -g unix.cmxa -o scan1 t.ml scan1.ml 37 | 38 | scan2: scan2.rl 39 | $(RAGEL) $(MODE) -O -o scan2.ml scan2.rl 40 | ocamlopt -g unix.cmxa -o scan2 scan2.ml 41 | 42 | .PHONY: clean 43 | clean: 44 | rm -f *.cm* *.o *.annot 45 | rm -f $(subst .rl,.ml,$(wildcard *.rl)) 46 | rm -f $(subst .rl,,$(wildcard *.rl)) 47 | -------------------------------------------------------------------------------- /examples/ocaml/README: -------------------------------------------------------------------------------- 1 | 2 | ragel examples for OCaml codegen 3 | ================================ 4 | 5 | `make` will run several simple tests. 6 | `make run_url` will compile and run url parser benchmark. 7 | 8 | Examples were taken from examples/go/ and examples/ and 9 | converted to OCaml, thanks to original authors. 10 | 11 | -- 12 | ygrek 13 | 14 | -------------------------------------------------------------------------------- /examples/ocaml/atoi.rl: -------------------------------------------------------------------------------- 1 | 2 | %%{ 3 | machine atoi; 4 | write data; 5 | }%% 6 | 7 | let fail fmt = Printf.ksprintf failwith fmt 8 | 9 | let atoi data = 10 | let cs = ref 0 in 11 | let p = ref 0 in 12 | let pe = ref (String.length data) in 13 | let neg = ref false in 14 | let res = ref 0 in 15 | 16 | %%{ 17 | action see_neg { neg := true; } 18 | action add_digit { res := !res * 10 + (Char.code fc - Char.code '0'); } 19 | 20 | main := 21 | ( '-'@see_neg | '+' )? ( digit @add_digit )+ 22 | '\n'? 23 | ; 24 | 25 | write init; 26 | write exec; 27 | }%% 28 | 29 | if !neg then 30 | res := (-1) * !res ; 31 | 32 | if !cs < atoi_first_final then 33 | fail "atoi: cs %d < %d" !cs atoi_first_final; 34 | 35 | !res 36 | ;; 37 | let () = 38 | let t = T.test atoi in 39 | t "7" 7; 40 | t "666" 666; 41 | t "-666" (-666); 42 | t "+666" 666; 43 | t "123456789" 123456789; 44 | t "+123456789\n" 123456789; 45 | T.error atoi "+ 1234567890"; 46 | () 47 | ;; 48 | -------------------------------------------------------------------------------- /examples/ocaml/cond.rl: -------------------------------------------------------------------------------- 1 | 2 | %% machine cond; 3 | %% write data; 4 | 5 | let fail fmt = Printf.ksprintf failwith fmt 6 | 7 | let run data = 8 | let cs = ref 0 in 9 | let p = ref 0 in 10 | let pe = ref (String.length data) in 11 | 12 | %%{ 13 | action rec_num { i = 0; n = getnumber(); } 14 | action test_len { i++ < n } 15 | main := ( 16 | "d" 17 | [0-9]+ %rec_num 18 | ":" 19 | ( [a-z] when test_len )* 20 | )**; 21 | 22 | write init; 23 | write exec; 24 | }%% 25 | 26 | if !cs < cond_first_final then 27 | fail "parsing failed" 28 | 29 | let () = 30 | run "d2:aac" 31 | 32 | -------------------------------------------------------------------------------- /examples/ocaml/rpn.rl: -------------------------------------------------------------------------------- 1 | (* 2 | // -*-go-*- 3 | // 4 | // Reverse Polish Notation Calculator 5 | // Copyright (c) 2010 J.A. Roberts Tunney 6 | // MIT License 7 | // 8 | // To compile: 9 | // 10 | // ragel -Z -G2 -o rpn.go rpn.rl 11 | // 6g -o rpn.6 rpn.go 12 | // 6l -o rpn rpn.6 13 | // ./rpn 14 | // 15 | // To show a diagram of your state machine: 16 | // 17 | // ragel -V -G2 -p -o rpn.dot rpn.rl 18 | // dot -Tpng -o rpn.png rpn.dot 19 | // chrome rpn.png 20 | // 21 | *) 22 | 23 | %% machine rpn; 24 | %% write data; 25 | 26 | let fail fmt = Printf.ksprintf failwith fmt 27 | 28 | let rpn data = 29 | let (cs, p, pe) = (ref 0, ref 0, ref (String.length data)) in 30 | let mark = ref 0 in 31 | let st = Stack.create () in 32 | 33 | %%{ 34 | action mark { mark := !p } 35 | action push { Stack.push (int_of_string (String.sub data !mark (!p - !mark))) st } 36 | action add { let y = Stack.pop st in let x = Stack.pop st in Stack.push (x + y) st } 37 | action sub { let y = Stack.pop st in let x = Stack.pop st in Stack.push (x - y) st } 38 | action mul { let y = Stack.pop st in let x = Stack.pop st in Stack.push (x * y) st } 39 | action div { let y = Stack.pop st in let x = Stack.pop st in Stack.push (x / y) st } 40 | action abs { Stack.push (abs (Stack.pop st)) st } 41 | action abba { Stack.push 666 st } 42 | 43 | stuff = digit+ >mark %push 44 | | '+' @add 45 | | '-' @sub 46 | | '*' @mul 47 | | '/' @div 48 | | 'abs' %abs 49 | | 'add' %add 50 | | 'abba' %abba 51 | ; 52 | 53 | main := ( space | stuff space )* ; 54 | 55 | write init; 56 | write exec; 57 | }%% 58 | 59 | if !cs < rpn_first_final then 60 | begin 61 | if !p = !pe then 62 | fail "unexpected eof" 63 | else 64 | fail "error at position %d" !p 65 | end; 66 | 67 | if Stack.is_empty st then 68 | fail "rpn stack empty on result" 69 | else 70 | Stack.pop st 71 | 72 | (* ////////////////////////////////////////////////////////////////////// *) 73 | 74 | let rpnTests = [ 75 | ("666\n", 666); 76 | ("666 111\n", 111); 77 | ("4 3 add\n", 7); 78 | ("4 3 +\n", 7); 79 | ("4 3 -\n", 1); 80 | ("4 3 *\n", 12); 81 | ("6 2 /\n", 3); 82 | ("0 3 -\n", -3); 83 | ("0 3 - abs\n", 3); 84 | (" 2 2 + 3 - \n", 1); 85 | ("10 7 3 2 * - +\n", 11); 86 | ("abba abba add\n", 1332); 87 | ] 88 | 89 | let rpnFailTests = [ 90 | ("\n") 91 | ] 92 | 93 | let () = 94 | List.iter (fun (s,x) -> T.test rpn s x) rpnTests; 95 | List.iter (fun s -> T.error rpn s) rpnFailTests 96 | 97 | -------------------------------------------------------------------------------- /examples/ocaml/scan1.rl: -------------------------------------------------------------------------------- 1 | %%{ 2 | machine scanner; 3 | 4 | # Warning: changing the patterns or the input string will affect the 5 | # coverage of the scanner action types. 6 | main := |* 7 | 'a' => { 8 | prints "on last "; 9 | if !p+1 = !te then 10 | (on_last := !cnt; incr cnt; prints "yes"); 11 | prints "\n"; 12 | }; 13 | 14 | 'b'+ => { 15 | prints "on next "; 16 | if !p+1 = !te then 17 | ( on_next := !cnt; incr cnt; prints "yes"); 18 | prints "\n"; 19 | }; 20 | 21 | 'c1' 'dxxx'? => { 22 | prints "on lag "; 23 | if !p+1 = !te then 24 | ( on_lag := !cnt; incr cnt; prints "yes"); 25 | prints "\n"; 26 | }; 27 | 28 | 'd1' => { 29 | prints "lm switch1 "; 30 | if !p+1 = !te then 31 | (sw1 := !cnt; incr cnt; prints "yes"); 32 | prints "\n"; 33 | }; 34 | 'd2' => { 35 | prints "lm switch2 "; 36 | if !p+1 = !te then 37 | (sw2 := !cnt; incr cnt; prints "yes"); 38 | prints "\n"; 39 | }; 40 | 41 | [d0-9]+ '.'; 42 | 43 | '\n'; 44 | *|; 45 | 46 | write data; 47 | }%% 48 | 49 | let () = 50 | let prints (_:string) = () in 51 | let ts = ref 0 and te = ref 0 and act = ref 0 in 52 | let data = "abbc1d1d2\n" in 53 | let cs = ref 0 in 54 | let p = ref 0 and pe = ref (String.length data) in 55 | let eof = ref !pe in 56 | %% write init; 57 | let on_last = ref 0 and on_next = ref 0 and on_lag = ref 0 and 58 | sw1 = ref 0 and sw2 = ref 0 in 59 | let cnt = ref 1 in 60 | %% write exec; 61 | let t = T.test' (fun x -> string_of_int !x) (!) in 62 | t on_last 1; 63 | t on_next 2; 64 | t on_lag 3; 65 | t sw1 4; 66 | t sw2 5; 67 | t cnt 6; 68 | () 69 | 70 | (* 71 | on last yes 72 | on next yes 73 | on lag yes 74 | lm switch1 yes 75 | lm switch2 yes 76 | *) 77 | -------------------------------------------------------------------------------- /examples/ocaml/scan2.rl: -------------------------------------------------------------------------------- 1 | 2 | %%{ 3 | machine scanner; 4 | 5 | # Warning: changing the patterns or the input string will affect the 6 | # coverage of the scanner action types. 7 | main := |* 8 | 'a' => { 9 | got `Pat1; 10 | }; 11 | 12 | [ab]+ . 'c' => { 13 | got `Pat2; 14 | }; 15 | 16 | any => { 17 | got `Any; 18 | }; 19 | *|; 20 | 21 | write data; 22 | }%% 23 | 24 | let fail fmt = Printf.ksprintf failwith fmt 25 | 26 | let () = 27 | let expect = ref [`Pat1; `Any; `Pat2; `Any; `Any; `Any; ] in 28 | let got z = match !expect with 29 | | [] -> fail "nothing more expected" 30 | | x::xs -> expect := xs; if z <> x then fail "mismatch" 31 | in 32 | let ts = ref 0 and te = ref 0 and cs = ref 0 and act = ref 0 in 33 | let data = "araabccde" in 34 | let p = ref 0 and pe = ref (String.length data) in 35 | let eof = ref !pe in 36 | %% write init; 37 | %% write exec; 38 | () 39 | 40 | -------------------------------------------------------------------------------- /examples/ocaml/t.ml: -------------------------------------------------------------------------------- 1 | (* Common utility code *) 2 | 3 | let id x = x 4 | let fail fmt = Printf.ksprintf failwith fmt 5 | let pr fmt = Printf.ksprintf print_endline fmt 6 | 7 | let failed fmt = Printf.ksprintf (fun s -> prerr_endline s; exit 1) fmt 8 | let test' show f x y = if f x <> y then failed "FAILED: test %S" (show x) 9 | let case = ref 0 10 | let test f x y = incr case; if f x <> y then failed "FAILED: case %d" !case 11 | let error f x = match try Some (f x) with _ -> None with Some _ -> failed "FAILED: fail %S" x | None -> () 12 | 13 | -------------------------------------------------------------------------------- /examples/ocaml/test.ml: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env ocaml 2 | 3 | (* test suite *) 4 | 5 | open Printf 6 | 7 | let names = [ 8 | "atoi"; 9 | "scan2"; 10 | "scan1"; 11 | "gotocallret"; 12 | "rpn"; 13 | ] 14 | 15 | let () = 16 | let ragel = match Sys.argv with [|_;s|] -> s | _ -> "ragel" in 17 | let modes = ["-T0";"-T1";"-F0";"-F1";"-G0";] in 18 | assert (0 = Sys.command "ocamlc -c -g t.ml"); 19 | List.iter (fun mode -> 20 | List.iter (fun name -> 21 | let cmd = sprintf "%s %s -O %s.rl && ocamlc -g t.cmo %s.ml -o %s && ./%s" ragel mode name name name name in 22 | print_endline ("+ " ^ cmd); 23 | if 0 <> Sys.command cmd then (prerr_endline "RESULT: FAILED"; exit 2)) names) modes; 24 | print_endline "RESULT: OK" 25 | 26 | -------------------------------------------------------------------------------- /examples/params.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * Parse command line arguments. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #define BUFLEN 1024 9 | 10 | struct params 11 | { 12 | char buffer[BUFLEN+1]; 13 | int buflen; 14 | int cs; 15 | }; 16 | 17 | %%{ 18 | machine params; 19 | access fsm->; 20 | 21 | # A buffer to collect argurments 22 | 23 | # Append to the buffer. 24 | action append { 25 | if ( fsm->buflen < BUFLEN ) 26 | fsm->buffer[fsm->buflen++] = fc; 27 | } 28 | 29 | # Terminate a buffer. 30 | action term { 31 | if ( fsm->buflen < BUFLEN ) 32 | fsm->buffer[fsm->buflen++] = 0; 33 | } 34 | 35 | # Clear out the buffer 36 | action clear { fsm->buflen = 0; } 37 | 38 | action help { printf("help\n"); } 39 | action version { printf("version\n"); } 40 | action output { printf("output: \"%s\"\n", fsm->buffer); } 41 | action spec { printf("spec: \"%s\"\n", fsm->buffer); } 42 | action mach { printf("machine: \"%s\"\n", fsm->buffer); } 43 | 44 | # Helpers that collect strings 45 | string = [^\0]+ >clear $append %term; 46 | 47 | # Different arguments. 48 | help = ( '-h' | '-H' | '-?' | '--help' ) 0 @help; 49 | version = ( '-v' | '--version' ) 0 @version; 50 | output = '-o' 0? string 0 @output; 51 | spec = '-S' 0? string 0 @spec; 52 | mach = '-M' 0? string 0 @mach; 53 | 54 | main := ( 55 | help | 56 | version | 57 | output | 58 | spec | 59 | mach 60 | )*; 61 | }%% 62 | 63 | %% write data; 64 | 65 | void params_init( struct params *fsm ) 66 | { 67 | fsm->buflen = 0; 68 | %% write init; 69 | } 70 | 71 | void params_execute( struct params *fsm, const char *data, int len ) 72 | { 73 | const char *p = data; 74 | const char *pe = data + len; 75 | 76 | %% write exec; 77 | } 78 | 79 | int params_finish( struct params *fsm ) 80 | { 81 | if ( fsm->cs == params_error ) 82 | return -1; 83 | if ( fsm->cs >= params_first_final ) 84 | return 1; 85 | return 0; 86 | } 87 | 88 | #define BUFSIZE 2048 89 | 90 | int main( int argc, char **argv ) 91 | { 92 | int a; 93 | struct params params; 94 | 95 | params_init( ¶ms ); 96 | for ( a = 1; a < argc; a++ ) 97 | params_execute( ¶ms, argv[a], strlen(argv[a])+1 ); 98 | if ( params_finish( ¶ms ) != 1 ) 99 | fprintf( stderr, "params: error processing arguments\n" ); 100 | 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /examples/rust/.gitignore: -------------------------------------------------------------------------------- 1 | /clang 2 | /concurrent 3 | /gotocallret 4 | /url 5 | /rpn 6 | /scan1 7 | /scan2 8 | /atoi 9 | /*.rc 10 | /*.rs 11 | /*.dSYM 12 | -------------------------------------------------------------------------------- /examples/rust/Makefile: -------------------------------------------------------------------------------- 1 | 2 | .SUFFIXES: 3 | 4 | RAGEL = ../../ragel/ragel 5 | MODE = 6 | RUSTC = rustc -O 7 | 8 | all: url concurrent rpn atoi clang gotocallret scan1 scan2 9 | 10 | url: url.rl 11 | $(RAGEL) $(MODE) --host-lang=rust url_authority.rl -o url_authority.rs 12 | $(RAGEL) $(MODE) --host-lang=rust url.rl -o url.rs 13 | $(RUSTC) --test url.rs 14 | 15 | concurrent: concurrent.rl 16 | $(RAGEL) $(MODE) --host-lang=rust concurrent.rl -o concurrent.rs 17 | $(RUSTC) concurrent.rs 18 | 19 | rpn: rpn.rl 20 | $(RAGEL) $(MODE) --host-lang=rust rpn.rl -o rpn.rs 21 | $(RUSTC) --test rpn.rs 22 | 23 | atoi: atoi.rl 24 | $(RAGEL) $(MODE) --host-lang=rust atoi.rl -o atoi.rs 25 | $(RUSTC) --test atoi.rs 26 | 27 | clang: clang.rl 28 | $(RAGEL) $(MODE) --host-lang=rust clang.rl -o clang.rs 29 | $(RUSTC) clang.rs 30 | 31 | gotocallret: gotocallret.rl 32 | $(RAGEL) $(MODE) --host-lang=rust gotocallret.rl -o gotocallret.rs 33 | $(RUSTC) gotocallret.rs 34 | 35 | scan1: scan1.rl 36 | $(RAGEL) $(MODE) --host-lang=rust scan1.rl -o scan1.rs 37 | $(RUSTC) scan1.rs 38 | 39 | scan2: scan2.rl 40 | $(RAGEL) $(MODE) --host-lang=rust scan2.rl -o scan2.rs 41 | $(RUSTC) scan2.rs 42 | 43 | .PHONY: clean 44 | clean: 45 | rm -f *.o 46 | rm -f $(subst .rl,.rs,$(wildcard *.rl)) 47 | rm -f $(subst .rl,,$(wildcard *.rl)) 48 | -------------------------------------------------------------------------------- /examples/rust/README: -------------------------------------------------------------------------------- 1 | 2 | ragel examples for Rust codegen 3 | ================================ 4 | 5 | `make` will run several simple tests. 6 | `make run_url` will compile and run url parser benchmark. 7 | 8 | Examples were taken from examples/ocaml/, examples/go/ and examples/ and 9 | converted to Rust, thanks to original authors. 10 | 11 | -- 12 | erickt 13 | 14 | -------------------------------------------------------------------------------- /examples/rust/atoi.rl: -------------------------------------------------------------------------------- 1 | %%{ 2 | machine atoi; 3 | write data; 4 | }%% 5 | 6 | 7 | fn atoi(data: &str) -> Option { 8 | let mut cs: int; 9 | let mut p = 0; 10 | let pe = data.len(); 11 | let mut neg = false; 12 | let mut res = 0; 13 | 14 | %%{ 15 | action see_neg { neg = true; } 16 | action add_digit { res = res * 10 + (fc as int - '0' as int); } 17 | 18 | main := 19 | ( '-' @see_neg | '+' )? ( digit @add_digit )+ 20 | '\n'? 21 | ; 22 | 23 | write init; 24 | write exec; 25 | }%% 26 | 27 | if neg { res = -1 * res; } 28 | 29 | if cs < atoi_first_final { 30 | None 31 | } else { 32 | Some(res) 33 | } 34 | } 35 | 36 | #[test] 37 | fn test_atoi() { 38 | assert_eq!(atoi("7"), Some(7)); 39 | assert_eq!(atoi("666"), Some(666)); 40 | assert_eq!(atoi("-666"), Some(-666)); 41 | assert_eq!(atoi("+666"), Some(666)); 42 | assert_eq!(atoi("123456789"), Some(123456789)); 43 | assert_eq!(atoi("+123456789\n"), Some(123456789)); 44 | assert_eq!(atoi("+ 1234567890"), None); 45 | } 46 | -------------------------------------------------------------------------------- /examples/rust/scan2.rl: -------------------------------------------------------------------------------- 1 | %%{ 2 | machine scanner; 3 | 4 | # Warning: changing the patterns or the input string will affect the 5 | # coverage of the scanner action types. 6 | main := |* 7 | 'a' => { 8 | assert_eq!(expect[i], Pat1); 9 | i += 1; 10 | }; 11 | 12 | [ab]+ . 'c' => { 13 | assert_eq!(expect[i], Pat2); 14 | i += 1; 15 | }; 16 | 17 | any => { 18 | assert_eq!(expect[i], Any); 19 | i += 1; 20 | }; 21 | *|; 22 | 23 | write data; 24 | }%% 25 | 26 | #[deriving(Eq)] 27 | enum Expect { Pat1, Pat2, Any } 28 | 29 | #[allow(dead_assignment, unused_variable)] 30 | fn main() { 31 | let mut i = 0; 32 | let expect = ~[Pat1, Any, Pat2, Any, Any, Any]; 33 | 34 | let mut ts: uint; 35 | let mut te: uint; 36 | let mut cs: int; 37 | let mut act: uint; 38 | let data = ~"araabccde"; 39 | let mut p = 0; 40 | let pe = data.len(); 41 | let eof = pe; 42 | %% write init; 43 | %% write exec; 44 | } 45 | -------------------------------------------------------------------------------- /examples/statechart.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * Demonstrate the use of labels, the epsilon operator, and the join operator 3 | * for creating machines using the named state and transition list paradigm. 4 | * This implementes the same machine as the atoi example. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | struct StateChart 15 | { 16 | bool neg; 17 | int val; 18 | int cs; 19 | 20 | int init( ); 21 | int execute( const char *data, int len ); 22 | int finish( ); 23 | }; 24 | 25 | %%{ 26 | machine StateChart; 27 | 28 | action begin { 29 | neg = false; 30 | val = 0; 31 | } 32 | 33 | action see_neg { 34 | neg = true; 35 | } 36 | 37 | action add_digit { 38 | val = val * 10 + (fc - '0'); 39 | } 40 | 41 | action finish { 42 | if ( neg ) 43 | val = -1 * val; 44 | } 45 | 46 | atoi = ( 47 | start: ( 48 | '-' @see_neg ->om_num | 49 | '+' ->om_num | 50 | [0-9] @add_digit ->more_nums 51 | ), 52 | 53 | # One or more nums. 54 | om_num: ( 55 | [0-9] @add_digit ->more_nums 56 | ), 57 | 58 | # Zero ore more nums. 59 | more_nums: ( 60 | [0-9] @add_digit ->more_nums | 61 | '' -> final 62 | ) 63 | ) >begin %finish; 64 | 65 | main := ( atoi '\n' @{ cout << val << endl; } )*; 66 | }%% 67 | 68 | %% write data; 69 | 70 | int StateChart::init( ) 71 | { 72 | neg = false; 73 | val = false; 74 | %% write init; 75 | return 1; 76 | } 77 | 78 | int StateChart::execute( const char *data, int len ) 79 | { 80 | const char *p = data; 81 | const char *pe = data + len; 82 | 83 | %% write exec; 84 | 85 | if ( cs == StateChart_error ) 86 | return -1; 87 | if ( cs >= StateChart_first_final ) 88 | return 1; 89 | return 0; 90 | } 91 | 92 | int StateChart::finish( ) 93 | { 94 | if ( cs == StateChart_error ) 95 | return -1; 96 | if ( cs >= StateChart_first_final ) 97 | return 1; 98 | return 0; 99 | } 100 | 101 | 102 | #define BUFSIZE 1024 103 | 104 | int main() 105 | { 106 | char buf[BUFSIZE]; 107 | 108 | StateChart atoi; 109 | atoi.init(); 110 | while ( fgets( buf, sizeof(buf), stdin ) != 0 ) { 111 | atoi.execute( buf, strlen(buf) ); 112 | } 113 | if ( atoi.finish() <= 0 ) 114 | cerr << "statechart: error: parsing input" << endl; 115 | return 0; 116 | } 117 | -------------------------------------------------------------------------------- /examples/uri.rl: -------------------------------------------------------------------------------- 1 | %%{ 2 | machine uri; 3 | 4 | action scheme {} 5 | action loc {} 6 | action item {} 7 | action query {} 8 | action last {} 9 | action nothing {} 10 | 11 | main := 12 | # Scheme machine. This is ambiguous with the item machine. We commit 13 | # to the scheme machine on colon. 14 | ( [^:/?#]+ ':' @(colon,1) @scheme )? 15 | 16 | # Location machine. This is ambiguous with the item machine. We remain 17 | # ambiguous until a second slash, at that point and all points after 18 | # we place a higher priority on staying in the location machine over 19 | # moving into the item machine. 20 | ( ( '/' ( '/' [^/?#]* ) $(loc,1) ) %loc %/loc )? 21 | 22 | # Item machine. Ambiguous with both scheme and location, which both 23 | # get a higher priority on the characters causing ambiguity. 24 | ( ( [^?#]+ ) $(loc,0) $(colon,0) %item %/item )? 25 | 26 | # Last two components, the characters that initiate these machines are 27 | # not supported in any previous components, therefore there are no 28 | # ambiguities introduced by these parts. 29 | ( '?' [^#]* %query %/query)? 30 | ( '#' any* %/last )?; 31 | }%% 32 | -------------------------------------------------------------------------------- /ragel/.gitignore: -------------------------------------------------------------------------------- 1 | /tags 2 | /Makefile 3 | /Makefile.in 4 | /rlscan.cpp 5 | /rlparse.cpp 6 | /rlparse.h 7 | /version.h 8 | /config.h 9 | /config.h.in 10 | /ragel 11 | /ragel.exe 12 | /.deps 13 | /stamp-h1 14 | /*.o 15 | -------------------------------------------------------------------------------- /ragel/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | INCLUDES = -I$(top_srcdir)/aapl 3 | 4 | bin_PROGRAMS = ragel 5 | 6 | ragel_CXXFLAGS = -Wall 7 | 8 | ragel_SOURCES = \ 9 | buffer.h cdgoto.h cscodegen.h csipgoto.h inputdata.h rbxgoto.h \ 10 | rubyflat.h cdcodegen.h cdipgoto.h csfflat.h cssplit.h javacodegen.h \ 11 | redfsm.h rubyftable.h cdfflat.h cdsplit.h csfgoto.h cstable.h \ 12 | parsedata.h rlparse.h rubytable.h cdfgoto.h cdtable.h csflat.h \ 13 | dotcodegen.h parsetree.h rlscan.h version.h cdflat.h common.h \ 14 | csftable.h fsmgraph.h pcheck.h rubycodegen.h xmlcodegen.h cdftable.h \ 15 | csgoto.h gendata.h ragel.h rubyfflat.h \ 16 | gocodegen.h gotable.h goftable.h goflat.h gofflat.h gogoto.h gofgoto.h \ 17 | goipgoto.h gotablish.h \ 18 | mlcodegen.h mltable.h mlftable.h mlflat.h mlfflat.h mlgoto.h \ 19 | main.cpp parsetree.cpp parsedata.cpp fsmstate.cpp fsmbase.cpp \ 20 | fsmattach.cpp fsmmin.cpp fsmgraph.cpp fsmap.cpp rlscan.cpp rlparse.cpp \ 21 | inputdata.cpp common.cpp redfsm.cpp gendata.cpp cdcodegen.cpp \ 22 | cdtable.cpp cdftable.cpp cdflat.cpp cdfflat.cpp cdgoto.cpp cdfgoto.cpp \ 23 | cdipgoto.cpp cdsplit.cpp javacodegen.cpp rubycodegen.cpp rubytable.cpp \ 24 | rubyftable.cpp rubyflat.cpp rubyfflat.cpp rbxgoto.cpp cscodegen.cpp \ 25 | cstable.cpp csftable.cpp csflat.cpp csfflat.cpp csgoto.cpp csfgoto.cpp \ 26 | csipgoto.cpp cssplit.cpp dotcodegen.cpp xmlcodegen.cpp \ 27 | gocodegen.cpp gotable.cpp goftable.cpp goflat.cpp gofflat.cpp gogoto.cpp gofgoto.cpp \ 28 | goipgoto.cpp gotablish.cpp \ 29 | mlcodegen.cpp mltable.cpp mlftable.cpp mlflat.cpp mlfflat.cpp mlgoto.cpp \ 30 | rustcodegen.h rustcodegen.cc 31 | 32 | BUILT_SOURCES = \ 33 | rlscan.cpp rlparse.h rlparse.cpp version.h 34 | 35 | version.h: Makefile 36 | echo '#define VERSION "$(PACKAGE_VERSION)"' > version.h 37 | echo '#define PUBDATE "$(PUBDATE)"' >> version.h 38 | 39 | EXTRA_DIST = rlscan.rl rlparse.kh rlparse.kl 40 | 41 | if BUILD_PARSERS 42 | 43 | CLEANFILES = \ 44 | rlscan.cpp rlparse.h rlparse.cpp 45 | 46 | rlparse.h: rlparse.kh 47 | kelbt -o $@ $< 48 | 49 | rlparse.cpp: rlparse.kl rlparse.kh 50 | kelbt -o $@ $< 51 | 52 | # This dependency comes from the import of the parser defines 53 | # into the scanner. 54 | rlscan.cpp: rlparse.h 55 | 56 | rlscan.cpp: rlscan.rl 57 | ragel -G2 -I$(builddir) -o $@ $< 58 | 59 | endif 60 | -------------------------------------------------------------------------------- /ragel/buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003 Adrian Thurston 3 | */ 4 | 5 | /* This file is part of Ragel. 6 | * 7 | * Ragel is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Ragel is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Ragel; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #ifndef _BUFFER_H 23 | #define _BUFFER_H 24 | 25 | #define BUFFER_INITIAL_SIZE 4096 26 | 27 | /* An automatically grown buffer for collecting tokens. Always reuses space; 28 | * never down resizes. */ 29 | struct Buffer 30 | { 31 | Buffer() 32 | { 33 | data = (char*) malloc( BUFFER_INITIAL_SIZE ); 34 | allocated = BUFFER_INITIAL_SIZE; 35 | length = 0; 36 | } 37 | ~Buffer() { free(data); } 38 | 39 | void append( char p ) 40 | { 41 | if ( length == allocated ) { 42 | allocated *= 2; 43 | data = (char*) realloc( data, allocated ); 44 | } 45 | data[length++] = p; 46 | } 47 | 48 | void clear() { length = 0; } 49 | 50 | char *data; 51 | int allocated; 52 | int length; 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /ragel/cdfflat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2004-2006 Adrian Thurston 3 | * 2004 Erich Ocean 4 | * 2005 Alan West 5 | */ 6 | 7 | /* This file is part of Ragel. 8 | * 9 | * Ragel is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * Ragel is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with Ragel; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef _CDFFLAT_H 25 | #define _CDFFLAT_H 26 | 27 | #include 28 | #include "cdflat.h" 29 | 30 | /* Forwards. */ 31 | struct CodeGenData; 32 | 33 | /* 34 | * FFlatCodeGen 35 | */ 36 | class FFlatCodeGen : public FlatCodeGen 37 | { 38 | protected: 39 | FFlatCodeGen( ostream &out ) : FsmCodeGen(out), FlatCodeGen(out) {} 40 | 41 | std::ostream &TO_STATE_ACTION_SWITCH(); 42 | std::ostream &FROM_STATE_ACTION_SWITCH(); 43 | std::ostream &EOF_ACTION_SWITCH(); 44 | std::ostream &ACTION_SWITCH(); 45 | 46 | virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); 47 | virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); 48 | virtual std::ostream &EOF_ACTION( RedStateAp *state ); 49 | virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); 50 | 51 | virtual void writeData(); 52 | virtual void writeExec(); 53 | }; 54 | 55 | /* 56 | * CFFlatCodeGen 57 | */ 58 | struct CFFlatCodeGen 59 | : public FFlatCodeGen, public CCodeGen 60 | { 61 | CFFlatCodeGen( ostream &out ) : 62 | FsmCodeGen(out), FFlatCodeGen(out), CCodeGen(out) {} 63 | }; 64 | 65 | /* 66 | * DFFlatCodeGen 67 | */ 68 | struct DFFlatCodeGen 69 | : public FFlatCodeGen, public DCodeGen 70 | { 71 | DFFlatCodeGen( ostream &out ) : 72 | FsmCodeGen(out), FFlatCodeGen(out), DCodeGen(out) {} 73 | }; 74 | 75 | /* 76 | * D2FFlatCodeGen 77 | */ 78 | struct D2FFlatCodeGen 79 | : public FFlatCodeGen, public D2CodeGen 80 | { 81 | D2FFlatCodeGen( ostream &out ) : 82 | FsmCodeGen(out), FFlatCodeGen(out), D2CodeGen(out) {} 83 | }; 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /ragel/cdfgoto.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2001-2006 Adrian Thurston 3 | * 2004 Erich Ocean 4 | * 2005 Alan West 5 | */ 6 | 7 | /* This file is part of Ragel. 8 | * 9 | * Ragel is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * Ragel is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with Ragel; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef _CDFGOTO_H 25 | #define _CDFGOTO_H 26 | 27 | #include 28 | #include "cdgoto.h" 29 | 30 | /* Forwards. */ 31 | struct CodeGenData; 32 | 33 | 34 | /* 35 | * class FGotoCodeGen 36 | */ 37 | class FGotoCodeGen : public GotoCodeGen 38 | { 39 | public: 40 | FGotoCodeGen( ostream &out ) : FsmCodeGen(out), GotoCodeGen(out) {} 41 | 42 | std::ostream &EXEC_ACTIONS(); 43 | std::ostream &TO_STATE_ACTION_SWITCH(); 44 | std::ostream &FROM_STATE_ACTION_SWITCH(); 45 | std::ostream &FINISH_CASES(); 46 | std::ostream &EOF_ACTION_SWITCH(); 47 | unsigned int TO_STATE_ACTION( RedStateAp *state ); 48 | unsigned int FROM_STATE_ACTION( RedStateAp *state ); 49 | unsigned int EOF_ACTION( RedStateAp *state ); 50 | 51 | virtual void writeData(); 52 | virtual void writeExec(); 53 | }; 54 | 55 | /* 56 | * class CFGotoCodeGen 57 | */ 58 | struct CFGotoCodeGen 59 | : public FGotoCodeGen, public CCodeGen 60 | { 61 | CFGotoCodeGen( ostream &out ) : 62 | FsmCodeGen(out), FGotoCodeGen(out), CCodeGen(out) {} 63 | }; 64 | 65 | /* 66 | * class DFGotoCodeGen 67 | */ 68 | struct DFGotoCodeGen 69 | : public FGotoCodeGen, public DCodeGen 70 | { 71 | DFGotoCodeGen( ostream &out ) : 72 | FsmCodeGen(out), FGotoCodeGen(out), DCodeGen(out) {} 73 | }; 74 | 75 | /* 76 | * class DFGotoCodeGen 77 | */ 78 | struct D2FGotoCodeGen 79 | : public FGotoCodeGen, public D2CodeGen 80 | { 81 | D2FGotoCodeGen( ostream &out ) : 82 | FsmCodeGen(out), FGotoCodeGen(out), D2CodeGen(out) {} 83 | }; 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /ragel/cdsplit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006 Adrian Thurston 3 | */ 4 | 5 | /* This file is part of Ragel. 6 | * 7 | * Ragel is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Ragel is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Ragel; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #ifndef _CDSPLIT_H 23 | #define _CDSPLIT_H 24 | 25 | #include "cdipgoto.h" 26 | 27 | class SplitCodeGen : public IpGotoCodeGen 28 | { 29 | public: 30 | SplitCodeGen( ostream &out ) : FsmCodeGen(out), IpGotoCodeGen(out) {} 31 | 32 | bool ptOutLabelUsed; 33 | 34 | std::ostream &PART_MAP(); 35 | std::ostream &EXIT_STATES( int partition ); 36 | std::ostream &PART_TRANS( int partition ); 37 | std::ostream &TRANS_GOTO( RedTransAp *trans, int level ); 38 | void GOTO_HEADER( RedStateAp *state, bool stateInPartition ); 39 | std::ostream &STATE_GOTOS( int partition ); 40 | std::ostream &PARTITION( int partition ); 41 | std::ostream &ALL_PARTITIONS(); 42 | void writeData(); 43 | void writeExec(); 44 | void writeParts(); 45 | 46 | void setLabelsNeeded( RedStateAp *fromState, GenInlineList *inlineList ); 47 | void setLabelsNeeded( RedStateAp *fromState, RedTransAp *trans ); 48 | void setLabelsNeeded(); 49 | 50 | int currentPartition; 51 | }; 52 | 53 | struct CSplitCodeGen 54 | : public SplitCodeGen, public CCodeGen 55 | { 56 | CSplitCodeGen( ostream &out ) : 57 | FsmCodeGen(out), SplitCodeGen(out), CCodeGen(out) {} 58 | }; 59 | 60 | /* 61 | * class DIpGotoCodeGen 62 | */ 63 | struct DSplitCodeGen 64 | : public SplitCodeGen, public DCodeGen 65 | { 66 | DSplitCodeGen( ostream &out ) : 67 | FsmCodeGen(out), SplitCodeGen(out), DCodeGen(out) {} 68 | }; 69 | 70 | /* 71 | * class D2SplitCodeGen 72 | */ 73 | struct D2SplitCodeGen 74 | : public SplitCodeGen, public D2CodeGen 75 | { 76 | D2SplitCodeGen( ostream &out ) : 77 | FsmCodeGen(out), SplitCodeGen(out), D2CodeGen(out) {} 78 | }; 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /ragel/csfflat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2004-2006 Adrian Thurston 3 | * 2004 Erich Ocean 4 | * 2005 Alan West 5 | */ 6 | 7 | /* This file is part of Ragel. 8 | * 9 | * Ragel is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * Ragel is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with Ragel; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef _CSFFLAT_H 25 | #define _CSFFLAT_H 26 | 27 | #include 28 | #include "csflat.h" 29 | 30 | /* Forwards. */ 31 | struct CodeGenData; 32 | 33 | /* 34 | * CSharpFFlatCodeGen 35 | */ 36 | class CSharpFFlatCodeGen : public CSharpFlatCodeGen 37 | { 38 | public: 39 | CSharpFFlatCodeGen( ostream &out ) : CSharpFsmCodeGen(out), CSharpFlatCodeGen(out) {} 40 | private: 41 | std::ostream &TO_STATE_ACTION_SWITCH(); 42 | std::ostream &FROM_STATE_ACTION_SWITCH(); 43 | std::ostream &EOF_ACTION_SWITCH(); 44 | std::ostream &ACTION_SWITCH(); 45 | 46 | virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); 47 | virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); 48 | virtual std::ostream &EOF_ACTION( RedStateAp *state ); 49 | virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); 50 | 51 | virtual void writeData(); 52 | virtual void writeExec(); 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /ragel/csfgoto.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2001-2006 Adrian Thurston 3 | * 2004 Erich Ocean 4 | * 2005 Alan West 5 | */ 6 | 7 | /* This file is part of Ragel. 8 | * 9 | * Ragel is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * Ragel is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with Ragel; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef _CSFGOTO_H 25 | #define _CSFGOTO_H 26 | 27 | #include 28 | #include "csgoto.h" 29 | 30 | /* Forwards. */ 31 | struct CodeGenData; 32 | 33 | 34 | /* 35 | * class CSharpFGotoCodeGen 36 | */ 37 | class CSharpFGotoCodeGen : public CSharpGotoCodeGen 38 | { 39 | public: 40 | CSharpFGotoCodeGen( ostream &out ) : CSharpFsmCodeGen(out), CSharpGotoCodeGen(out) {} 41 | 42 | std::ostream &EXEC_ACTIONS(); 43 | std::ostream &TO_STATE_ACTION_SWITCH(); 44 | std::ostream &FROM_STATE_ACTION_SWITCH(); 45 | std::ostream &FINISH_CASES(); 46 | std::ostream &EOF_ACTION_SWITCH(); 47 | unsigned int TO_STATE_ACTION( RedStateAp *state ); 48 | unsigned int FROM_STATE_ACTION( RedStateAp *state ); 49 | unsigned int EOF_ACTION( RedStateAp *state ); 50 | 51 | virtual void writeData(); 52 | virtual void writeExec(); 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /ragel/csftable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2001-2006 Adrian Thurston 3 | * 2004 Erich Ocean 4 | * 2005 Alan West 5 | */ 6 | 7 | /* This file is part of Ragel. 8 | * 9 | * Ragel is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * Ragel is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with Ragel; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef _CSFTABLE_H 25 | #define _CSFTABLE_H 26 | 27 | #include 28 | #include "cstable.h" 29 | 30 | /* Forwards. */ 31 | struct CodeGenData; 32 | 33 | 34 | /* 35 | * CSharpFTabCodeGen 36 | */ 37 | class CSharpFTabCodeGen : public CSharpTabCodeGen 38 | { 39 | public: 40 | CSharpFTabCodeGen( ostream &out ) : CSharpFsmCodeGen(out), CSharpTabCodeGen(out) {} 41 | private: 42 | std::ostream &TO_STATE_ACTION_SWITCH(); 43 | std::ostream &FROM_STATE_ACTION_SWITCH(); 44 | std::ostream &EOF_ACTION_SWITCH(); 45 | std::ostream &ACTION_SWITCH(); 46 | 47 | virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); 48 | virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); 49 | virtual std::ostream &EOF_ACTION( RedStateAp *state ); 50 | virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); 51 | virtual void writeData(); 52 | virtual void writeExec(); 53 | virtual void calcIndexSize(); 54 | }; 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /ragel/cssplit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006 Adrian Thurston 3 | */ 4 | 5 | /* This file is part of Ragel. 6 | * 7 | * Ragel is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Ragel is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Ragel; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #ifndef _SPLITCODEGEN_H 23 | #define _SPLITCODEGEN_H 24 | 25 | #include "csipgoto.h" 26 | 27 | class CSharpSplitCodeGen : public CSharpIpGotoCodeGen 28 | { 29 | public: 30 | CSharpSplitCodeGen( ostream &out ) : CSharpFsmCodeGen(out), CSharpIpGotoCodeGen(out) {} 31 | 32 | bool ptOutLabelUsed; 33 | 34 | std::ostream &PART_MAP(); 35 | std::ostream &EXIT_STATES( int partition ); 36 | std::ostream &PART_TRANS( int partition ); 37 | std::ostream &TRANS_GOTO( RedTransAp *trans, int level ); 38 | void GOTO_HEADER( RedStateAp *state, bool stateInPartition ); 39 | std::ostream &STATE_GOTOS( int partition ); 40 | std::ostream &PARTITION( int partition ); 41 | std::ostream &ALL_PARTITIONS(); 42 | void writeData(); 43 | void writeExec(); 44 | void writeParts(); 45 | 46 | void setLabelsNeeded( RedStateAp *fromState, GenInlineList *inlineList ); 47 | void setLabelsNeeded( RedStateAp *fromState, RedTransAp *trans ); 48 | void setLabelsNeeded(); 49 | 50 | int currentPartition; 51 | }; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /ragel/dotcodegen.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2001-2007 Adrian Thurston 3 | */ 4 | 5 | /* This file is part of Ragel. 6 | * 7 | * Ragel is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Ragel is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Ragel; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #ifndef _GVDOTGEN_H 23 | #define _GVDOTGEN_H 24 | 25 | #include 26 | #include "gendata.h" 27 | 28 | class GraphvizDotGen : public CodeGenData 29 | { 30 | public: 31 | GraphvizDotGen( ostream &out ) : CodeGenData(out) { } 32 | 33 | /* Print an fsm to out stream. */ 34 | void writeTransList( RedStateAp *state ); 35 | void writeDotFile( ); 36 | 37 | virtual void finishRagelDef(); 38 | virtual void writeStatement( InputLoc &, int, char ** ); 39 | 40 | private: 41 | /* Writing labels and actions. */ 42 | std::ostream &ONCHAR( Key lowKey, Key highKey ); 43 | std::ostream &TRANS_ACTION( RedStateAp *fromState, RedTransAp *trans ); 44 | std::ostream &ACTION( RedAction *action ); 45 | std::ostream &KEY( Key key ); 46 | }; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /ragel/gofflat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2004-2006 Adrian Thurston 3 | * 2004 Erich Ocean 4 | * 2005 Alan West 5 | */ 6 | 7 | /* This file is part of Ragel. 8 | * 9 | * Ragel is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * Ragel is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with Ragel; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef _GOFFLAT_H 25 | #define _GOFFLAT_H 26 | 27 | #include 28 | #include "goflat.h" 29 | 30 | /* Forwards. */ 31 | struct CodeGenData; 32 | 33 | /* 34 | * FFlatCodeGen 35 | */ 36 | class GoFFlatCodeGen 37 | : public GoFlatCodeGen 38 | { 39 | public: 40 | GoFFlatCodeGen( ostream &out ) 41 | : GoFlatCodeGen(out) {} 42 | 43 | protected: 44 | std::ostream &TO_STATE_ACTION_SWITCH( int level ); 45 | std::ostream &FROM_STATE_ACTION_SWITCH( int level ); 46 | std::ostream &EOF_ACTION_SWITCH( int level ); 47 | std::ostream &ACTION_SWITCH( int level ); 48 | 49 | virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); 50 | virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); 51 | virtual std::ostream &EOF_ACTION( RedStateAp *state ); 52 | virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); 53 | 54 | virtual void writeData(); 55 | virtual void writeExec(); 56 | }; 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /ragel/gofgoto.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2001-2006 Adrian Thurston 3 | * 2004 Erich Ocean 4 | * 2005 Alan West 5 | */ 6 | 7 | /* This file is part of Ragel. 8 | * 9 | * Ragel is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * Ragel is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with Ragel; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef _GOFGOTO_H 25 | #define _GOFGOTO_H 26 | 27 | #include 28 | #include "gogoto.h" 29 | 30 | /* Forwards. */ 31 | struct CodeGenData; 32 | 33 | 34 | class GoFGotoCodeGen 35 | : public GoGotoCodeGen 36 | { 37 | public: 38 | GoFGotoCodeGen( ostream &out ) 39 | : GoGotoCodeGen(out) {} 40 | 41 | std::ostream &EXEC_ACTIONS(); 42 | std::ostream &TO_STATE_ACTION_SWITCH( int level ); 43 | std::ostream &FROM_STATE_ACTION_SWITCH( int level ); 44 | std::ostream &FINISH_CASES(); 45 | std::ostream &EOF_ACTION_SWITCH( int level ); 46 | unsigned int TO_STATE_ACTION( RedStateAp *state ); 47 | unsigned int FROM_STATE_ACTION( RedStateAp *state ); 48 | unsigned int EOF_ACTION( RedStateAp *state ); 49 | 50 | virtual void writeData(); 51 | virtual void writeExec(); 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /ragel/goflat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2004-2006 Adrian Thurston 3 | * 2004 Erich Ocean 4 | * 2005 Alan West 5 | */ 6 | 7 | /* This file is part of Ragel. 8 | * 9 | * Ragel is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * Ragel is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with Ragel; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef _GOFLAT_H 25 | #define _GOFLAT_H 26 | 27 | #include 28 | #include "gotablish.h" 29 | 30 | /* Forwards. */ 31 | struct CodeGenData; 32 | struct NameInst; 33 | struct RedTransAp; 34 | struct RedStateAp; 35 | 36 | /* 37 | * GoFlatCodeGen 38 | */ 39 | class GoFlatCodeGen 40 | : public GoTablishCodeGen 41 | { 42 | public: 43 | GoFlatCodeGen( ostream &out ) 44 | : GoTablishCodeGen(out) {} 45 | 46 | virtual ~GoFlatCodeGen() { } 47 | 48 | protected: 49 | std::ostream &TO_STATE_ACTION_SWITCH( int level ); 50 | std::ostream &FROM_STATE_ACTION_SWITCH( int level ); 51 | std::ostream &EOF_ACTION_SWITCH( int level ); 52 | std::ostream &ACTION_SWITCH( int level ); 53 | std::ostream &KEYS(); 54 | std::ostream &INDICIES(); 55 | std::ostream &FLAT_INDEX_OFFSET(); 56 | std::ostream &KEY_SPANS(); 57 | std::ostream &TO_STATE_ACTIONS(); 58 | std::ostream &FROM_STATE_ACTIONS(); 59 | std::ostream &EOF_ACTIONS(); 60 | std::ostream &EOF_TRANS(); 61 | std::ostream &TRANS_TARGS(); 62 | std::ostream &TRANS_ACTIONS(); 63 | void LOCATE_TRANS(); 64 | 65 | std::ostream &COND_INDEX_OFFSET(); 66 | void COND_TRANSLATE(); 67 | std::ostream &CONDS(); 68 | std::ostream &COND_KEYS(); 69 | std::ostream &COND_KEY_SPANS(); 70 | 71 | virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); 72 | virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); 73 | virtual std::ostream &EOF_ACTION( RedStateAp *state ); 74 | virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); 75 | 76 | virtual void writeData(); 77 | virtual void writeExec(); 78 | }; 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /ragel/goftable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2001-2006 Adrian Thurston 3 | * 2004 Erich Ocean 4 | * 2005 Alan West 5 | */ 6 | 7 | /* This file is part of Ragel. 8 | * 9 | * Ragel is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * Ragel is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with Ragel; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef _GOFTABLE_H 25 | #define _GOFTABLE_H 26 | 27 | #include 28 | #include "gotable.h" 29 | 30 | /* Forwards. */ 31 | struct CodeGenData; 32 | 33 | /* 34 | * GoFTabCode 35 | */ 36 | class GoFTabCodeGen 37 | : public GoTabCodeGen 38 | { 39 | public: 40 | GoFTabCodeGen( ostream &out ) 41 | : GoTabCodeGen(out) {} 42 | 43 | protected: 44 | std::ostream &TO_STATE_ACTION_SWITCH( int level ); 45 | std::ostream &FROM_STATE_ACTION_SWITCH( int level ); 46 | std::ostream &EOF_ACTION_SWITCH( int level ); 47 | std::ostream &ACTION_SWITCH( int level ); 48 | 49 | virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); 50 | virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); 51 | virtual std::ostream &EOF_ACTION( RedStateAp *state ); 52 | virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); 53 | 54 | virtual void writeData(); 55 | virtual void writeExec(); 56 | virtual void calcIndexSize(); 57 | }; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /ragel/gotablish.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2001-2006 Adrian Thurston 3 | * 2004 Erich Ocean 4 | * 2005 Alan West 5 | */ 6 | 7 | /* This file is part of Ragel. 8 | * 9 | * Ragel is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * Ragel is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with Ragel; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef _GOTABLISH_H 25 | #define _GOTABLISH_H 26 | 27 | #include "gocodegen.h" 28 | 29 | class GoTablishCodeGen 30 | : public GoCodeGen 31 | { 32 | public: 33 | GoTablishCodeGen( ostream &out ) 34 | : GoCodeGen(out) {} 35 | protected: 36 | virtual void GOTO( ostream &ret, int gotoDest, bool inFinish ); 37 | virtual void CALL( ostream &ret, int callDest, int targState, bool inFinish ); 38 | virtual void NEXT( ostream &ret, int nextDest, bool inFinish ); 39 | virtual void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); 40 | virtual void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); 41 | virtual void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ); 42 | virtual void CURS( ostream &ret, bool inFinish ); 43 | virtual void TARGS( ostream &ret, bool inFinish, int targState ); 44 | virtual void RET( ostream &ret, bool inFinish ); 45 | virtual void BREAK( ostream &ret, int targState, bool csForced ); 46 | }; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /ragel/mlfflat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2004-2006 Adrian Thurston 3 | * 2004 Erich Ocean 4 | * 2005 Alan West 5 | */ 6 | 7 | /* This file is part of Ragel. 8 | * 9 | * Ragel is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * Ragel is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with Ragel; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef _MLFFLAT_H 25 | #define _MLFFLAT_H 26 | 27 | #include 28 | #include "mlflat.h" 29 | 30 | /* Forwards. */ 31 | //struct CodeGenData; 32 | 33 | /* 34 | * OCamlFFlatCodeGen 35 | */ 36 | class OCamlFFlatCodeGen : public OCamlFlatCodeGen 37 | { 38 | public: 39 | OCamlFFlatCodeGen( ostream &out ) : OCamlFlatCodeGen(out) {} 40 | private: 41 | std::ostream &TO_STATE_ACTION_SWITCH(); 42 | std::ostream &FROM_STATE_ACTION_SWITCH(); 43 | std::ostream &EOF_ACTION_SWITCH(); 44 | std::ostream &ACTION_SWITCH(); 45 | 46 | virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); 47 | virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); 48 | virtual std::ostream &EOF_ACTION( RedStateAp *state ); 49 | virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); 50 | 51 | virtual void writeData(); 52 | virtual void writeExec(); 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /ragel/mlftable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2001-2006 Adrian Thurston 3 | * 2004 Erich Ocean 4 | * 2005 Alan West 5 | */ 6 | 7 | /* This file is part of Ragel. 8 | * 9 | * Ragel is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * Ragel is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with Ragel; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef _MLFTABLE_H 25 | #define _MLFTABLE_H 26 | 27 | #include 28 | #include "mltable.h" 29 | 30 | /* Forwards. */ 31 | //struct CodeGenData; 32 | 33 | 34 | /* 35 | * OCamlFTabCodeGen 36 | */ 37 | class OCamlFTabCodeGen : public OCamlTabCodeGen 38 | { 39 | public: 40 | OCamlFTabCodeGen( ostream &out ) : OCamlTabCodeGen(out) {} 41 | private: 42 | std::ostream &TO_STATE_ACTION_SWITCH(); 43 | std::ostream &FROM_STATE_ACTION_SWITCH(); 44 | std::ostream &EOF_ACTION_SWITCH(); 45 | std::ostream &ACTION_SWITCH(); 46 | 47 | virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); 48 | virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); 49 | virtual std::ostream &EOF_ACTION( RedStateAp *state ); 50 | virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); 51 | virtual void writeData(); 52 | virtual void writeExec(); 53 | virtual void calcIndexSize(); 54 | }; 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /ragel/pcheck.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2001, 2002 Adrian Thurston 3 | */ 4 | 5 | /* This file is part of Ragel. 6 | * 7 | * Ragel is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Ragel is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Ragel; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #ifndef _PCHECK_H 23 | #define _PCHECK_H 24 | 25 | class ParamCheck 26 | { 27 | public: 28 | ParamCheck( const char *paramSpec, int argc, const char **argv); 29 | 30 | bool check(); 31 | 32 | const char *paramArg; /* The argument to the parameter. */ 33 | char parameter; /* The parameter matched. */ 34 | enum { match, invalid, noparam } state; 35 | 36 | const char *argOffset; /* If we are reading params inside an 37 | * arg this points to the offset. */ 38 | 39 | const char *curArg; /* Pointer to the current arg. */ 40 | int iCurArg; /* Index to the current arg. */ 41 | 42 | private: 43 | const char *paramSpec; /* Parameter spec supplied by the coder. */ 44 | int argc; /* Arguement data from the command line. */ 45 | const char **argv; 46 | }; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /ragel/rubyfflat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 2007 Victor Hugo Borja 3 | * Copyright 2001-2007 Adrian Thurston 4 | */ 5 | 6 | /* This file is part of Ragel. 7 | * 8 | * Ragel is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * Ragel is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with Ragel; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 | */ 22 | 23 | #ifndef _RUBY_FFLATCODEGEN_H 24 | #define _RUBY_FFLATCODEGEN_H 25 | 26 | #include 27 | #include "rubyflat.h" 28 | 29 | class RubyFFlatCodeGen : public RubyFlatCodeGen 30 | { 31 | public: 32 | RubyFFlatCodeGen( ostream &out ) : 33 | RubyFlatCodeGen(out) {} 34 | protected: 35 | 36 | std::ostream &TO_STATE_ACTION_SWITCH(); 37 | std::ostream &FROM_STATE_ACTION_SWITCH(); 38 | std::ostream &EOF_ACTION_SWITCH(); 39 | std::ostream &ACTION_SWITCH(); 40 | 41 | void GOTO( ostream &out, int gotoDest, bool inFinish ); 42 | void GOTO_EXPR( ostream &out, GenInlineItem *ilItem, bool inFinish ); 43 | void CALL( ostream &out, int callDest, int targState, bool inFinish ); 44 | void CALL_EXPR(ostream &out, GenInlineItem *ilItem, int targState, bool inFinish ); 45 | void RET( ostream &out, bool inFinish ); 46 | void BREAK( ostream &out, int targState ); 47 | 48 | virtual int TO_STATE_ACTION( RedStateAp *state ); 49 | virtual int FROM_STATE_ACTION( RedStateAp *state ); 50 | virtual int EOF_ACTION( RedStateAp *state ); 51 | virtual int TRANS_ACTION( RedTransAp *trans ); 52 | 53 | virtual void writeData(); 54 | virtual void writeExec(); 55 | }; 56 | 57 | /* 58 | * Local Variables: 59 | * mode: c++ 60 | * indent-tabs-mode: 1 61 | * c-file-style: "bsd" 62 | * End: 63 | */ 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /ragel/rubyftable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 2007 Victor Hugo Borja 3 | * Copyright 2001-2007 Adrian Thurston 4 | */ 5 | 6 | /* This file is part of Ragel. 7 | * 8 | * Ragel is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * Ragel is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with Ragel; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 | */ 22 | 23 | #ifndef _RUBY_FTABCODEGEN_H 24 | #define _RUBY_FTABCODEGEN_H 25 | 26 | #include "rubytable.h" 27 | 28 | class RubyFTabCodeGen : public RubyTabCodeGen 29 | { 30 | public: 31 | RubyFTabCodeGen( ostream &out ): RubyTabCodeGen(out) {} 32 | protected: 33 | std::ostream &TO_STATE_ACTION_SWITCH(); 34 | std::ostream &FROM_STATE_ACTION_SWITCH(); 35 | std::ostream &EOF_ACTION_SWITCH(); 36 | std::ostream &ACTION_SWITCH(); 37 | 38 | void GOTO( ostream &out, int gotoDest, bool inFinish ); 39 | void GOTO_EXPR( ostream &out, GenInlineItem *ilItem, bool inFinish ); 40 | void CALL( ostream &out, int callDest, int targState, bool inFinish ); 41 | void CALL_EXPR(ostream &out, GenInlineItem *ilItem, int targState, bool inFinish ); 42 | void RET( ostream &out, bool inFinish ); 43 | void BREAK( ostream &out, int targState ); 44 | 45 | int TO_STATE_ACTION( RedStateAp *state ); 46 | int FROM_STATE_ACTION( RedStateAp *state ); 47 | int EOF_ACTION( RedStateAp *state ); 48 | virtual int TRANS_ACTION( RedTransAp *trans ); 49 | 50 | void writeData(); 51 | void writeExec(); 52 | void calcIndexSize(); 53 | }; 54 | 55 | /* 56 | * Local Variables: 57 | * mode: c++ 58 | * indent-tabs-mode: 1 59 | * c-file-style: "bsd" 60 | * End: 61 | */ 62 | 63 | #endif 64 | 65 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | /Makefile.in 2 | /Makefile 3 | /runtests 4 | /*.c 5 | /*.cpp 6 | /*.cs 7 | /*.m 8 | /*.d 9 | /*.rb 10 | /*.bin 11 | /*.exp 12 | /*.out 13 | /*.java 14 | /*.class 15 | /*.go 16 | /*_c.rl 17 | /*_d.rl 18 | /*_java.rl 19 | /*_ruby.rl 20 | /*_csharp.rl 21 | /*_go.rl 22 | -------------------------------------------------------------------------------- /test/Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2002-2009 Adrian Thurston 3 | # 4 | 5 | # This file is part of Ragel. 6 | # 7 | # Ragel is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Ragel is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Ragel; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | 21 | 22 | TESTS = runtests 23 | 24 | EXTRA_DIST = \ 25 | atoi1.rl clang2.rl cond7.rl element3.rl erract8.rl forder3.rl java1.rl \ 26 | range.rl scan3.rl xml.rl atoi2.rl clang3.rl cppscan1.rl eofact.rl \ 27 | erract9.rl gotocallret1.rl java2.rl recdescent1.rl scan4.rl atoi3.rl \ 28 | clang4.rl cppscan2.rl erract1.rl export1.rl gotocallret2.rl keller1.rl \ 29 | recdescent2.rl stateact1.rl awkemu.rl cond1.rl cppscan3.rl erract2.rl \ 30 | export2.rl high1.rl lmgoto.rl recdescent3.rl statechart1.rl builtin.rl \ 31 | cond2.rl cppscan4.rl erract3.rl export3.rl high2.rl mailbox1.rl \ 32 | repetition.rl strings1.rl call1.rl cond3.rl cppscan5.rl erract4.rl \ 33 | export4.rl high3.rl mailbox2.rl rlscan.rl strings2.rl call2.rl cond4.rl \ 34 | cppscan6.rl erract5.rl fnext1.rl import1.rl mailbox3.rl ruby1.rl \ 35 | tokstart1.rl call3.rl cond5.rl element1.rl erract6.rl forder1.rl \ 36 | include1.rl minimize1.rl scan1.rl union.rl clang1.rl cond6.rl \ 37 | element2.rl erract7.rl forder2.rl include2.rl patact.rl scan2.rl \ 38 | xmlcommon.rl langtrans_c.sh langtrans_csharp.sh langtrans_d.sh \ 39 | langtrans_java.sh langtrans_ruby.sh checkeofact.txl \ 40 | langtrans_csharp.txl langtrans_c.txl langtrans_d.txl langtrans_java.txl \ 41 | langtrans_ruby.txl testcase.txl cppscan1.h eofact.h mailbox1.h strings2.h 42 | 43 | CLEANFILES = \ 44 | *.c *.cpp *.m *.d *.java *.bin *.class *.exp \ 45 | *.out *_c.rl *_d.rl *_java.rl *_ruby.rl *_csharp.rl *.cs \ 46 | *_go.rl *.go *.exe 47 | -------------------------------------------------------------------------------- /test/README: -------------------------------------------------------------------------------- 1 | 2 | The test suite now depends on TXL. Since the trend in Ragel is towards 3 | independence of the host-language, tests are now being written in a fictional 4 | mini-language designed for the purpose of testing ragel. The host language 5 | test-cases are then generated using a TXL transformation. This allows one test 6 | case to be run against all host languages in addition to all code generation 7 | styles. 8 | 9 | TXL is not open source, but a free download is available from the homepage. 10 | 11 | http://www.txl.ca/ 12 | 13 | -Adrian 14 | -------------------------------------------------------------------------------- /test/atoi1.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: indep 3 | */ 4 | bool neg; 5 | int val; 6 | %% 7 | val = 0; 8 | neg = false; 9 | %%{ 10 | machine AtoI; 11 | 12 | action begin { 13 | neg = false; 14 | val = 0; 15 | } 16 | 17 | action see_neg { 18 | neg = true; 19 | } 20 | 21 | action add_digit { 22 | val = val * 10 + (fc - 48); 23 | } 24 | 25 | action finish { 26 | if ( neg ) { 27 | val = -1 * val; 28 | } 29 | } 30 | action print { 31 | printi val; 32 | prints "\n"; 33 | } 34 | 35 | atoi = ( 36 | ('-'@see_neg | '+')? (digit @add_digit)+ 37 | ) >begin %finish; 38 | 39 | main := atoi '\n' @print; 40 | }%% 41 | /* _____INPUT_____ 42 | "1\n" 43 | "12\n" 44 | "222222\n" 45 | "+2123\n" 46 | "213 3213\n" 47 | "-12321\n" 48 | "--123\n" 49 | "-99\n" 50 | " -3000\n" 51 | _____INPUT_____ */ 52 | 53 | /* _____OUTPUT_____ 54 | 1 55 | ACCEPT 56 | 12 57 | ACCEPT 58 | 222222 59 | ACCEPT 60 | 2123 61 | ACCEPT 62 | FAIL 63 | -12321 64 | ACCEPT 65 | FAIL 66 | -99 67 | ACCEPT 68 | FAIL 69 | _____OUTPUT_____ */ 70 | -------------------------------------------------------------------------------- /test/atoi2.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: indep 3 | * This implementes an atoi machine using the statechart paradigm. 4 | */ 5 | bool neg; 6 | int val; 7 | %% 8 | val = 0; 9 | neg = false; 10 | %%{ 11 | machine StateChart; 12 | 13 | action begin { 14 | neg = false; 15 | val = 0; 16 | } 17 | 18 | action see_neg { 19 | neg = true; 20 | } 21 | 22 | action add_digit { 23 | val = val * 10 + (fc - 48); 24 | } 25 | 26 | action finish { 27 | if ( neg ) 28 | val = -1 * val; 29 | } 30 | 31 | atoi = ( 32 | start: ( 33 | '-' @see_neg ->om_num | 34 | '+' ->om_num | 35 | [0-9] @add_digit ->more_nums 36 | ), 37 | 38 | # One or more nums. 39 | om_num: ( 40 | [0-9] @add_digit ->more_nums 41 | ), 42 | 43 | # Zero ore more nums. 44 | more_nums: ( 45 | [0-9] @add_digit ->more_nums | 46 | '' -> final 47 | ) 48 | ) >begin %finish; 49 | 50 | action oneof { printi val; prints "\n"; } 51 | main := ( atoi '\n' @oneof )*; 52 | }%% 53 | /* _____INPUT_____ 54 | "1\n" 55 | "12\n" 56 | "222222\n" 57 | "+2123\n" 58 | "213 3213\n" 59 | "-12321\n" 60 | "--123\n" 61 | "-99\n" 62 | " -3000\n" 63 | _____INPUT_____ */ 64 | 65 | /* _____OUTPUT_____ 66 | 1 67 | ACCEPT 68 | 12 69 | ACCEPT 70 | 222222 71 | ACCEPT 72 | 2123 73 | ACCEPT 74 | FAIL 75 | -12321 76 | ACCEPT 77 | FAIL 78 | -99 79 | ACCEPT 80 | FAIL 81 | _____OUTPUT_____ */ 82 | -------------------------------------------------------------------------------- /test/atoi3.rl: -------------------------------------------------------------------------------- 1 | # 2 | # @LANG: ruby 3 | # 4 | 5 | %%{ 6 | machine atoi3; 7 | action begin { 8 | neg = false; 9 | val = 0; 10 | } 11 | action see_neg { 12 | neg = true; 13 | } 14 | action add_digit { 15 | val = val * 10 + (fc - "0"[0]); 16 | } 17 | action finish { 18 | val = -1 * val if neg 19 | } 20 | action print { 21 | puts val; 22 | } 23 | atoi = (('-' @ see_neg | '+') ? (digit @ add_digit) +) > begin % finish; 24 | main := atoi '\n' @ print; 25 | }%% 26 | 27 | %% write data; 28 | 29 | def run_machine( data ) 30 | p = 0; 31 | pe = data.length 32 | cs = 0 33 | val = 0; 34 | neg = false; 35 | 36 | %% write init; 37 | %% write exec; 38 | if cs >= atoi3_first_final 39 | puts "ACCEPT" 40 | else 41 | puts "FAIL" 42 | end 43 | end 44 | 45 | inp = [ 46 | "1\n", 47 | "12\n", 48 | "222222\n", 49 | "+2123\n", 50 | "213 3213\n", 51 | "-12321\n", 52 | "--123\n", 53 | "-99\n", 54 | " -3000\n", 55 | ] 56 | 57 | inp.each { |str| run_machine(str) } 58 | 59 | =begin _____OUTPUT_____ 60 | 1 61 | ACCEPT 62 | 12 63 | ACCEPT 64 | 222222 65 | ACCEPT 66 | 2123 67 | ACCEPT 68 | FAIL 69 | -12321 70 | ACCEPT 71 | FAIL 72 | -99 73 | ACCEPT 74 | FAIL 75 | =end _____OUTPUT_____ 76 | -------------------------------------------------------------------------------- /test/call1.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | int num = 0; 9 | 10 | struct test 11 | { 12 | int cs, top, stack[32]; 13 | }; 14 | 15 | %%{ 16 | machine test; 17 | access fsm->; 18 | 19 | action check_num { 20 | if ( num & 1 ) 21 | fcall *fentry(odd); 22 | else 23 | fcall even; 24 | } 25 | 26 | # Test call and return functionality. 27 | even := 'even' any @{fhold; fret;}; 28 | odd := 'odd' any @{fhold; fret;}; 29 | num = [0-9]+ ${ num = num * 10 + (fc - '0'); }; 30 | even_odd = num ' ' @check_num "\n"; 31 | 32 | # Test calls in out actions. 33 | fail := !(any*); 34 | out_acts = 'OA ok\n' | 35 | 'OA error1\n' | 36 | 'OA error2\n'; 37 | 38 | main := even_odd | out_acts; 39 | }%% 40 | 41 | %% write data; 42 | 43 | void test_init( struct test *fsm ) 44 | { 45 | num = 0; 46 | %% write init; 47 | } 48 | 49 | void test_execute( struct test *fsm, const char *data, int len ) 50 | { 51 | const char *p = data; 52 | const char *pe = data+len; 53 | 54 | %% write exec; 55 | } 56 | 57 | int test_finish( struct test *fsm ) 58 | { 59 | if ( fsm->cs == test_error ) 60 | return -1; 61 | if ( fsm->cs >= test_first_final ) 62 | return 1; 63 | return 0; 64 | } 65 | 66 | #define BUFSIZE 1024 67 | 68 | void test( char *buf ) 69 | { 70 | struct test test; 71 | test_init( &test ); 72 | test_execute( &test, buf, strlen(buf) ); 73 | if ( test_finish( &test ) > 0 ) 74 | printf( "ACCEPT\n" ); 75 | else 76 | printf( "FAIL\n" ); 77 | } 78 | 79 | int main() 80 | { 81 | test( "78 even\n" ); 82 | test( "89 odd\n" ); 83 | test( "1 even\n" ); 84 | test( "0 odd\n" ); 85 | test( "OA ok\n" ); 86 | test( "OA error1\n" ); 87 | test( "OA error2\n" ); 88 | 89 | return 0; 90 | } 91 | 92 | 93 | #ifdef _____OUTPUT_____ 94 | ACCEPT 95 | ACCEPT 96 | FAIL 97 | FAIL 98 | ACCEPT 99 | ACCEPT 100 | ACCEPT 101 | #endif 102 | -------------------------------------------------------------------------------- /test/checkeofact.txl: -------------------------------------------------------------------------------- 1 | include "testcase.txl" 2 | 3 | define program 4 | [lang_indep] 5 | | 'yes 6 | | 'no 7 | end define 8 | 9 | rule findEof1 10 | match [machine_expr_item] 11 | '>/ 12 | end rule 13 | 14 | rule findEof2 15 | match [machine_expr_item] 16 | '/ 37 | end rule 38 | 39 | rule findEof7 40 | match [repeat machine_expr_item] 41 | '> 'eof _ [repeat machine_expr_item] 42 | end rule 43 | 44 | rule findEof8 45 | match [repeat machine_expr_item] 46 | '< 'eof _ [repeat machine_expr_item] 47 | end rule 48 | 49 | rule findEof9 50 | match [repeat machine_expr_item] 51 | '$ 'eof _ [repeat machine_expr_item] 52 | end rule 53 | 54 | rule findEof10 55 | match [repeat machine_expr_item] 56 | '% 'eof _ [repeat machine_expr_item] 57 | end rule 58 | 59 | rule findEof11 60 | match [repeat machine_expr_item] 61 | '@ 'eof _ [repeat machine_expr_item] 62 | end rule 63 | 64 | rule findEof12 65 | match [repeat machine_expr_item] 66 | '<> 'eof _ [repeat machine_expr_item] 67 | end rule 68 | 69 | rule findScanner 70 | match [machine_expr_item] 71 | '|* _ [repeat scanner_item] '*| 72 | end rule 73 | 74 | function findEof P [program] 75 | replace [program] 76 | _ [program] 77 | where 78 | P 79 | [findEof1] [findEof2] [findEof3] 80 | [findEof4] [findEof5] [findEof6] 81 | [findEof7] [findEof8] [findEof9] 82 | [findEof10] [findEof11] [findEof12] 83 | [findScanner] 84 | by 85 | 'yes 86 | end function 87 | 88 | function main 89 | replace [program] 90 | P [program] 91 | construct NewP [program] 92 | 'no 93 | by 94 | NewP [findEof P] 95 | end function 96 | -------------------------------------------------------------------------------- /test/cond1.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: indep 3 | * @ALLOW_GENFLAGS: -T0 -T1 -G0 -G1 -G2 4 | */ 5 | bool i; 6 | bool j; 7 | bool k; 8 | %% 9 | 10 | %%{ 11 | machine foo; 12 | 13 | action c1 {i} 14 | action c2 {j} 15 | action c3 {k} 16 | action one { prints " one\n";} 17 | action two { prints " two\n";} 18 | action three { prints " three\n";} 19 | 20 | action seti { if ( fc == 48 ) i = false; else i = true; } 21 | action setj { if ( fc == 48 ) j = false; else j = true; } 22 | action setk { if ( fc == 48 ) k = false; else k = true; } 23 | 24 | action break {fbreak;} 25 | 26 | one = 'a' 'b' when c1 'c' @one; 27 | two = 'a'* 'b' when c2 'c' @two; 28 | three = 'a'+ 'b' when c3 'c' @three; 29 | 30 | main := 31 | [01] @seti 32 | [01] @setj 33 | [01] @setk 34 | ( one | two | three ) '\n' @break; 35 | 36 | }%% 37 | 38 | /* _____INPUT_____ 39 | "000abc\n" 40 | "100abc\n" 41 | "010abc\n" 42 | "110abc\n" 43 | "001abc\n" 44 | "101abc\n" 45 | "011abc\n" 46 | "111abc\n" 47 | _____INPUT_____ */ 48 | /* _____OUTPUT_____ 49 | FAIL 50 | one 51 | ACCEPT 52 | two 53 | ACCEPT 54 | one 55 | two 56 | ACCEPT 57 | three 58 | ACCEPT 59 | one 60 | three 61 | ACCEPT 62 | two 63 | three 64 | ACCEPT 65 | one 66 | two 67 | three 68 | ACCEPT 69 | _____OUTPUT_____ */ 70 | -------------------------------------------------------------------------------- /test/cond2.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c++ 3 | */ 4 | 5 | #include 6 | #include 7 | using std::cout; 8 | using std::endl; 9 | 10 | %%{ 11 | machine foo; 12 | 13 | action c1 {i} 14 | action c2 {j} 15 | 16 | action one { cout << " one" << endl;} 17 | action two { cout << " two" << endl;} 18 | 19 | main := ( 20 | [a-z] | 21 | ('\n' when c1 @one) 22 | )* 23 | ('\n' when c2 @two); 24 | }%% 25 | 26 | %% write data noerror; 27 | 28 | void test( int i, int j, const char *str ) 29 | { 30 | int cs = foo_start; 31 | const char *p = str; 32 | const char *pe = str + strlen( str ); 33 | 34 | cout << "run:" << endl; 35 | %% write exec; 36 | if ( cs >= foo_first_final ) 37 | cout << " success" << endl; 38 | else 39 | cout << " failure" << endl; 40 | cout << endl; 41 | } 42 | 43 | int main() 44 | { 45 | test( 0, 0, "hi\n\n" ); 46 | test( 1, 0, "hi\n\n" ); 47 | test( 0, 1, "hi\n" ); 48 | test( 0, 1, "hi\n\n" ); 49 | test( 1, 1, "hi\n" ); 50 | test( 1, 1, "hi\n\n" ); 51 | test( 1, 1, "hi\n\nx" ); 52 | return 0; 53 | } 54 | 55 | #ifdef _____OUTPUT_____ 56 | run: 57 | failure 58 | 59 | run: 60 | one 61 | one 62 | failure 63 | 64 | run: 65 | two 66 | success 67 | 68 | run: 69 | two 70 | failure 71 | 72 | run: 73 | one 74 | two 75 | success 76 | 77 | run: 78 | one 79 | two 80 | one 81 | two 82 | success 83 | 84 | run: 85 | one 86 | two 87 | one 88 | two 89 | failure 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /test/cond3.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c++ 3 | */ 4 | 5 | #include 6 | #include 7 | using std::cout; 8 | using std::endl; 9 | 10 | %%{ 11 | machine foo; 12 | 13 | action hit_5 {c == 5} 14 | action done { cout << " done" << endl; } 15 | action inc {c++;} 16 | 17 | # The any* includes '\n' when hit_5 is true, so use guarded concatenation. 18 | main := (any @inc)* :> '\n' when hit_5 @done; 19 | }%% 20 | 21 | %% write data noerror; 22 | 23 | void test( const char *str ) 24 | { 25 | int cs = foo_start; 26 | int c = 0; 27 | const char *p = str; 28 | const char *pe = str + strlen( str ); 29 | 30 | cout << "run:" << endl; 31 | %% write exec; 32 | if ( cs >= foo_first_final ) 33 | cout << " success" << endl; 34 | else 35 | cout << " failure" << endl; 36 | cout << endl; 37 | } 38 | 39 | int main() 40 | { 41 | test( "12345\n" ); // success 42 | test( "\n2345\n" ); // success, first newline ignored 43 | test( "1234\n" ); // failure, didn't get 5 chars before newline. 44 | return 0; 45 | } 46 | 47 | #ifdef _____OUTPUT_____ 48 | run: 49 | done 50 | success 51 | 52 | run: 53 | done 54 | success 55 | 56 | run: 57 | failure 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /test/cond4.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c++ 3 | */ 4 | 5 | #include 6 | #include 7 | using std::cout; 8 | using std::endl; 9 | 10 | %%{ 11 | machine foo; 12 | 13 | action c1 {(cout << "c1 ", true)} 14 | action c2 {(cout << "c2 ", true)} 15 | action c3 {(cout << "c3 ", true)} 16 | action c4 {(cout << "c4 ", true)} 17 | 18 | main := ( 19 | 10 .. 60 when c1 | 20 | 20 .. 40 when c2 | 21 | 30 .. 50 when c3 | 22 | 32 .. 38 when c4 | 23 | 0 .. 70 )* ${cout << "char: " << (int)*p << endl;}; 24 | }%% 25 | 26 | %% write data noerror nofinal; 27 | 28 | void test( char *str ) 29 | { 30 | int len = strlen( str ); 31 | int cs = foo_start; 32 | char *p = str, *pe = str+len; 33 | %% write exec; 34 | } 35 | 36 | char data[] = { 5, 15, 25, 31, 35, 39, 45, 55, 65, 0 }; 37 | 38 | int main() 39 | { 40 | test( data ); 41 | return 0; 42 | } 43 | 44 | #ifdef _____OUTPUT_____ 45 | char: 5 46 | c1 char: 15 47 | c1 c2 char: 25 48 | c1 c2 c3 char: 31 49 | c1 c2 c3 c4 char: 35 50 | c1 c2 c3 char: 39 51 | c1 c3 char: 45 52 | c1 char: 55 53 | char: 65 54 | #endif 55 | -------------------------------------------------------------------------------- /test/cond5.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c++ 3 | */ 4 | 5 | #include 6 | #include 7 | using std::cout; 8 | using std::endl; 9 | 10 | %%{ 11 | machine foo; 12 | write data noerror; 13 | }%% 14 | 15 | void test( const char *str ) 16 | { 17 | int cs = foo_start; 18 | int c = 0; 19 | const char *p = str; 20 | const char *pe = str + strlen( str ); 21 | char last = '0'; 22 | 23 | cout << "run:"; 24 | %%{ 25 | action d1 { cout << " d1"; } 26 | action see_five { cout << " see_five"; } 27 | 28 | see_five = ([0-9] when{c++ < 5} @d1)* '\n' @see_five; 29 | 30 | action in_sequence { cout << " in_sequence"; } 31 | action d2 { last = *p; cout << " d2"; } 32 | in_sequence = ( [0-9] when { *p == last+1 } @d2 )* '\n' @in_sequence; 33 | 34 | main := ( see_five | in_sequence ) ${cout << " |";}; 35 | 36 | write exec; 37 | }%% 38 | if ( cs < foo_first_final ) 39 | cout << " failure"; 40 | cout << endl; 41 | } 42 | 43 | int main() 44 | { 45 | test( "123456789012\n" ); // fails both 46 | test( "123456789\n" ); // fails five 47 | test( "1234\n" ); // fails five 48 | test( "13245\n" ); // fails sequence 49 | test( "12345\n" ); // succeeds in both 50 | return 0; 51 | } 52 | 53 | #ifdef _____OUTPUT_____ 54 | run: d1 d2 | d1 d2 | d1 d2 | d1 d2 | d1 d2 | d2 | d2 | d2 | d2 | failure 55 | run: d1 d2 | d1 d2 | d1 d2 | d1 d2 | d1 d2 | d2 | d2 | d2 | d2 | in_sequence | 56 | run: d1 d2 | d1 d2 | d1 d2 | d1 d2 | see_five in_sequence | 57 | run: d1 d2 | d1 | d1 | d1 | d1 | see_five | 58 | run: d1 d2 | d1 d2 | d1 d2 | d1 d2 | d1 d2 | see_five in_sequence | 59 | #endif 60 | -------------------------------------------------------------------------------- /test/cond6.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c++ 3 | */ 4 | 5 | /* Balanced parenthesis with conditions. */ 6 | 7 | #include 8 | #include 9 | using std::cout; 10 | using std::endl; 11 | 12 | %%{ 13 | machine cond; 14 | write data noerror; 15 | }%% 16 | 17 | void test( const char *str ) 18 | { 19 | int cs = cond_start, n = 0; 20 | const char *p = str; 21 | const char *pe = str + strlen( str ); 22 | 23 | %%{ 24 | comment = '(' @{n=0;} 25 | ( '('@{n++;} | ')'@{n--;} | [^()] )* 26 | :> ')' when{!n}; 27 | 28 | main := ' '* comment ' '* '\n' @{cout << "success";}; 29 | 30 | write exec; 31 | }%% 32 | if ( cs < cond_first_final ) 33 | cout << "failure"; 34 | cout << endl; 35 | } 36 | 37 | int main() 38 | { 39 | test( "( ( )\n" ); 40 | test( "()()\n" ); 41 | test( "(((\n" ); 42 | test( "((()\n" ); 43 | test( "((())\n" ); 44 | test( "()\n" ); 45 | test( "((()))\n" ); 46 | test( "(()())\n" ); 47 | test( "((())()(((()))))\n" ); 48 | return 0; 49 | } 50 | 51 | #ifdef _____OUTPUT_____ 52 | failure 53 | failure 54 | failure 55 | failure 56 | failure 57 | success 58 | success 59 | success 60 | success 61 | #endif 62 | -------------------------------------------------------------------------------- /test/cond7.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: indep 3 | */ 4 | int i; 5 | int c; 6 | %% 7 | 8 | %%{ 9 | machine foo; 10 | 11 | action testi {i > 0} 12 | action inc { 13 | i = i - 1; 14 | c = (fc); 15 | prints "item: "; 16 | printi c; 17 | prints "\n"; 18 | } 19 | 20 | count = [0-9] @{ 21 | i = (fc - '0'); 22 | prints "count: "; 23 | printi i; 24 | prints "\n"; 25 | }; 26 | 27 | sub = 28 | count # record the number of digits 29 | ( digit when testi @inc )* outwhen !testi; 30 | 31 | main := sub sub '\n'; 32 | }%% 33 | 34 | /* _____INPUT_____ 35 | "00\n" 36 | "019\n" 37 | "190\n" 38 | "1719\n" 39 | "1040000\n" 40 | "104000a\n" 41 | "104000\n" 42 | _____INPUT_____ */ 43 | /* _____OUTPUT_____ 44 | count: 0 45 | count: 0 46 | ACCEPT 47 | count: 0 48 | count: 1 49 | item: 57 50 | ACCEPT 51 | count: 1 52 | item: 57 53 | count: 0 54 | ACCEPT 55 | count: 1 56 | item: 55 57 | count: 1 58 | item: 57 59 | ACCEPT 60 | count: 1 61 | item: 48 62 | count: 4 63 | item: 48 64 | item: 48 65 | item: 48 66 | item: 48 67 | ACCEPT 68 | count: 1 69 | item: 48 70 | count: 4 71 | item: 48 72 | item: 48 73 | item: 48 74 | FAIL 75 | count: 1 76 | item: 48 77 | count: 4 78 | item: 48 79 | item: 48 80 | item: 48 81 | FAIL 82 | _____OUTPUT_____ */ 83 | -------------------------------------------------------------------------------- /test/element1.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c++ 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | struct LangEl 9 | { 10 | int key; 11 | const char *name; 12 | }; 13 | 14 | struct Fsm 15 | { 16 | int cs; 17 | 18 | // Initialize the machine. Invokes any init statement blocks. Returns 0 19 | // if the machine begins in a non-accepting state and 1 if the machine 20 | // begins in an accepting state. 21 | int init( ); 22 | 23 | // Execute the machine on a block of data. Returns -1 if after processing 24 | // the data, the machine is in the error state and can never accept, 0 if 25 | // the machine is in a non-accepting state and 1 if the machine is in an 26 | // accepting state. 27 | int execute( LangEl *data, int len ); 28 | 29 | // Indicate that there is no more data. Returns -1 if the machine finishes 30 | // in the error state and does not accept, 0 if the machine finishes 31 | // in any other non-accepting state and 1 if the machine finishes in an 32 | // accepting state. 33 | int finish( ); 34 | 35 | }; 36 | 37 | %%{ 38 | machine Fsm; 39 | 40 | alphtype int; 41 | getkey fpc->key; 42 | variable eof eof_marker; 43 | 44 | action a1 {} 45 | action a2 {} 46 | action a3 {} 47 | 48 | main := ( 1 2* 3 ) 49 | ${cout << fpc->name << endl;} 50 | %/{cout << "accept" << endl;}; 51 | }%% 52 | 53 | %% write data; 54 | 55 | int Fsm::init( ) 56 | { 57 | %% write init; 58 | return 0; 59 | } 60 | 61 | int Fsm::execute( LangEl *data, int len ) 62 | { 63 | LangEl *p = data; 64 | LangEl *pe = data + len; 65 | LangEl *eof_marker = pe; 66 | %% write exec; 67 | 68 | if ( cs == Fsm_error ) 69 | return -1; 70 | if ( cs >= Fsm_first_final ) 71 | return 1; 72 | return 0; 73 | } 74 | 75 | int Fsm::finish( ) 76 | { 77 | if ( cs == Fsm_error ) 78 | return -1; 79 | if ( cs >= Fsm_first_final ) 80 | return 1; 81 | return 0; 82 | } 83 | 84 | int main( ) 85 | { 86 | static Fsm fsm; 87 | static LangEl lel[] = { 88 | {1, "one"}, 89 | {2, "two-a"}, 90 | {2, "two-b"}, 91 | {2, "two-c"}, 92 | {3, "three"} 93 | }; 94 | 95 | fsm.init(); 96 | fsm.execute( lel, 5 ); 97 | fsm.finish(); 98 | return 0; 99 | } 100 | 101 | #ifdef _____OUTPUT_____ 102 | one 103 | two-a 104 | two-b 105 | two-c 106 | three 107 | accept 108 | #endif 109 | -------------------------------------------------------------------------------- /test/element2.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | */ 4 | 5 | #include 6 | 7 | struct LangEl 8 | { 9 | int key; 10 | char *name; 11 | }; 12 | 13 | struct fsm 14 | { 15 | int cs; 16 | }; 17 | 18 | %%{ 19 | machine fsm; 20 | alphtype int; 21 | getkey fpc->key; 22 | variable cs fsm->cs; 23 | 24 | action a1 {} 25 | action a2 {} 26 | action a3 {} 27 | 28 | main := ( 1 2* 3 ) 29 | ${printf("%s\n", fpc->name);} 30 | %/{printf("accept\n");}; 31 | }%% 32 | 33 | %% write data; 34 | 35 | void fsm_init( struct fsm *fsm ) 36 | { 37 | %% write init; 38 | } 39 | 40 | void fsm_execute( struct fsm *fsm, struct LangEl *_data, int _len ) 41 | { 42 | struct LangEl *p = _data; 43 | struct LangEl *pe = _data+_len; 44 | struct LangEl *eof = pe; 45 | 46 | %% write exec; 47 | } 48 | 49 | int fsm_finish( struct fsm *fsm ) 50 | { 51 | if ( fsm->cs == fsm_error ) 52 | return -1; 53 | if ( fsm->cs >= fsm_first_final ) 54 | return 1; 55 | return 0; 56 | } 57 | 58 | int main() 59 | { 60 | static struct fsm fsm; 61 | static struct LangEl lel[] = { 62 | {1, "one"}, 63 | {2, "two-a"}, 64 | {2, "two-b"}, 65 | {2, "two-c"}, 66 | {3, "three"} 67 | }; 68 | 69 | fsm_init( &fsm ); 70 | fsm_execute( &fsm, lel, 5 ); 71 | fsm_finish( &fsm ); 72 | 73 | return 0; 74 | } 75 | 76 | #ifdef _____OUTPUT_____ 77 | one 78 | two-a 79 | two-b 80 | two-c 81 | three 82 | accept 83 | #endif 84 | -------------------------------------------------------------------------------- /test/eofact.h: -------------------------------------------------------------------------------- 1 | #ifndef _EOFACT_H 2 | #define _EOFACT_H 3 | 4 | struct eofact 5 | { 6 | int cs; 7 | }; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /test/eofact.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: indep 3 | * 4 | * Test works with split code gen. 5 | */ 6 | %% 7 | %%{ 8 | machine eofact; 9 | 10 | action a1 { prints "a1\n"; } 11 | action a2 { prints "a2\n"; } 12 | action a3 { prints "a3\n"; } 13 | action a4 { prints "a4\n"; } 14 | 15 | 16 | main := ( 17 | 'hello' @eof a1 %eof a2 '\n'? | 18 | 'there' @eof a3 %eof a4 19 | ); 20 | 21 | }%% 22 | /* _____INPUT_____ 23 | "" 24 | "h" 25 | "hell" 26 | "hello" 27 | "hello\n" 28 | "t" 29 | "ther" 30 | "there" 31 | "friend" 32 | _____INPUT_____ */ 33 | /* _____OUTPUT_____ 34 | a1 35 | a3 36 | FAIL 37 | a1 38 | FAIL 39 | a1 40 | FAIL 41 | a2 42 | ACCEPT 43 | ACCEPT 44 | a3 45 | FAIL 46 | a3 47 | FAIL 48 | a4 49 | ACCEPT 50 | FAIL 51 | _____OUTPUT_____ */ 52 | -------------------------------------------------------------------------------- /test/erract2.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: indep 3 | * 4 | * Test error actions. 5 | */ 6 | %% 7 | %%{ 8 | machine ErrAct; 9 | 10 | action err_start { prints "err_start\n"; } 11 | action err_all { prints "err_all\n"; } 12 | action err_middle { prints "err_middle\n"; } 13 | action err_out { prints "err_out\n"; } 14 | 15 | action eof_start { prints "eof_start\n"; } 16 | action eof_all { prints "eof_all\n"; } 17 | action eof_middle { prints "eof_middle\n"; } 18 | action eof_out { prints "eof_out\n"; } 19 | 20 | main := ( 'hello' 21 | >err err_start $err err_all <>err err_middle %err err_out 22 | >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out 23 | ) '\n'; 24 | }%% 25 | 26 | /* _____INPUT_____ 27 | "" 28 | "h" 29 | "x" 30 | "he" 31 | "hx" 32 | "hel" 33 | "hex" 34 | "hell" 35 | "helx" 36 | "hello" 37 | "hellx" 38 | "hello\n" 39 | "hellox" 40 | _____INPUT_____ */ 41 | 42 | /* _____OUTPUT_____ 43 | err_start 44 | eof_start 45 | err_all 46 | eof_all 47 | FAIL 48 | err_all 49 | err_middle 50 | eof_all 51 | eof_middle 52 | FAIL 53 | err_start 54 | err_all 55 | FAIL 56 | err_all 57 | err_middle 58 | eof_all 59 | eof_middle 60 | FAIL 61 | err_all 62 | err_middle 63 | FAIL 64 | err_all 65 | err_middle 66 | eof_all 67 | eof_middle 68 | FAIL 69 | err_all 70 | err_middle 71 | FAIL 72 | err_all 73 | err_middle 74 | eof_all 75 | eof_middle 76 | FAIL 77 | err_all 78 | err_middle 79 | FAIL 80 | err_all 81 | err_out 82 | eof_all 83 | eof_out 84 | FAIL 85 | err_all 86 | err_middle 87 | FAIL 88 | ACCEPT 89 | err_all 90 | err_out 91 | FAIL 92 | _____OUTPUT_____ */ 93 | -------------------------------------------------------------------------------- /test/erract3.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | */ 4 | 5 | #include 6 | #define IDENT_BUFLEN 256 7 | 8 | struct erract 9 | { 10 | int cs; 11 | }; 12 | 13 | %%{ 14 | machine erract; 15 | variable cs fsm->cs; 16 | 17 | # The data that is to go into the fsm structure. 18 | action hello_fails { printf("hello fails\n");} 19 | 20 | newline = ( any | '\n' @{printf("newline\n");} )*; 21 | hello = 'hello\n'* $lerr hello_fails @eof hello_fails; 22 | main := newline | hello; 23 | }%% 24 | 25 | %% write data; 26 | 27 | void erract_init( struct erract *fsm ) 28 | { 29 | %% write init; 30 | } 31 | 32 | void erract_execute( struct erract *fsm, const char *_data, int _len ) 33 | { 34 | const char *p = _data; 35 | const char *pe = _data+_len; 36 | const char *eof = pe; 37 | %% write exec; 38 | } 39 | 40 | int erract_finish( struct erract *fsm ) 41 | { 42 | if ( fsm->cs == erract_error ) 43 | return -1; 44 | else if ( fsm->cs >= erract_first_final ) 45 | return 1; 46 | return 0; 47 | } 48 | 49 | #include 50 | #include 51 | 52 | struct erract fsm; 53 | 54 | void test( char *buf ) 55 | { 56 | int len = strlen(buf); 57 | erract_init( &fsm ); 58 | erract_execute( &fsm, buf, len ); 59 | if ( erract_finish( &fsm ) > 0 ) 60 | printf("ACCEPT\n"); 61 | else 62 | printf("FAIL\n"); 63 | } 64 | 65 | int main() 66 | { 67 | test( 68 | "hello\n" 69 | "hello\n" 70 | "hello\n" 71 | ); 72 | 73 | test( 74 | "hello\n" 75 | "hello\n" 76 | "hello there\n" 77 | ); 78 | 79 | test( 80 | "hello\n" 81 | "hello\n" 82 | "he" ); 83 | 84 | test( "" ); 85 | 86 | return 0; 87 | } 88 | 89 | #ifdef _____OUTPUT_____ 90 | newline 91 | newline 92 | newline 93 | ACCEPT 94 | newline 95 | newline 96 | hello fails 97 | newline 98 | ACCEPT 99 | newline 100 | newline 101 | hello fails 102 | ACCEPT 103 | ACCEPT 104 | #endif 105 | -------------------------------------------------------------------------------- /test/erract6.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | */ 4 | 5 | /* 6 | * Test of a transition going to the error state. 7 | */ 8 | 9 | #include 10 | #define BUFSIZE 2048 11 | 12 | struct errintrans 13 | { 14 | int cs; 15 | }; 16 | 17 | %%{ 18 | machine errintrans; 19 | variable cs fsm->cs; 20 | 21 | char = any - (digit | '\n'); 22 | line = char* "\n"; 23 | main := line+; 24 | }%% 25 | 26 | %% write data; 27 | 28 | void errintrans_init( struct errintrans *fsm ) 29 | { 30 | %% write init; 31 | } 32 | 33 | void errintrans_execute( struct errintrans *fsm, const char *_data, int _len ) 34 | { 35 | const char *p = _data; 36 | const char *pe = _data+_len; 37 | 38 | %% write exec; 39 | } 40 | 41 | int errintrans_finish( struct errintrans *fsm ) 42 | { 43 | if ( fsm->cs == errintrans_error ) 44 | return -1; 45 | if ( fsm->cs >= errintrans_first_final ) 46 | return 1; 47 | return 0; 48 | } 49 | 50 | 51 | struct errintrans fsm; 52 | #include 53 | 54 | void test( char *buf ) 55 | { 56 | int len = strlen( buf ); 57 | errintrans_init( &fsm ); 58 | errintrans_execute( &fsm, buf, len ); 59 | if ( errintrans_finish( &fsm ) > 0 ) 60 | printf("ACCEPT\n"); 61 | else 62 | printf("FAIL\n"); 63 | } 64 | 65 | 66 | int main() 67 | { 68 | test( 69 | "good, does not have numbers\n" 70 | ); 71 | 72 | test( 73 | "bad, has numbers 666\n" 74 | ); 75 | 76 | return 0; 77 | } 78 | 79 | #ifdef _____OUTPUT_____ 80 | ACCEPT 81 | FAIL 82 | #endif 83 | -------------------------------------------------------------------------------- /test/erract7.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | %%{ 9 | machine foo; 10 | 11 | action on_char { printf("char: %c\n", *p); } 12 | action on_err { printf("err: %c\n", *p); } 13 | action to_state { printf("to state: %c\n", *p); } 14 | 15 | main := 'heXXX' $on_char $err(on_err) $to(to_state); 16 | }%% 17 | 18 | %% write data; 19 | 20 | int main() 21 | { 22 | int cs; 23 | char *p = "hello", *pe = p + strlen(p); 24 | char *eof = pe; 25 | %%{ 26 | write init; 27 | write exec; 28 | }%% 29 | 30 | printf( "rest: %s\n", p ); 31 | 32 | return 0; 33 | } 34 | 35 | #ifdef _____OUTPUT_____ 36 | char: h 37 | to state: h 38 | char: e 39 | to state: e 40 | err: l 41 | rest: llo 42 | #endif 43 | -------------------------------------------------------------------------------- /test/erract8.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: java 3 | */ 4 | 5 | class erract8 6 | { 7 | %%{ 8 | machine erract8; 9 | 10 | action on_char { System.out.println("char: " + data[p]); } 11 | action on_err { System.out.println("err: " + data[p]); } 12 | action to_state { System.out.println("to state: " + data[p]); } 13 | 14 | main := 'heXXX' $on_char $err(on_err) $to(to_state); 15 | }%% 16 | 17 | %% write data; 18 | 19 | static void test( char data[] ) 20 | { 21 | int cs, p = 0, pe = data.length; 22 | int eof = pe; 23 | int top; 24 | 25 | %% write init; 26 | %% write exec; 27 | 28 | System.out.println("rest: " + data[p] + data[p+1] + data[p+2]); 29 | } 30 | 31 | public static void main( String args[] ) 32 | { 33 | test( "hello".toCharArray() ); 34 | } 35 | } 36 | 37 | /* _____OUTPUT_____ 38 | char: h 39 | to state: h 40 | char: e 41 | to state: e 42 | err: l 43 | rest: llo 44 | */ 45 | -------------------------------------------------------------------------------- /test/erract9.rl: -------------------------------------------------------------------------------- 1 | # 2 | # @LANG: ruby 3 | # 4 | # Test the host language scanning for ruby. 5 | # 6 | 7 | %%{ 8 | machine erract9; 9 | 10 | action on_char { print("char: ", data[p..p], "\n"); } 11 | action on_err { print("err: ", data[p..p], "\n"); } 12 | action to_state { print("to state: " , data[p..p], "\n"); } 13 | 14 | main := 'heXXX' $on_char $err(on_err) $to(to_state); 15 | }%% 16 | 17 | %% write data; 18 | 19 | def run_machine( data ) 20 | p = 0; 21 | pe = data.length 22 | cs = 0 23 | 24 | %% write init; 25 | %% write exec; 26 | 27 | print("rest: " , data[p..p+2], "\n") 28 | end 29 | 30 | inp = [ 31 | "hello\n", 32 | ] 33 | 34 | inp.each { |str| run_machine(str) } 35 | 36 | =begin _____OUTPUT_____ 37 | char: h 38 | to state: h 39 | char: e 40 | to state: e 41 | err: l 42 | rest: llo 43 | =end _____OUTPUT_____ 44 | -------------------------------------------------------------------------------- /test/export1.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | %%{ 9 | machine test; 10 | 11 | export c1 = 'c'; 12 | export c2 = 'z'; 13 | export c3 = 't'; 14 | 15 | commands := ( 16 | c1 . digit* '\n' @{ printf( "c1\n" );} | 17 | c2 . alpha* '\n' @{ printf( "c2\n" );}| 18 | c3 . '.'* '\n' @{ printf( "c3\n" );} 19 | )*; 20 | 21 | some_other := any*; 22 | }%% 23 | 24 | %% write exports; 25 | %% write data; 26 | 27 | int test( const char *data, int len ) 28 | { 29 | int cs = test_en_commands; 30 | const char *p = data, *pe = data + len; 31 | 32 | %% write init nocs; 33 | %% write exec; 34 | 35 | if ( cs >= test_first_final ) 36 | printf("ACCEPT\n"); 37 | else 38 | printf("ERROR\n"); 39 | return 0; 40 | } 41 | 42 | char data[] = { 43 | test_ex_c1, '1', '2', '\n', 44 | test_ex_c2, 'a', 'b', '\n', 45 | test_ex_c3, '.', '.', '\n', 0 46 | }; 47 | 48 | int main() 49 | { 50 | test( data, strlen( data ) ); 51 | return 0; 52 | } 53 | 54 | #ifdef _____OUTPUT_____ 55 | c1 56 | c2 57 | c3 58 | ACCEPT 59 | #endif 60 | -------------------------------------------------------------------------------- /test/export2.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: java 3 | */ 4 | 5 | class export2 6 | { 7 | %%{ 8 | machine test; 9 | 10 | export c1 = 'c'; 11 | export c2 = 'z'; 12 | export c3 = 't'; 13 | 14 | commands := ( 15 | c1 . digit* '\n' @{ System.out.println( "c1" );} | 16 | c2 . alpha* '\n' @{ System.out.println( "c2" );}| 17 | c3 . '.'* '\n' @{ System.out.println( "c3" );} 18 | )*; 19 | 20 | other := any*; 21 | }%% 22 | 23 | %% write exports; 24 | %% write data; 25 | 26 | static void test( char data[] ) 27 | { 28 | int cs = test_en_commands, p = 0, pe = data.length; 29 | int top; 30 | 31 | %% write init nocs; 32 | %% write exec; 33 | 34 | if ( cs >= test_first_final ) 35 | System.out.println( "ACCEPT" ); 36 | else 37 | System.out.println( "FAIL" ); 38 | } 39 | 40 | public static void main( String args[] ) 41 | { 42 | char data[] = { 43 | test_ex_c1, '1', '2', '\n', 44 | test_ex_c2, 'a', 'b', '\n', 45 | test_ex_c3, '.', '.', '\n', 46 | }; 47 | test( data ); 48 | } 49 | } 50 | 51 | 52 | /* _____OUTPUT_____ 53 | c1 54 | c2 55 | c3 56 | ACCEPT 57 | */ 58 | -------------------------------------------------------------------------------- /test/export3.rl: -------------------------------------------------------------------------------- 1 | # 2 | # @LANG: ruby 3 | # 4 | 5 | %%{ 6 | machine test; 7 | 8 | export c1 = 'c'; 9 | export c2 = 'z'; 10 | export c3 = 't'; 11 | 12 | commands := ( 13 | c1 . digit* '\n' @{ puts "c1"; } | 14 | c2 . alpha* '\n' @{ puts "c2"; }| 15 | c3 . '.'* '\n' @{ puts "c3"; } 16 | )*; 17 | 18 | other := any*; 19 | }%% 20 | 21 | %% write exports; 22 | %% write data; 23 | 24 | def run_machine( data ) 25 | p = 0; 26 | pe = data.length 27 | cs = test_en_commands 28 | val = 0; 29 | neg = false; 30 | 31 | %% write init nocs; 32 | %% write exec; 33 | if cs >= test_first_final 34 | puts "ACCEPT" 35 | else 36 | puts "FAIL" 37 | end 38 | end 39 | 40 | inp = [ 41 | test_ex_c1, ?1, ?2, ?\n, 42 | test_ex_c2, ?a, ?b, ?\n, 43 | test_ex_c3, ?., ?., ?\n 44 | ] 45 | 46 | run_machine( inp ); 47 | 48 | =begin _____OUTPUT_____ 49 | c1 50 | c2 51 | c3 52 | ACCEPT 53 | =end _____OUTPUT_____ 54 | -------------------------------------------------------------------------------- /test/export4.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: d 3 | */ 4 | 5 | import std.c.stdio; 6 | import std.string; 7 | 8 | %%{ 9 | machine test; 10 | 11 | export c1 = 'c'; 12 | export c2 = 'z'; 13 | export c3 = 't'; 14 | 15 | commands := ( 16 | c1 . digit* '\n' @{ printf( "c1\n" );} | 17 | c2 . alpha* '\n' @{ printf( "c2\n" );}| 18 | c3 . '.'* '\n' @{ printf( "c3\n" );} 19 | )*; 20 | 21 | some_other := any*; 22 | }%% 23 | 24 | %% write exports; 25 | %% write data; 26 | 27 | int test( char data[] ) 28 | { 29 | int cs = test_en_commands; 30 | char *p = data.ptr, pe = data.ptr + data.length; 31 | 32 | %% write init nocs; 33 | %% write exec; 34 | 35 | if ( cs >= test_first_final ) 36 | printf("ACCEPT\n"); 37 | else 38 | printf("ERROR\n"); 39 | return 0; 40 | } 41 | 42 | char data[] = [ 43 | test_ex_c1, '1', '2', '\n', 44 | test_ex_c2, 'a', 'b', '\n', 45 | test_ex_c3, '.', '.', '\n' 46 | ]; 47 | 48 | int main() 49 | { 50 | test( data ); 51 | return 0; 52 | } 53 | 54 | /+ _____OUTPUT_____ 55 | c1 56 | c2 57 | c3 58 | ACCEPT 59 | ++++++++++++++++++/ 60 | -------------------------------------------------------------------------------- /test/fnext1.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | * 4 | * Tests fnext in combination with fbreak. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | char comm; 11 | int top; 12 | int stack [32]; 13 | 14 | %%{ 15 | machine fnext; 16 | action break {fbreak;} 17 | 18 | main := 'h' @{ /*h*/ fnext e; fbreak; }; 19 | e := 'e' @{ /*e*/ fnext l; } @{ fbreak; }; 20 | l := 'll' @{ /*ll*/ fnext o; } ${ fbreak; }; 21 | o := |* 'o' { /*o*/ fnext nl; fbreak; }; *|; 22 | nl := '\n' @{ /*nl*/ fbreak; printf("ACCEPT\n"); }; 23 | }%% 24 | 25 | int cs; 26 | char *ts, *te; 27 | int act; 28 | 29 | %% write data; 30 | 31 | void init() 32 | { 33 | %% write init; 34 | } 35 | 36 | void exec( char *data, int len ) 37 | { 38 | char *p = data; 39 | char *pe = data + len; 40 | 41 | while ( cs != fnext_error && p < pe ) { 42 | printf( "%c\n", *p ); 43 | %% write exec; 44 | } 45 | } 46 | 47 | void finish( ) 48 | { 49 | if ( cs >= fnext_first_final ) 50 | printf( "ACCEPT\n" ); 51 | else 52 | printf( "FAIL\n" ); 53 | } 54 | 55 | char *inp[] = { 56 | "hello\n" 57 | }; 58 | 59 | int inplen = 1; 60 | 61 | int main( ) 62 | { 63 | int i; 64 | for ( i = 0; i < inplen; i++ ) { 65 | init(); 66 | exec( inp[i], strlen(inp[i]) ); 67 | finish(); 68 | } 69 | return 0; 70 | } 71 | 72 | #ifdef _____OUTPUT_____ 73 | h 74 | e 75 | l 76 | l 77 | o 78 | 79 | 80 | ACCEPT 81 | #endif 82 | -------------------------------------------------------------------------------- /test/forder1.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | struct forder 9 | { 10 | int cs; 11 | }; 12 | 13 | %%{ 14 | machine forder; 15 | variable cs fsm->cs; 16 | 17 | second = 'b' 18 | >{printf("enter b1\n");} 19 | >{printf("enter b2\n");} 20 | ; 21 | 22 | first = 'a' 23 | %{printf("leave a\n");} 24 | @{printf("finish a\n");} 25 | ; 26 | 27 | main := first . second . '\n'; 28 | }%% 29 | 30 | %% write data; 31 | 32 | void forder_init( struct forder *fsm ) 33 | { 34 | %% write init; 35 | } 36 | 37 | void forder_execute( struct forder *fsm, const char *_data, int _len ) 38 | { 39 | const char *p = _data; 40 | const char *pe = _data+_len; 41 | 42 | %% write exec; 43 | } 44 | 45 | int forder_finish( struct forder *fsm ) 46 | { 47 | if ( fsm->cs == forder_error ) 48 | return -1; 49 | if ( fsm->cs >= forder_first_final ) 50 | return 1; 51 | return 0; 52 | } 53 | 54 | struct forder fsm; 55 | 56 | void test( char *buf ) 57 | { 58 | int len = strlen(buf); 59 | forder_init( &fsm ); 60 | forder_execute( &fsm, buf, len ); 61 | if ( forder_finish( &fsm ) > 0 ) 62 | printf("ACCEPT\n"); 63 | else 64 | printf("FAIL\n"); 65 | } 66 | 67 | int main() 68 | { 69 | test( "ab\n"); 70 | test( "abx\n"); 71 | test( "" ); 72 | 73 | test( 74 | "ab\n" 75 | "fail after newline\n" 76 | ); 77 | 78 | return 0; 79 | } 80 | 81 | #ifdef _____OUTPUT_____ 82 | finish a 83 | leave a 84 | enter b1 85 | enter b2 86 | ACCEPT 87 | finish a 88 | leave a 89 | enter b1 90 | enter b2 91 | FAIL 92 | FAIL 93 | finish a 94 | leave a 95 | enter b1 96 | enter b2 97 | FAIL 98 | #endif 99 | -------------------------------------------------------------------------------- /test/forder2.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | /* 9 | * After the fact start and ending transitions. Behaves like constructors of 10 | * and destructors in c++. 11 | */ 12 | 13 | struct forder 14 | { 15 | int cs; 16 | }; 17 | 18 | %%{ 19 | machine forder; 20 | variable cs fsm->cs; 21 | 22 | inner = 'inner' 23 | >{printf("enter inner\n");} 24 | ${printf("inside inner\n");} 25 | %{printf("leave inner\n");} 26 | ; 27 | 28 | outter = inner 29 | >{printf("enter outter\n");} 30 | ${printf("inside outter\n");} 31 | %{printf("leave outter\n");} 32 | ; 33 | 34 | main := outter . '\n'; 35 | }%% 36 | 37 | %% write data; 38 | 39 | void forder_init( struct forder *fsm ) 40 | { 41 | %% write init; 42 | } 43 | 44 | void forder_execute( struct forder *fsm, const char *_data, int _len ) 45 | { 46 | const char *p = _data; 47 | const char *pe = _data+_len; 48 | 49 | %% write exec; 50 | } 51 | 52 | int forder_finish( struct forder *fsm ) 53 | { 54 | if ( fsm->cs == forder_error ) 55 | return -1; 56 | if ( fsm->cs >= forder_first_final ) 57 | return 1; 58 | return 0; 59 | } 60 | 61 | struct forder fsm; 62 | 63 | void test( char *buf ) 64 | { 65 | int len = strlen( buf ); 66 | forder_init( &fsm ); 67 | forder_execute( &fsm, buf, len ); 68 | if ( forder_finish( &fsm ) > 0 ) 69 | printf("ACCEPT\n"); 70 | else 71 | printf("FAIL\n"); 72 | } 73 | 74 | 75 | int main() 76 | { 77 | test( "inner\n"); 78 | 79 | test( 80 | "inner\n" 81 | "foobar\n" 82 | ); 83 | 84 | test( "" ); 85 | test( "\n" ); 86 | test( "inn\n" ); 87 | 88 | return 0; 89 | } 90 | 91 | #ifdef _____OUTPUT_____ 92 | enter outter 93 | enter inner 94 | inside inner 95 | inside outter 96 | inside inner 97 | inside outter 98 | inside inner 99 | inside outter 100 | inside inner 101 | inside outter 102 | inside inner 103 | inside outter 104 | leave inner 105 | leave outter 106 | ACCEPT 107 | enter outter 108 | enter inner 109 | inside inner 110 | inside outter 111 | inside inner 112 | inside outter 113 | inside inner 114 | inside outter 115 | inside inner 116 | inside outter 117 | inside inner 118 | inside outter 119 | leave inner 120 | leave outter 121 | FAIL 122 | FAIL 123 | FAIL 124 | enter outter 125 | enter inner 126 | inside inner 127 | inside outter 128 | inside inner 129 | inside outter 130 | inside inner 131 | inside outter 132 | FAIL 133 | #endif 134 | -------------------------------------------------------------------------------- /test/forder3.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | struct forder 9 | { 10 | int cs; 11 | }; 12 | 13 | %%{ 14 | machine forder; 15 | variable cs fsm->cs; 16 | 17 | m1 = ( "" %{printf("enter m1 aa\n");} | 18 | 'aa'* >{printf("enter m1 aa\n");} %{printf("leave m1 aa\n");} ) 19 | 'b' @{printf("through m1 b\n");} . 'b'* . 'a'*; 20 | 21 | m2 = 'bbb'* 'aa'*; 22 | 23 | main := ( 24 | m1 %{printf("accept m1\n");} | 25 | "" %{printf("enter m2\n");} | 26 | m2 >{printf("enter m2\n");} %{printf("accept m2\n");} 27 | ) . '\n'; 28 | }%% 29 | 30 | %% write data; 31 | 32 | void forder_init( struct forder *fsm ) 33 | { 34 | %% write init; 35 | } 36 | 37 | void forder_execute( struct forder *fsm, const char *_data, int _len ) 38 | { 39 | const char *p = _data; 40 | const char *pe = _data+_len; 41 | 42 | %% write exec; 43 | } 44 | 45 | int forder_finish( struct forder *fsm ) 46 | { 47 | if ( fsm->cs == forder_error ) 48 | return -1; 49 | if ( fsm->cs >= forder_first_final ) 50 | return 1; 51 | return 0; 52 | } 53 | 54 | struct forder fsm; 55 | 56 | void test( char *buf ) 57 | { 58 | int len = strlen( buf ); 59 | forder_init( &fsm ); 60 | forder_execute( &fsm, buf, len ); 61 | if ( forder_finish( &fsm ) > 0 ) 62 | printf("ACCEPT\n"); 63 | else 64 | printf("FAIL\n"); 65 | } 66 | 67 | int main() 68 | { 69 | test( "aaaaaabbbaa\n" ); 70 | test( "\n" ); 71 | test( "bbbbbbaaaaaaa\n" ); 72 | test( "bbbbbbaaaaaa\n" ); 73 | test( "aaaaa\n" ); 74 | 75 | return 0; 76 | } 77 | 78 | #ifdef _____OUTPUT_____ 79 | enter m1 aa 80 | enter m2 81 | leave m1 aa 82 | through m1 b 83 | accept m1 84 | ACCEPT 85 | enter m2 86 | enter m2 87 | accept m2 88 | ACCEPT 89 | enter m1 aa 90 | enter m1 aa 91 | leave m1 aa 92 | through m1 b 93 | enter m2 94 | accept m1 95 | ACCEPT 96 | enter m1 aa 97 | enter m1 aa 98 | leave m1 aa 99 | through m1 b 100 | enter m2 101 | accept m1 102 | accept m2 103 | ACCEPT 104 | enter m1 aa 105 | enter m2 106 | FAIL 107 | #endif 108 | -------------------------------------------------------------------------------- /test/gotocallret2.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: indep 3 | */ 4 | 5 | char comm; 6 | int top; 7 | int stack[32]; 8 | ptr ts; 9 | ptr te; 10 | int act; 11 | int val; 12 | %% 13 | %%{ 14 | machine GotoCallRet; 15 | 16 | sp = ' '; 17 | 18 | handle := any @{ 19 | prints "handle "; 20 | fhold; 21 | if ( val == 1 ) fnext *fentry(one); 22 | if ( val == 2 ) fnext *fentry(two); 23 | if ( val == 3 ) fnext main; 24 | }; 25 | 26 | one := |* 27 | '{' => { prints "{ "; fcall *fentry(one); }; 28 | "[" => { prints "[ "; fcall *fentry(two); }; 29 | "}" sp* => { prints "} "; fret; }; 30 | [a-z]+ => { prints "word "; val = 1; fgoto *fentry(handle); }; 31 | ' ' => { prints "space "; }; 32 | *|; 33 | 34 | two := |* 35 | '{' => { prints "{ "; fcall *fentry(one); }; 36 | "[" => { prints "[ "; fcall *fentry(two); }; 37 | ']' sp* => { prints "] "; fret; }; 38 | [a-z]+ => { prints "word "; val = 2; fgoto *fentry(handle); }; 39 | ' ' => { prints "space "; }; 40 | *|; 41 | 42 | main := |* 43 | '{' => { prints "{ "; fcall one; }; 44 | "[" => { prints "[ "; fcall two; }; 45 | [a-z]+ => { prints "word "; val = 3; fgoto handle; }; 46 | [a-z] ' foil' => { prints "this is the foil";}; 47 | ' ' => { prints "space "; }; 48 | '\n'; 49 | *|; 50 | }%% 51 | /* _____INPUT_____ 52 | "{a{b[c d]d}c}\n" 53 | "[a{b[c d]d}c}\n" 54 | "[a[b]c]d{ef{g{h}i}j}l\n" 55 | "{{[]}}\n" 56 | "a b c\n" 57 | "{a b c}\n" 58 | "[a b c]\n" 59 | "{]\n" 60 | "{{}\n" 61 | "[[[[[[]]]]]]\n" 62 | "[[[[[[]]}]]]\n" 63 | _____INPUT_____ */ 64 | /* _____OUTPUT_____ 65 | { word handle { word handle [ word handle space word handle ] word handle } word handle } ACCEPT 66 | [ word handle { word handle [ word handle space word handle ] word handle } word handle FAIL 67 | [ word handle [ word handle ] word handle ] word handle { word handle { word handle { word handle } word handle } word handle } word handle ACCEPT 68 | { { [ ] } } ACCEPT 69 | word handle space word handle space word handle ACCEPT 70 | { word handle space word handle space word handle } ACCEPT 71 | [ word handle space word handle space word handle ] ACCEPT 72 | { FAIL 73 | { { } FAIL 74 | [ [ [ [ [ [ ] ] ] ] ] ] ACCEPT 75 | [ [ [ [ [ [ ] ] FAIL 76 | _____OUTPUT_____ */ 77 | 78 | -------------------------------------------------------------------------------- /test/high2.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c++ 3 | */ 4 | 5 | /** 6 | * Test a high character to make sure signedness 7 | * isn't messing us up. 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | struct Fsm 14 | { 15 | int cs; 16 | 17 | // Initialize the machine. Invokes any init statement blocks. Returns 0 18 | // if the machine begins in a non-accepting state and 1 if the machine 19 | // begins in an accepting state. 20 | int init( ); 21 | 22 | // Execute the machine on a block of data. Returns -1 if after processing 23 | // the data, the machine is in the error state and can never accept, 0 if 24 | // the machine is in a non-accepting state and 1 if the machine is in an 25 | // accepting state. 26 | int execute( const unsigned char *data, int len ); 27 | 28 | // Indicate that there is no more data. Returns -1 if the machine finishes 29 | // in the error state and does not accept, 0 if the machine finishes 30 | // in any other non-accepting state and 1 if the machine finishes in an 31 | // accepting state. 32 | int finish( ); 33 | }; 34 | 35 | %%{ 36 | machine Fsm; 37 | 38 | alphtype unsigned char; 39 | 40 | # Indicate we got the high character. 41 | action gothigh { 42 | printf("yes\n"); 43 | } 44 | 45 | main := 0xe8 @gothigh '\n'; 46 | }%% 47 | 48 | %% write data; 49 | 50 | int Fsm::init( ) 51 | { 52 | %% write init; 53 | return 0; 54 | } 55 | 56 | int Fsm::execute( const unsigned char *_data, int _len ) 57 | { 58 | const unsigned char *p = _data; 59 | const unsigned char *pe = _data+_len; 60 | %% write exec; 61 | if ( cs == Fsm_error ) 62 | return -1; 63 | if ( cs >= Fsm_first_final ) 64 | return 1; 65 | return 0; 66 | } 67 | 68 | int Fsm::finish() 69 | { 70 | if ( cs == Fsm_error ) 71 | return -1; 72 | if ( cs >= Fsm_first_final ) 73 | return 1; 74 | return 0; 75 | } 76 | 77 | Fsm fsm; 78 | 79 | void test( unsigned char *buf, int len ) 80 | { 81 | fsm.init(); 82 | fsm.execute( buf, len ); 83 | if ( fsm.finish() > 0 ) 84 | printf("ACCEPT\n"); 85 | else 86 | printf("FAIL\n"); 87 | } 88 | 89 | unsigned char data1[] = { 0xe8, 10 }; 90 | unsigned char data2[] = { 0xf8, 10 }; 91 | 92 | int main() 93 | { 94 | test( data1, 2 ); 95 | test( data2, 2 ); 96 | return 0; 97 | } 98 | 99 | #ifdef _____OUTPUT_____ 100 | yes 101 | ACCEPT 102 | FAIL 103 | #endif 104 | -------------------------------------------------------------------------------- /test/high3.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: obj-c 3 | */ 4 | 5 | /** 6 | * Test a high character to make sure signedness 7 | * isn't messing us up. 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | @interface Fsm : Object 14 | { 15 | @public 16 | int cs; 17 | }; 18 | 19 | // Initialize the machine. Invokes any init statement blocks. Returns 0 20 | // if the machine begins in a non-accepting state and 1 if the machine 21 | // begins in an accepting state. 22 | - (int) initFsm; 23 | 24 | // Execute the machine on a block of data. Returns -1 if after processing 25 | // the data, the machine is in the error state and can never accept, 0 if 26 | // the machine is in a non-accepting state and 1 if the machine is in an 27 | // accepting state. 28 | - (void) executeWithData:(const unsigned char *)data len:(int)len; 29 | 30 | // Indicate that there is no more data. Returns -1 if the machine finishes 31 | // in the error state and does not accept, 0 if the machine finishes 32 | // in any other non-accepting state and 1 if the machine finishes in an 33 | // accepting state. 34 | - (int) finish; 35 | 36 | @end 37 | 38 | @implementation Fsm 39 | 40 | %%{ 41 | machine Fsm; 42 | 43 | alphtype unsigned char; 44 | 45 | # Indicate we got the high character. 46 | action gothigh { 47 | printf("yes\n"); 48 | } 49 | 50 | main := 0xe8 @gothigh '\n'; 51 | }%% 52 | 53 | %% write data; 54 | 55 | - (int) initFsm; 56 | { 57 | %% write init; 58 | return 1; 59 | } 60 | 61 | - (void) executeWithData:(const unsigned char *)_data len:(int)_len; 62 | { 63 | const unsigned char *p = _data; 64 | const unsigned char *pe = _data + _len; 65 | %% write exec; 66 | } 67 | 68 | - (int) finish; 69 | { 70 | if ( cs == Fsm_error ) 71 | return -1; 72 | else if ( cs >= Fsm_first_final ) 73 | return 1; 74 | return 0; 75 | } 76 | 77 | 78 | @end 79 | 80 | 81 | #define BUFSIZE 2048 82 | 83 | Fsm *fsm; 84 | unsigned char buf[BUFSIZE]; 85 | 86 | void test( unsigned char *buf, int len ) 87 | { 88 | fsm = [[Fsm alloc] init]; 89 | [fsm initFsm]; 90 | [fsm executeWithData:buf len:len]; 91 | if ( [fsm finish] > 0 ) 92 | printf("ACCEPT\n"); 93 | else 94 | printf("FAIL\n"); 95 | } 96 | 97 | unsigned char data1[] = { 0xe8, 10 }; 98 | unsigned char data2[] = { 0xf8, 10 }; 99 | 100 | int main() 101 | { 102 | test( data1, 2 ); 103 | test( data2, 2 ); 104 | return 0; 105 | } 106 | 107 | #ifdef _____OUTPUT_____ 108 | yes 109 | ACCEPT 110 | FAIL 111 | #endif 112 | -------------------------------------------------------------------------------- /test/import1.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | */ 4 | 5 | #include 6 | 7 | char *foo = "foo"; 8 | 9 | char b = 98; 10 | char a = 97; 11 | char r = 114; 12 | 13 | #define SP 32 14 | #define NL '\n' 15 | 16 | %%{ 17 | machine tmp; 18 | import "import1.rl"; 19 | 20 | foobar = 21 | foo @{printf("foo\n"); } | 22 | b a r @{printf("bar\n");}; 23 | 24 | main := ( foobar SP foobar NL )*; 25 | }%% 26 | 27 | %% write data; 28 | 29 | int cs; 30 | 31 | void exec_str( char *p, int len ) 32 | { 33 | char *pe = p + len; 34 | %% write exec; 35 | } 36 | 37 | void exec_c( char c ) 38 | { 39 | exec_str( &c, 1 ); 40 | } 41 | 42 | int main() 43 | { 44 | %% write init; 45 | 46 | exec_str( foo, 3 ); 47 | exec_c( SP ); 48 | exec_c( b ); 49 | exec_c( a ); 50 | exec_c( r ); 51 | exec_c( NL ); 52 | 53 | exec_c( b ); 54 | exec_c( a ); 55 | exec_c( r ); 56 | exec_c( SP ); 57 | exec_str( foo, 3 ); 58 | exec_c( NL ); 59 | 60 | if ( cs < tmp_first_final ) 61 | printf("FAIL\n"); 62 | else 63 | printf("ACCEPT\n"); 64 | 65 | return 0; 66 | } 67 | #ifdef _____OUTPUT_____ 68 | foo 69 | bar 70 | bar 71 | foo 72 | ACCEPT 73 | #endif 74 | -------------------------------------------------------------------------------- /test/include1.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | * @IGNORE: yes 4 | * 5 | * Provides definitions for include tests. 6 | */ 7 | 8 | %%{ 9 | machine include_test_1; 10 | 11 | action A {printf(" a1");} 12 | action B {printf(" b1");} 13 | 14 | action NonRef1 {printf(" nr1");} 15 | 16 | a1 = 'a' @A; 17 | b1 = 'b' @B; 18 | }%% 19 | 20 | %%{ 21 | machine include_test_2; 22 | 23 | action NonRef2 {printf(" nr2");} 24 | 25 | a2 = 'a' @{printf(" a2");}; 26 | b2 = 'b' @{printf(" b2");}; 27 | }%% 28 | 29 | -------------------------------------------------------------------------------- /test/include2.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | %%{ 9 | machine include_test_4; 10 | 11 | action NonRef3 {printf(" nr3");} 12 | 13 | a3 = 'a'@{printf(" a3");}; 14 | b3 = 'b'@{printf(" b3");}; 15 | 16 | }%% 17 | 18 | %%{ 19 | machine include_test_1; 20 | 21 | include "include1.rl"; 22 | 23 | include include_test_2 "include1.rl"; 24 | 25 | include include_test_4; 26 | 27 | main := 28 | a1 b1 @NonRef1 29 | a2 b2 @NonRef2 30 | a3 b3 @NonRef3 31 | 0 @{fbreak;}; 32 | }%% 33 | 34 | %% write data; 35 | 36 | void test( char *p ) 37 | { 38 | int cs; 39 | %% write init; 40 | %% write exec noend; 41 | printf("\n"); 42 | } 43 | 44 | int main() 45 | { 46 | test( "ababab" ); 47 | return 0; 48 | } 49 | 50 | #ifdef _____OUTPUT_____ 51 | a1 b1 nr1 a2 b2 nr2 a3 b3 nr3 52 | #endif 53 | -------------------------------------------------------------------------------- /test/java1.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: java 3 | */ 4 | 5 | class java1 6 | { 7 | %%{ 8 | machine java1; 9 | 10 | one := 'one\n'; 11 | two := 'two\n'; 12 | four := 'four\n'; 13 | 14 | main := 15 | ( 'hello' | 'there' | 'friend' ) 16 | '\n' @{int s = fentry(one); fgoto *s; char c = fc;} 17 | ( 'one' | 'two' | 'four' ) '\n'; 18 | }%% 19 | 20 | %% write data; 21 | 22 | static void test( char data[] ) 23 | { 24 | int cs, p = 0, pe = data.length; 25 | int top; 26 | 27 | %% write init; 28 | %% write exec; 29 | 30 | if ( cs >= java1_first_final ) 31 | System.out.println( "ACCEPT" ); 32 | else 33 | System.out.println( "FAIL" ); 34 | } 35 | 36 | public static void main( String args[] ) 37 | { 38 | test( "hello\none\n".toCharArray() ); 39 | test( "there\ntwo\n".toCharArray() ); 40 | test( "friend\nfour\n".toCharArray() ); 41 | } 42 | } 43 | 44 | /* _____OUTPUT_____ 45 | ACCEPT 46 | FAIL 47 | FAIL 48 | */ 49 | -------------------------------------------------------------------------------- /test/java2.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: java 3 | */ 4 | 5 | class java2 6 | { 7 | %%{ 8 | machine java1; 9 | alphtype int; 10 | 11 | main := 1 2 3 4 ( 12 | 5 6 7 8 | 13 | 9 10 11 12 14 | ) 1073741824; 15 | 16 | }%% 17 | 18 | %% write data; 19 | 20 | static void test( int data[] ) 21 | { 22 | int cs, p = 0, pe = data.length; 23 | int top; 24 | 25 | %% write init; 26 | %% write exec; 27 | 28 | if ( cs >= java1_first_final ) 29 | System.out.println( "ACCEPT" ); 30 | else 31 | System.out.println( "FAIL" ); 32 | } 33 | 34 | static final int t1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 1073741824 }; 35 | static final int t2[] = { 1, 2, 3, 4, 9, 10, 11, 12, 1073741824 }; 36 | static final int t3[] = { 1, 2, 3, 4, 1073741824 }; 37 | 38 | public static void main( String args[] ) 39 | { 40 | test( t1 ); 41 | test( t2 ); 42 | test( t3 ); 43 | } 44 | } 45 | 46 | /* _____OUTPUT_____ 47 | ACCEPT 48 | ACCEPT 49 | FAIL 50 | */ 51 | -------------------------------------------------------------------------------- /test/langtrans_c.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | 4 | file=$1 5 | 6 | [ -f $file ] || exit 1 7 | 8 | # Get the machine name. 9 | machine=`sed -n 's/^[\t ]*machine[\t ]*\([a-zA-Z_0-9]*\)[\t ]*;[\t ]*$/\1/p' $file` 10 | 11 | # Make a temporary version of the test case using the C language translations. 12 | sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin langtrans_c.txl > $file.pr 13 | 14 | needs_eof=`sed '/@NEEDS_EOF/s/^.*$/yes/p;d' $file` 15 | if [ "$needs_eof" != 'yes' ]; then 16 | needs_eof=`sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin checkeofact.txl` 17 | fi 18 | 19 | # Begin writing out the test case. 20 | cat << EOF 21 | /* 22 | * @LANG: c 23 | * @GENERATED: yes 24 | EOF 25 | 26 | grep '@ALLOW_GENFLAGS:' $file 27 | grep '@ALLOW_MINFLAGS:' $file 28 | 29 | cat << EOF 30 | */ 31 | #include 32 | #include 33 | EOF 34 | 35 | # Write the data declarations 36 | sed -n '/^%%$/q;p' $file.pr 37 | 38 | # Write out the machine specification. 39 | sed -n '/^%%{$/,/^}%%/p' $file.pr 40 | 41 | # Write out the init and execute routines. 42 | cat << EOF 43 | int cs; 44 | %% write data; 45 | void init() 46 | { 47 | EOF 48 | 49 | sed -n '0,/^%%$/d; /^%%{$/q; {s/^/\t/;p}' $file.pr 50 | 51 | cat << EOF 52 | %% write init; 53 | } 54 | 55 | void exec( char *data, int len ) 56 | { 57 | char *p = data; 58 | char *pe = data + len; 59 | EOF 60 | 61 | [ "$needs_eof" = "yes" ] && echo "char *eof = pe;" 62 | 63 | cat << EOF 64 | %% write exec; 65 | } 66 | 67 | void finish( ) 68 | { 69 | if ( cs >= ${machine}_first_final ) 70 | printf( "ACCEPT\\n" ); 71 | else 72 | printf( "FAIL\\n" ); 73 | } 74 | EOF 75 | 76 | # Write out the test data. 77 | sed -n '0,/\/\* _____INPUT_____/d; /_____INPUT_____ \*\//q; p;' $file | awk ' 78 | BEGIN { 79 | print "char *inp[] = {" 80 | } 81 | { 82 | print " " $0 "," 83 | } 84 | END { 85 | print "};" 86 | print "" 87 | print "int inplen = " NR ";" 88 | }' 89 | 90 | # Write out the main routine. 91 | cat << EOF 92 | 93 | int main( ) 94 | { 95 | int i; 96 | for ( i = 0; i < inplen; i++ ) { 97 | init(); 98 | exec( inp[i], strlen(inp[i]) ); 99 | finish(); 100 | } 101 | return 0; 102 | } 103 | #ifdef _____OUTPUT_____ 104 | EOF 105 | 106 | # Write out the expected output. 107 | sed -n '0,/\/\* _____OUTPUT_____/d; /_____OUTPUT_____ \*\//q; p;' $file 108 | echo "#endif" 109 | 110 | # Don't need this language-specific file anymore. 111 | rm $file.pr 112 | -------------------------------------------------------------------------------- /test/langtrans_csharp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | 4 | file=$1 5 | 6 | [ -f $file ] || exit 1 7 | root=${file%.rl} 8 | class=${root}_csharp 9 | 10 | # Make a temporary version of the test case using the Java language translations. 11 | sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin langtrans_csharp.txl - $class > $file.pr 12 | 13 | # Begin writing out the test case. 14 | cat << EOF 15 | /* 16 | * @LANG: csharp 17 | * @GENERATED: yes 18 | EOF 19 | 20 | grep '@ALLOW_GENFLAGS:' $file | sed 's/-G2//g' 21 | grep '@ALLOW_MINFLAGS:' $file 22 | 23 | cat << EOF 24 | */ 25 | using System; 26 | // Disables lots of warnings that appear in the test suite 27 | #pragma warning disable 0168, 0169, 0219, 0162, 0414 28 | namespace Test { 29 | class $class 30 | { 31 | EOF 32 | 33 | # Write the data declarations 34 | sed -n '/^%%$/q;{s/^/\t/;p}' $file.pr 35 | 36 | # Write out the machine specification. 37 | sed -n '/^%%{$/,/^}%%/{s/^/\t/;p}' $file.pr 38 | 39 | # Write out the init and execute routines. 40 | cat << EOF 41 | 42 | int cs; 43 | %% write data; 44 | 45 | void init() 46 | { 47 | EOF 48 | 49 | sed -n '0,/^%%$/d; /^%%{$/q; {s/^/\t\t/;p}' $file.pr 50 | 51 | cat << EOF 52 | %% write init; 53 | } 54 | 55 | void exec( char[] data, int len ) 56 | { 57 | int p = 0; 58 | int pe = len; 59 | int eof = len; 60 | string _s; 61 | %% write exec; 62 | } 63 | 64 | void finish( ) 65 | { 66 | if ( cs >= ${class}_first_final ) 67 | Console.WriteLine( "ACCEPT" ); 68 | else 69 | Console.WriteLine( "FAIL" ); 70 | } 71 | 72 | EOF 73 | 74 | # Write out the test data. 75 | sed -n '0,/\/\* _____INPUT_____/d; /_____INPUT_____ \*\//q; p;' $file | awk ' 76 | BEGIN { 77 | print " static readonly string[] inp = {" 78 | } 79 | { 80 | print " " $0 "," 81 | } 82 | END { 83 | print " };" 84 | print "" 85 | print " static readonly int inplen = " NR ";" 86 | }' 87 | 88 | 89 | # Write out the main routine. 90 | cat << EOF 91 | 92 | public static void Main (string[] args) 93 | { 94 | $class machine = new $class(); 95 | for ( int i = 0; i < inplen; i++ ) { 96 | machine.init(); 97 | machine.exec( inp[i].ToCharArray(), inp[i].Length ); 98 | machine.finish(); 99 | } 100 | } 101 | } 102 | } 103 | EOF 104 | 105 | # Write out the expected output. 106 | sed -n '/\/\* _____OUTPUT_____/,/_____OUTPUT_____ \*\//p;' $file 107 | 108 | # Don't need this language-specific file anymore. 109 | rm $file.pr 110 | -------------------------------------------------------------------------------- /test/langtrans_d.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | 4 | file=$1 5 | 6 | [ -f $file ] || exit 1 7 | 8 | # Get the amchine name. 9 | machine=`sed -n 's/^[\t ]*machine[\t ]*\([a-zA-Z_0-9]*\)[\t ]*;[\t ]*$/\1/p' $file` 10 | 11 | # Make a temporary version of the test case the D language translations. 12 | sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin langtrans_d.txl > $file.pr 13 | 14 | # Begin writing out the test case. 15 | cat << EOF 16 | /* 17 | * @LANG: d 18 | * @GENERATED: yes 19 | EOF 20 | 21 | grep '@ALLOW_GENFLAGS:' $file 22 | grep '@ALLOW_MINFLAGS:' $file 23 | 24 | cat << EOF 25 | */ 26 | import std.stdio; 27 | import std.string; 28 | 29 | class $machine 30 | { 31 | EOF 32 | 33 | # Write the data declarations 34 | sed -n '/^%%$/q;{s/^/\t/;p}' $file.pr 35 | 36 | # Write out the machine specification. 37 | sed -n '/^%%{$/,/^}%%/{s/^/\t/;p}' $file.pr 38 | 39 | # Write out the init and execute routines. 40 | cat << EOF 41 | int cs; 42 | %% write data; 43 | void init() 44 | { 45 | EOF 46 | 47 | sed -n '0,/^%%$/d; /^%%{$/q; {s/^/\t\t/;p}' $file.pr 48 | 49 | cat << EOF 50 | %% write init; 51 | } 52 | 53 | void exec( char data[] ) 54 | { 55 | char *p = data.ptr; 56 | char *pe = data.ptr + data.length; 57 | char *eof = pe; 58 | char _s[]; 59 | 60 | %% write exec; 61 | } 62 | 63 | void finish( ) 64 | { 65 | if ( cs >= ${machine}_first_final ) 66 | writefln( "ACCEPT" ); 67 | else 68 | writefln( "FAIL" ); 69 | } 70 | 71 | EOF 72 | 73 | # Write out the test data. 74 | sed -n '0,/\/\* _____INPUT_____/d; /_____INPUT_____ \*\//q; p;' $file | awk ' 75 | BEGIN { 76 | print " char[][] inp = [" 77 | } 78 | { 79 | print " " $0 "," 80 | } 81 | END { 82 | print " ];" 83 | print "" 84 | print " int inplen = " NR ";" 85 | }' 86 | 87 | # Write out the main routine. 88 | cat << EOF 89 | } 90 | 91 | int main( ) 92 | { 93 | $machine m = new $machine(); 94 | int i; 95 | for ( i = 0; i < m.inplen; i++ ) { 96 | m.init(); 97 | m.exec( m.inp[i] ); 98 | m.finish(); 99 | } 100 | return 0; 101 | } 102 | /* _____OUTPUT_____ 103 | EOF 104 | 105 | # Write out the expected output. 106 | sed -n '0,/\/\* _____OUTPUT_____/d; /_____OUTPUT_____ \*\//q; p;' $file 107 | echo "*/" 108 | 109 | # Don't need this language-specific file anymore. 110 | rm $file.pr 111 | -------------------------------------------------------------------------------- /test/langtrans_go.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | 4 | file=$1 5 | 6 | [ -f $file ] || exit 1 7 | root=${file%.rl} 8 | 9 | # Get the machine name. 10 | machine=`sed -n 's/^[\t ]*machine[\t ]*\([a-zA-Z_0-9]*\)[\t ]*;[\t ]*$/\1/p' $file` 11 | 12 | 13 | # Make a temporary version of the test case using the Java language translations. 14 | sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin langtrans_go.txl > $file.pr 15 | 16 | needs_eof=`sed '/@NEEDS_EOF/s/^.*$/yes/p;d' $file` 17 | if [ "$needs_eof" != 'yes' ]; then 18 | needs_eof=`sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin checkeofact.txl` 19 | fi 20 | 21 | # Begin writing out the test case. 22 | cat << EOF 23 | /* 24 | * @LANG: go 25 | * @GENERATED: yes 26 | EOF 27 | 28 | grep '@ALLOW_GENFLAGS:' $file 29 | grep '@ALLOW_MINFLAGS:' $file 30 | 31 | cat << EOF 32 | */ 33 | 34 | package main 35 | 36 | import "fmt" 37 | 38 | EOF 39 | 40 | # Write the data declarations 41 | sed -n '/^%%$/q;{s/^/\t/;p}' $file.pr 42 | 43 | # Write out the machine specification. 44 | sed -n '/^%%{$/,/^}%%/{s/^/\t/;p}' $file.pr 45 | 46 | # Write out the init and execute routines. 47 | cat << EOF 48 | 49 | var cs int 50 | %% write data; 51 | 52 | func prepare() { 53 | EOF 54 | 55 | sed -n '0,/^%%$/d; /^%%{$/q; {s/^/\t\t/;p}' $file.pr 56 | 57 | cat << EOF 58 | %% write init; 59 | } 60 | 61 | func exec(data string) { 62 | var p int = 0 63 | var pe int = len(data) 64 | EOF 65 | 66 | [ "$needs_eof" = "yes" ] && echo " var eof int = pe" 67 | 68 | cat << EOF 69 | 70 | %% write exec; 71 | } 72 | 73 | func finish() { 74 | if cs >= ${machine}_first_final { 75 | fmt.Println("ACCEPT") 76 | } else { 77 | fmt.Println("FAIL") 78 | } 79 | } 80 | EOF 81 | 82 | # Write out the test data. 83 | sed -n '0,/\/\* _____INPUT_____/d; /_____INPUT_____ \*\//q; p;' $file | awk ' 84 | BEGIN { 85 | printf "var inp []string = []string{" 86 | } 87 | { 88 | printf "%s, ", $0 89 | } 90 | END { 91 | print "}" 92 | print "" 93 | }' 94 | 95 | 96 | # Write out the main routine. 97 | cat << EOF 98 | 99 | func main() { 100 | for _, data := range inp { 101 | prepare() 102 | exec(data) 103 | finish() 104 | } 105 | } 106 | EOF 107 | 108 | # Write out the expected output. 109 | sed -n '/\/\* _____OUTPUT_____/,/_____OUTPUT_____ \*\//p;' $file 110 | 111 | # Don't need this language-specific file anymore. 112 | rm $file.pr 113 | -------------------------------------------------------------------------------- /test/langtrans_java.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | 4 | file=$1 5 | 6 | [ -f $file ] || exit 1 7 | root=${file%.rl} 8 | class=${root}_java 9 | 10 | # Make a temporary version of the test case using the Java language translations. 11 | sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin langtrans_java.txl - $class > $file.pr 12 | 13 | # Begin writing out the test case. 14 | cat << EOF 15 | /* 16 | * @LANG: java 17 | * @GENERATED: yes 18 | EOF 19 | 20 | grep '@ALLOW_GENFLAGS:' $file 21 | grep '@ALLOW_MINFLAGS:' $file 22 | 23 | cat << EOF 24 | */ 25 | 26 | class $class 27 | { 28 | EOF 29 | 30 | # Write the data declarations 31 | sed -n '/^%%$/q;{s/^/\t/;p}' $file.pr 32 | 33 | # Write out the machine specification. 34 | sed -n '/^%%{$/,/^}%%/{s/^/\t/;p}' $file.pr 35 | 36 | # Write out the init and execute routines. 37 | cat << EOF 38 | 39 | int cs; 40 | %% write data; 41 | 42 | void init() 43 | { 44 | EOF 45 | 46 | sed -n '0,/^%%$/d; /^%%{$/q; {s/^/\t\t/;p}' $file.pr 47 | 48 | cat << EOF 49 | %% write init; 50 | } 51 | 52 | void exec( char data[], int len ) 53 | { 54 | int p = 0; 55 | int pe = len; 56 | int eof = len; 57 | String _s; 58 | %% write exec; 59 | } 60 | 61 | void finish( ) 62 | { 63 | if ( cs >= ${class}_first_final ) 64 | System.out.println( "ACCEPT" ); 65 | else 66 | System.out.println( "FAIL" ); 67 | } 68 | 69 | EOF 70 | 71 | # Write out the test data. 72 | sed -n '0,/\/\* _____INPUT_____/d; /_____INPUT_____ \*\//q; p;' $file | awk ' 73 | BEGIN { 74 | print " static final String inp[] = {" 75 | } 76 | { 77 | print " " $0 "," 78 | } 79 | END { 80 | print " };" 81 | print "" 82 | print " static final int inplen = " NR ";" 83 | }' 84 | 85 | 86 | # Write out the main routine. 87 | cat << EOF 88 | 89 | public static void main (String[] args) 90 | { 91 | $class machine = new $class(); 92 | for ( int i = 0; i < inplen; i++ ) { 93 | machine.init(); 94 | machine.exec( inp[i].toCharArray(), inp[i].length() ); 95 | machine.finish(); 96 | } 97 | } 98 | } 99 | 100 | EOF 101 | 102 | # Write out the expected output. 103 | sed -n '/\/\* _____OUTPUT_____/,/_____OUTPUT_____ \*\//p;' $file 104 | 105 | # Don't need this language-specific file anymore. 106 | rm $file.pr 107 | -------------------------------------------------------------------------------- /test/langtrans_ruby.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | 4 | file=$1 5 | 6 | [ -f $file ] || exit 1 7 | 8 | # Get the machine name. 9 | machine=`sed -n 's/^[\t ]*machine[\t ]*\([a-zA-Z_0-9]*\)[\t ]*;[\t ]*$/\1/p' \ 10 | $file | tr '[A-Z]' '[a-z]'` 11 | 12 | # Make a temporary version of the test case using the Ruby language translations. 13 | sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin langtrans_ruby.txl > $file.pr 14 | 15 | # Begin writing out the test case. 16 | cat << EOF 17 | # 18 | # @LANG: ruby 19 | # @GENERATED: yes 20 | EOF 21 | 22 | grep '@ALLOW_GENFLAGS:' $file | sed 's/^ *\*/#/' | sed 's/-G.//g' 23 | grep '@ALLOW_MINFLAGS:' $file | sed 's/^ *\*/#/' 24 | 25 | cat << EOF 26 | # 27 | 28 | EOF 29 | 30 | # Write out the machine specification. 31 | sed -n '/^%%{$/,/^}%%/{s/^/\t/;p}' $file.pr 32 | 33 | # Write out the init and execute routines. 34 | cat << EOF 35 | 36 | %% write data; 37 | 38 | def run_machine( data ) 39 | p = 0 40 | pe = data.length 41 | eof = data.length 42 | cs = 0; 43 | EOF 44 | 45 | # Write the data declarations 46 | sed -n '/^%%$/q;{s/^/\t/;p}' $file.pr 47 | 48 | # Write the data initializations 49 | sed -n '0,/^%%$/d; /^%%{$/q; {s/^/\t\t/;p}' $file.pr 50 | 51 | cat << EOF 52 | 53 | %% write init; 54 | %% write exec; 55 | if cs >= ${machine}_first_final 56 | puts "ACCEPT" 57 | else 58 | puts "FAIL" 59 | end 60 | end 61 | 62 | EOF 63 | 64 | # Write out the test data. 65 | sed -n '0,/\/\* _____INPUT_____/d; /_____INPUT_____ \*\//q; p;' $file | awk ' 66 | BEGIN { 67 | print " inp = [" 68 | } 69 | { 70 | print " " $0 "," 71 | } 72 | END { 73 | print " ]" 74 | print "" 75 | print " inplen = " NR ";" 76 | }' 77 | 78 | 79 | # Write out the main routine. 80 | cat << EOF 81 | 82 | inp.each { |str| 83 | run_machine(str.unpack("c*")) 84 | } 85 | 86 | EOF 87 | 88 | # Write out the expected output. 89 | echo "=begin _____OUTPUT_____" 90 | 91 | sed -n '/\/\* _____OUTPUT_____/,/_____OUTPUT_____ \*\//{/_____OUTPUT_____/d;p;};' $file 92 | 93 | echo "=end _____OUTPUT_____" 94 | 95 | # Don't need this language-specific file anymore. 96 | rm $file.pr 97 | -------------------------------------------------------------------------------- /test/mailbox1.h: -------------------------------------------------------------------------------- 1 | #ifndef _MAILBOX1_H 2 | #define _MAILBOX1_H 3 | 4 | #include 5 | #include 6 | #include "vector.h" 7 | 8 | struct MBox 9 | { 10 | int cs; 11 | 12 | Vector headName; 13 | Vector headContent; 14 | 15 | // Initialize the machine. Invokes any init statement blocks. Returns 0 16 | // if the machine begins in a non-accepting state and 1 if the machine 17 | // begins in an accepting state. 18 | void init( ); 19 | 20 | // Execute the machine on a block of data. Returns -1 if after processing 21 | // the data, the machine is in the error state and can never accept, 0 if 22 | // the machine is in a non-accepting state and 1 if the machine is in an 23 | // accepting state. 24 | void execute( const char *data, int len ); 25 | 26 | // Indicate that there is no more data. Returns -1 if the machine finishes 27 | // in the error state and does not accept, 0 if the machine finishes 28 | // in any other non-accepting state and 1 if the machine finishes in an 29 | // accepting state. 30 | int finish( ); 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /test/minimize1.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | struct min 9 | { 10 | int cs; 11 | }; 12 | 13 | %%{ 14 | machine min; 15 | variable cs fsm->cs; 16 | 17 | action a_or_b { printf("a or b\n"); } 18 | 19 | main := ( 20 | ( 'a' . [ab]* @a_or_b ) | 21 | ( 'b' . [ab]* @a_or_b ) 22 | ) . '\n'; 23 | }%% 24 | 25 | %% write data; 26 | 27 | void min_init( struct min *fsm ) 28 | { 29 | %% write init; 30 | } 31 | 32 | void min_execute( struct min *fsm, const char *_data, int _len ) 33 | { 34 | const char *p = _data; 35 | const char *pe = _data+_len; 36 | 37 | %% write exec; 38 | } 39 | 40 | int min_finish( struct min *fsm ) 41 | { 42 | if ( fsm->cs == min_error ) 43 | return -1; 44 | if ( fsm->cs >= min_first_final ) 45 | return 1; 46 | return 0; 47 | } 48 | 49 | struct min fsm; 50 | 51 | void test( char *buf ) 52 | { 53 | int len = strlen( buf ); 54 | min_init( &fsm ); 55 | min_execute( &fsm, buf, len ); 56 | if ( min_finish( &fsm ) > 0 ) 57 | printf("ACCEPT\n"); 58 | else 59 | printf("FAIL\n"); 60 | } 61 | 62 | 63 | int main() 64 | { 65 | test( "aaaaaa\n" ); 66 | test( "a\n" ); 67 | test( "abc\n" ); 68 | return 0; 69 | } 70 | 71 | #ifdef _____OUTPUT_____ 72 | a or b 73 | a or b 74 | a or b 75 | a or b 76 | a or b 77 | ACCEPT 78 | ACCEPT 79 | a or b 80 | FAIL 81 | #endif 82 | -------------------------------------------------------------------------------- /test/patact.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: indep 3 | */ 4 | 5 | char comm; 6 | int top; 7 | int stack[32]; 8 | ptr ts; 9 | ptr te; 10 | int act; 11 | int val; 12 | %% 13 | %%{ 14 | machine patact; 15 | 16 | other := |* 17 | [a-z]+ => { prints "word\n"; }; 18 | [0-9]+ => { prints "num\n"; }; 19 | [\n ] => { prints "space\n"; }; 20 | *|; 21 | 22 | exec_test := |* 23 | [a-z]+ => { prints "word (w/lbh)\n"; fexec te-1; fgoto other; }; 24 | [a-z]+ ' foil' => { prints "word (c/lbh)\n"; }; 25 | [\n ] => { prints "space\n"; }; 26 | '22' => { prints "num (w/switch)\n"; }; 27 | [0-9]+ => { prints "num (w/switch)\n"; fexec te-1; fgoto other;}; 28 | [0-9]+ ' foil' => {prints "num (c/switch)\n"; }; 29 | '!';# => { prints "immdiate\n"; fgoto exec_test; }; 30 | *|; 31 | 32 | semi := |* 33 | ';' => { prints "in semi\n"; fgoto main; }; 34 | *|; 35 | 36 | main := |* 37 | [a-z]+ => { prints "word (w/lbh)\n"; fhold; fgoto other; }; 38 | [a-z]+ ' foil' => { prints "word (c/lbh)\n"; }; 39 | [\n ] => { prints "space\n"; }; 40 | '22' => { prints "num (w/switch)\n"; }; 41 | [0-9]+ => { prints "num (w/switch)\n"; fhold; fgoto other;}; 42 | [0-9]+ ' foil' => {prints "num (c/switch)\n"; }; 43 | ';' => { prints "going to semi\n"; fhold; fgoto semi;}; 44 | '!' => { prints "immdiate\n"; fgoto exec_test; }; 45 | *|; 46 | }%% 47 | /* _____INPUT_____ 48 | "abcd foix\n" 49 | "abcd\nanother\n" 50 | "123 foix\n" 51 | "!abcd foix\n" 52 | "!abcd\nanother\n" 53 | "!123 foix\n" 54 | ";" 55 | _____INPUT_____ */ 56 | /* _____OUTPUT_____ 57 | word (w/lbh) 58 | word 59 | space 60 | word 61 | space 62 | ACCEPT 63 | word (w/lbh) 64 | word 65 | space 66 | word 67 | space 68 | ACCEPT 69 | num (w/switch) 70 | num 71 | space 72 | word 73 | space 74 | ACCEPT 75 | immdiate 76 | word (w/lbh) 77 | word 78 | space 79 | word 80 | space 81 | ACCEPT 82 | immdiate 83 | word (w/lbh) 84 | word 85 | space 86 | word 87 | space 88 | ACCEPT 89 | immdiate 90 | num (w/switch) 91 | num 92 | space 93 | word 94 | space 95 | ACCEPT 96 | going to semi 97 | in semi 98 | ACCEPT 99 | _____OUTPUT_____ */ 100 | 101 | -------------------------------------------------------------------------------- /test/range.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | struct range 9 | { 10 | int cs; 11 | }; 12 | 13 | %%{ 14 | machine range; 15 | variable cs fsm->cs; 16 | 17 | main := ( 'a' .. 'c' | 'c' .. 'e' | 'm' .. 'n' | 'a' .. 'z' ) '\n'; 18 | }%% 19 | 20 | %% write data; 21 | 22 | void range_init( struct range *fsm ) 23 | { 24 | %% write init; 25 | } 26 | 27 | void range_execute( struct range *fsm, const char *_data, int _len ) 28 | { 29 | const char *p = _data; 30 | const char *pe = _data+_len; 31 | 32 | %% write exec; 33 | } 34 | 35 | int range_finish( struct range *fsm ) 36 | { 37 | if ( fsm->cs == range_error ) 38 | return -1; 39 | if ( fsm->cs >= range_first_final ) 40 | return 1; 41 | return 0; 42 | } 43 | 44 | struct range fsm; 45 | 46 | void test( char *buf ) 47 | { 48 | int len = strlen( buf ); 49 | range_init( &fsm ); 50 | range_execute( &fsm, buf, len ); 51 | if ( range_finish( &fsm ) > 0 ) 52 | printf("ACCEPT\n"); 53 | else 54 | printf("FAIL\n"); 55 | } 56 | 57 | int main() 58 | { 59 | test( "a\n" ); 60 | test( "z\n" ); 61 | test( "g\n" ); 62 | test( "no\n" ); 63 | test( "1\n" ); 64 | 65 | return 0; 66 | } 67 | 68 | #ifdef _____OUTPUT_____ 69 | ACCEPT 70 | ACCEPT 71 | ACCEPT 72 | FAIL 73 | FAIL 74 | #endif 75 | -------------------------------------------------------------------------------- /test/recdescent1.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | * Test growable stack. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | %%{ 11 | machine recdescent; 12 | 13 | prepush { 14 | if ( top == stack_size ) { 15 | printf( "growing stack\n" ); 16 | stack_size = top * 2; 17 | stack = (int*)realloc( stack, sizeof(int)*stack_size ); 18 | } 19 | } 20 | 21 | postpop { 22 | if ( stack_size > (top * 4) ) { 23 | stack_size = top * 2; 24 | stack = (int*)realloc( stack, sizeof(int)*stack_size ); 25 | printf( "shrinking stack\n" ); 26 | } 27 | } 28 | 29 | action item_start { item = p; } 30 | 31 | action item_finish 32 | { 33 | printf( "item: " ); 34 | fwrite( item, 1, p-item, stdout ); 35 | printf( "\n" ); 36 | } 37 | 38 | action call_main 39 | { 40 | printf( "calling main\n" ); 41 | fcall main; 42 | } 43 | 44 | action return_main 45 | { 46 | if ( top == 0 ) { 47 | printf( "STRAY CLOSE\n" ); 48 | fbreak; 49 | } 50 | 51 | printf( "returning from main\n" ); 52 | fhold; 53 | fret; 54 | } 55 | 56 | id = [a-zA-Z_]+; 57 | number = [0-9]+; 58 | ws = [ \t\n]+; 59 | 60 | main := ( 61 | ws | 62 | ( number | id ) >item_start %item_finish | 63 | 64 | '{' @call_main '}' | 65 | 66 | '}' @return_main 67 | )**; 68 | }%% 69 | 70 | %% write data; 71 | 72 | void test( char *buf ) 73 | { 74 | int cs; 75 | int *stack; 76 | int top, stack_size; 77 | char *p, *pe, *eof, *item = 0; 78 | 79 | int len = strlen( buf ); 80 | 81 | %% write init; 82 | 83 | stack_size = 1; 84 | stack = (int*)malloc( sizeof(int) * stack_size ); 85 | 86 | p = buf; 87 | pe = buf + len; 88 | eof = pe; 89 | 90 | %% write exec; 91 | 92 | if ( cs == recdescent_error ) { 93 | /* Machine failed before finding a token. */ 94 | printf( "PARSE ERROR\n" ); 95 | } 96 | } 97 | 98 | int main() 99 | { 100 | test( "88 foo { 99 {{{{}}}}{ } }"); 101 | test( "76 } sadf"); 102 | return 0; 103 | } 104 | 105 | #ifdef _____OUTPUT_____ 106 | item: 88 107 | item: foo 108 | calling main 109 | item: 99 110 | calling main 111 | growing stack 112 | calling main 113 | growing stack 114 | calling main 115 | calling main 116 | growing stack 117 | returning from main 118 | returning from main 119 | returning from main 120 | returning from main 121 | shrinking stack 122 | calling main 123 | returning from main 124 | returning from main 125 | shrinking stack 126 | item: 76 127 | STRAY CLOSE 128 | #endif 129 | -------------------------------------------------------------------------------- /test/recdescent3.rl: -------------------------------------------------------------------------------- 1 | # 2 | # @LANG: ruby 3 | # 4 | 5 | %%{ 6 | machine recdescent3; 7 | 8 | prepush { 9 | if top == stack_size 10 | print( "growing stack\n" ); 11 | stack_size = top * 2; 12 | # Don't actually bother to resize here, but we do print messages. 13 | # stack = (int*)realloc( stack, sizeof(int)*stack_size ); 14 | end 15 | } 16 | 17 | postpop { 18 | if stack_size > (top * 4) 19 | print( "shrinking stack\n" ); 20 | stack_size = top * 2; 21 | # Don't actually bother to resize here, but we do print messages. 22 | # stack = (int*)realloc( stack, sizeof(int)*stack_size ); 23 | end 24 | } 25 | 26 | action item_start { item = p; } 27 | 28 | action item_finish 29 | { 30 | print( "item: " ); 31 | print( data[item..p-1] ); 32 | print( "\n" ); 33 | } 34 | 35 | action call_main 36 | { 37 | print( "calling main\n" ); 38 | fcall main; 39 | } 40 | 41 | action return_main 42 | { 43 | if top == 0 44 | print( "STRAY CLOSE\n" ); 45 | fbreak; 46 | end 47 | 48 | print( "returning from main\n" ); 49 | fhold; 50 | fret; 51 | } 52 | 53 | id = [a-zA-Z_]+; 54 | number = [0-9]+; 55 | ws = [ \t\n]+; 56 | 57 | main := ( 58 | ws | 59 | ( number | id ) >item_start %item_finish | 60 | 61 | '{' @call_main '}' | 62 | 63 | '}' @return_main 64 | )**; 65 | }%% 66 | 67 | %% write data; 68 | 69 | def run_machine( data ) 70 | item = 0; 71 | p = 0; 72 | pe = data.length; 73 | eof = pe; 74 | cs = 0; 75 | stack = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; 76 | stack_size = 1; 77 | top = 0; 78 | 79 | %% write init; 80 | %% write exec; 81 | 82 | if cs == recdescent3_error 83 | puts "SCANNER_ERROR" 84 | end 85 | end 86 | 87 | inp = [ 88 | "88 foo { 99 {{{{}}}}{ } }", 89 | "76 } sadf" 90 | ] 91 | 92 | inp.each { |str| run_machine(str) } 93 | 94 | =begin _____OUTPUT_____ 95 | item: 88 96 | item: foo 97 | calling main 98 | item: 99 99 | calling main 100 | growing stack 101 | calling main 102 | growing stack 103 | calling main 104 | calling main 105 | growing stack 106 | returning from main 107 | returning from main 108 | returning from main 109 | returning from main 110 | shrinking stack 111 | calling main 112 | returning from main 113 | returning from main 114 | shrinking stack 115 | item: 76 116 | STRAY CLOSE 117 | =end _____OUTPUT_____ 118 | -------------------------------------------------------------------------------- /test/ruby1.rl: -------------------------------------------------------------------------------- 1 | # 2 | # @LANG: ruby 3 | # 4 | # Test the host language scanning for ruby. 5 | # 6 | 7 | # %%{ 8 | a = 1 9 | b = /%%\{\}/; 10 | 11 | %%{ 12 | machine ruby1; 13 | 14 | main := lower+ digit+ '\n' @{ 15 | 16 | # } 17 | c = 1 18 | d = /\}/ 19 | puts "NL" 20 | }; 21 | }%% 22 | 23 | # %%{ 24 | e = 1 25 | f = /%%\{\}/; 26 | 27 | %% write data; 28 | 29 | # %%{ 30 | g = 1 31 | h = /%%\{\}/; 32 | 33 | def run_machine( data ) 34 | p = 0; 35 | pe = data.length 36 | cs = 0 37 | 38 | %% write init; 39 | %% write exec; 40 | if cs >= ruby1_first_final 41 | puts "ACCEPT" 42 | else 43 | puts "FAIL" 44 | end 45 | end 46 | 47 | inp = [ 48 | "abc1231\n", 49 | ] 50 | 51 | inp.each { |str| run_machine(str) } 52 | 53 | =begin _____OUTPUT_____ 54 | NL 55 | ACCEPT 56 | =end _____OUTPUT_____ 57 | -------------------------------------------------------------------------------- /test/scan1.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: indep 3 | */ 4 | ptr ts; 5 | ptr te; 6 | int act; 7 | int token; 8 | %% 9 | %%{ 10 | machine scanner; 11 | 12 | # Warning: changing the patterns or the input string will affect the 13 | # coverage of the scanner action types. 14 | main := |* 15 | 'a' => { 16 | prints "on last "; 17 | if ( p+1 == te ) 18 | prints "yes"; 19 | prints "\n"; 20 | }; 21 | 22 | 'b'+ => { 23 | prints "on next "; 24 | if ( p+1 == te ) 25 | prints "yes"; 26 | prints "\n"; 27 | }; 28 | 29 | 'c1' 'dxxx'? => { 30 | prints "on lag "; 31 | if ( p+1 == te ) 32 | prints "yes"; 33 | prints "\n"; 34 | }; 35 | 36 | 'd1' => { 37 | prints "lm switch1 "; 38 | if ( p+1 == te ) 39 | prints "yes"; 40 | prints "\n"; 41 | }; 42 | 'd2' => { 43 | prints "lm switch2 "; 44 | if ( p+1 == te ) 45 | prints "yes"; 46 | prints "\n"; 47 | }; 48 | 49 | [d0-9]+ '.'; 50 | 51 | '\n'; 52 | *|; 53 | }%% 54 | /* _____INPUT_____ 55 | "abbc1d1d2\n" 56 | _____INPUT_____ */ 57 | /* _____OUTPUT_____ 58 | on last yes 59 | on next yes 60 | on lag yes 61 | lm switch1 yes 62 | lm switch2 yes 63 | ACCEPT 64 | _____OUTPUT_____ */ 65 | -------------------------------------------------------------------------------- /test/scan2.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: indep 3 | */ 4 | ptr ts; 5 | ptr te; 6 | int act; 7 | int token; 8 | %% 9 | %%{ 10 | machine scanner; 11 | 12 | # Warning: changing the patterns or the input string will affect the 13 | # coverage of the scanner action types. 14 | main := |* 15 | 'a' => { 16 | prints "pat1\n"; 17 | }; 18 | 19 | [ab]+ . 'c' => { 20 | prints "pat2\n"; 21 | }; 22 | 23 | any => { 24 | prints "any\n"; 25 | }; 26 | *|; 27 | }%% 28 | /* _____INPUT_____ 29 | "a" 30 | _____INPUT_____ */ 31 | /* _____OUTPUT_____ 32 | pat1 33 | ACCEPT 34 | _____OUTPUT_____ */ 35 | -------------------------------------------------------------------------------- /test/scan3.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: indep 3 | */ 4 | ptr ts; 5 | ptr te; 6 | int act; 7 | int token; 8 | %% 9 | %%{ 10 | machine scanner; 11 | 12 | # Warning: changing the patterns or the input string will affect the 13 | # coverage of the scanner action types. 14 | main := |* 15 | 'a' => { 16 | prints "pat1\n"; 17 | }; 18 | 'b' => { 19 | prints "pat2\n"; 20 | }; 21 | [ab] any* => { 22 | prints "pat3\n"; 23 | }; 24 | *|; 25 | }%% 26 | /* _____INPUT_____ 27 | "ab89" 28 | _____INPUT_____ */ 29 | /* _____OUTPUT_____ 30 | pat3 31 | ACCEPT 32 | _____OUTPUT_____ */ 33 | -------------------------------------------------------------------------------- /test/scan4.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: indep 3 | */ 4 | ptr ts; 5 | ptr te; 6 | int act; 7 | int token; 8 | %% 9 | %%{ 10 | machine scanner; 11 | 12 | # Warning: changing the patterns or the input string will affect the 13 | # coverage of the scanner action types. 14 | main := |* 15 | 'a' => { 16 | prints "pat1\n"; 17 | }; 18 | 19 | [ab]+ . 'c' => { 20 | prints "pat2\n"; 21 | }; 22 | 23 | any; 24 | *|; 25 | }%% 26 | /* _____INPUT_____ 27 | "ba a" 28 | _____INPUT_____ */ 29 | /* _____OUTPUT_____ 30 | pat1 31 | pat1 32 | ACCEPT 33 | _____OUTPUT_____ */ 34 | -------------------------------------------------------------------------------- /test/stateact1.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: indep 3 | * 4 | * Test in and out state actions. 5 | */ 6 | %% 7 | %%{ 8 | machine state_act; 9 | 10 | action a1 { prints "a1\n"; } 11 | action a2 { prints "a2\n"; } 12 | action b1 { prints "b1\n"; } 13 | action b2 { prints "b2\n"; } 14 | action c1 { prints "c1\n"; } 15 | action c2 { prints "c2\n"; } 16 | action next_again {fnext again;} 17 | 18 | hi = 'hi'; 19 | line = again: 20 | hi 21 | >to b1 22 | >from b2 23 | '\n' 24 | >to c1 25 | >from c2 26 | @next_again; 27 | 28 | main := line* 29 | >to a1 30 | >from a2; 31 | }%% 32 | 33 | /* _____INPUT_____ 34 | "hi\nhi\n" 35 | _____INPUT_____ */ 36 | 37 | /* _____OUTPUT_____ 38 | a2 39 | b2 40 | c1 41 | c2 42 | b1 43 | b2 44 | c1 45 | c2 46 | b1 47 | FAIL 48 | _____OUTPUT_____ */ 49 | -------------------------------------------------------------------------------- /test/statechart1.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * @LANG: c 3 | */ 4 | 5 | /* 6 | * Test in and out state actions. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | struct state_chart 13 | { 14 | int cs; 15 | }; 16 | 17 | %%{ 18 | machine state_chart; 19 | variable cs fsm->cs; 20 | 21 | action a { printf("a"); } 22 | action b { printf("b"); } 23 | action hexa { printf("a"); } 24 | action hexb { printf("b"); } 25 | 26 | hex_a = '0x' '0'* '61' @hexa; 27 | hex_b = '0x' '0'* '62' @hexb; 28 | 29 | a = 'a' @a | hex_a; 30 | b = 'b' @b | hex_b; 31 | ws = ' '+; 32 | 33 | mach = 34 | start: ( 35 | a -> st1 | 36 | b -> st2 | 37 | zlen -> final 38 | ), 39 | st1: ( 40 | a -> st1 | 41 | ws -> start | 42 | zlen -> final 43 | ), 44 | st2: ( 45 | b -> st2 | 46 | ws -> start | 47 | zlen -> final 48 | ); 49 | 50 | main := ( mach '\n' )*; 51 | }%% 52 | 53 | %% write data; 54 | 55 | void state_chart_init( struct state_chart *fsm ) 56 | { 57 | %% write init; 58 | } 59 | 60 | void state_chart_execute( struct state_chart *fsm, const char *_data, int _len ) 61 | { 62 | const char *p = _data; 63 | const char *pe = _data+_len; 64 | 65 | %% write exec; 66 | } 67 | 68 | int state_chart_finish( struct state_chart *fsm ) 69 | { 70 | if ( fsm->cs == state_chart_error ) 71 | return -1; 72 | if ( fsm->cs >= state_chart_first_final ) 73 | return 1; 74 | return 0; 75 | } 76 | 77 | struct state_chart sc; 78 | 79 | void test( char *buf ) 80 | { 81 | int len = strlen( buf ); 82 | state_chart_init( &sc ); 83 | state_chart_execute( &sc, buf, len ); 84 | state_chart_finish( &sc ); 85 | printf("\n"); 86 | } 87 | 88 | int main() 89 | { 90 | test( 91 | "aa0x0061aa b\n" 92 | "bbb0x62b 0x61 0x000062\n" 93 | ); 94 | 95 | return 0; 96 | } 97 | 98 | #ifdef _____OUTPUT_____ 99 | aaaaabbbbbbab 100 | #endif 101 | -------------------------------------------------------------------------------- /test/strings2.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRINGS1_H 2 | #define _STRINGS1_H 3 | 4 | struct strs 5 | { 6 | int cs; 7 | }; 8 | 9 | #endif 10 | --------------------------------------------------------------------------------