summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@colm.net>2020-03-16 08:54:20 +0200
committerAdrian Thurston <thurston@colm.net>2020-03-16 08:54:20 +0200
commit0f227e5db320e7b2ec9a69ea19269ec9060091c2 (patch)
tree0af24234cf16185f1021fc26a109b6e124dc1c2a
parentb38131d491567d436516fdababc006074230c034 (diff)
downloadcolm-0f227e5db320e7b2ec9a69ea19269ec9060091c2.tar.gz
removal of some files only belonging in ragel, install libfsm to include/libfsm
-rw-r--r--aapl/Makefile.am2
-rw-r--r--configure.ac15
-rw-r--r--libfsm/Makefile.am4
-rw-r--r--libfsm/buffer.h56
-rw-r--r--libfsm/common.cc130
-rw-r--r--libfsm/inputdata.cc1150
-rw-r--r--libfsm/libragel.h32
-rw-r--r--libfsm/load.h37
-rw-r--r--libfsm/pcheck.h49
-rw-r--r--libfsm/reducer.cc230
-rw-r--r--libfsm/reducer.h120
-rw-r--r--libfsm/rlscan.h136
-rw-r--r--libfsm/xmlparse.kh211
-rw-r--r--libfsm/xmlparse.kl1006
-rw-r--r--libfsm/xmlscan.rl315
-rw-r--r--libfsm/xmltags.gperf95
16 files changed, 16 insertions, 3572 deletions
diff --git a/aapl/Makefile.am b/aapl/Makefile.am
index 00cffba9..b3cd0c94 100644
--- a/aapl/Makefile.am
+++ b/aapl/Makefile.am
@@ -1,5 +1,3 @@
-aaplincludedir = $(includedir)/aapl
-
aaplinclude_HEADERS = \
avlbasic.h avlimel.h avlmap.h bstcommon.h compare.h insertsort.h \
sbstset.h avlcommon.h avlimelkey.h avlmel.h bstmap.h dlcommon.h \
diff --git a/configure.ac b/configure.ac
index 03c429f2..a5de89d5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,7 +50,6 @@ AC_PROG_CXX
AC_CHECK_TOOL(AR, ar)
AC_PROG_RANLIB
AC_PROG_LIBTOOL
-
SED_SUBST=["\
-e 's|@CXX@|${CXX}|g' \
-e 's|@CC@|${CC}|g' \
@@ -59,6 +58,20 @@ SED_SUBST=["\
dnl Set test on c++ compiler.
AC_LANG_CPLUSPLUS
+dnl
+dnl libfsmincludedir
+dnl
+libfsmincludedir='${includedir}/libfsm/'
+AC_SUBST(libfsmincludedir)
+SED_SUBST="$SED_SUBST -e 's|[@]libfsmincludedir[@]|$libfsmincludedir|g'"
+
+dnl
+dnl aaplincludedir
+dnl
+aaplincludedir='${includedir}/aapl/'
+AC_SUBST(aaplincludedir)
+SED_SUBST="$SED_SUBST -e 's|[@]aaplincludedir[@]|$aaplincludedir|g'"
+
dnl Check for definition of MAKE.
AC_PROG_MAKE_SET
diff --git a/libfsm/Makefile.am b/libfsm/Makefile.am
index 5a3761e9..261aa0a4 100644
--- a/libfsm/Makefile.am
+++ b/libfsm/Makefile.am
@@ -4,9 +4,9 @@
# to the ragel language.
lib_LTLIBRARIES = libfsm.la
-pkginclude_HEADERS = \
+libfsminclude_HEADERS = \
action.h fsmgraph.h common.h \
- gendata.h redfsm.h dot.h
+ gendata.h redfsm.h dot.h asm.h ragel.h
# nodist_pkginclude_HEADERS = config.h
diff --git a/libfsm/buffer.h b/libfsm/buffer.h
deleted file mode 100644
index 72bcd5f9..00000000
--- a/libfsm/buffer.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2003-2018 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef _BUFFER_H
-#define _BUFFER_H
-
-#define BUFFER_INITIAL_SIZE 4096
-
-/* An automatically grown buffer for collecting tokens. Always reuses space;
- * never down resizes. */
-struct Buffer
-{
- Buffer()
- {
- data = (char*) malloc( BUFFER_INITIAL_SIZE );
- allocated = BUFFER_INITIAL_SIZE;
- length = 0;
- }
- ~Buffer() { free(data); }
-
- void append( char p )
- {
- if ( length == allocated ) {
- allocated *= 2;
- data = (char*) realloc( data, allocated );
- }
- data[length++] = p;
- }
-
- void clear() { length = 0; }
-
- char *data;
- int allocated;
- int length;
-};
-
-#endif
diff --git a/libfsm/common.cc b/libfsm/common.cc
index 6e0f5c0c..9ebbd905 100644
--- a/libfsm/common.cc
+++ b/libfsm/common.cc
@@ -20,7 +20,6 @@
* SOFTWARE.
*/
-#include "pcheck.h"
#include "common.h"
#include "stdlib.h"
#include <string.h>
@@ -139,135 +138,6 @@ HostType *findAlphTypeInternal( const HostLang *hostLang, const char *s1 )
return 0;
}
-/* Construct a new parameter checker with for paramSpec. */
-ParamCheck::ParamCheck( const char *paramSpec, int argc, const char **argv )
-:
- state(noparam),
- argOffset(0),
- curArg(0),
- iCurArg(1),
- paramSpec(paramSpec),
- argc(argc),
- argv(argv)
-{
-}
-
-/* Check a single option. Returns the index of the next parameter. Sets p to
- * the arg character if valid, 0 otherwise. Sets parg to the parameter arg if
- * there is one, NULL otherwise. */
-bool ParamCheck::check()
-{
- bool requiresParam;
-
- if ( iCurArg >= argc ) { /* Off the end of the arg list. */
- state = noparam;
- return false;
- }
-
- if ( argOffset != 0 && *argOffset == 0 ) {
- /* We are at the end of an arg string. */
- iCurArg += 1;
- if ( iCurArg >= argc ) {
- state = noparam;
- return false;
- }
- argOffset = 0;
- }
-
- if ( argOffset == 0 ) {
- /* Set the current arg. */
- curArg = argv[iCurArg];
-
- /* We are at the beginning of an arg string. */
- if ( argv[iCurArg] == 0 || /* Argv[iCurArg] is null. */
- argv[iCurArg][0] != '-' || /* Not a param. */
- argv[iCurArg][1] == 0 ) { /* Only a dash. */
- parameter = 0;
- paramArg = 0;
-
- iCurArg += 1;
- state = noparam;
- return true;
- }
- argOffset = argv[iCurArg] + 1;
- }
-
- /* Get the arg char. */
- char argChar = *argOffset;
-
- /* Loop over all the parms and look for a match. */
- const char *pSpec = paramSpec;
- while ( *pSpec != 0 ) {
- char pSpecChar = *pSpec;
-
- /* If there is a ':' following the char then
- * it requires a parm. If a parm is required
- * then move ahead two in the parmspec. Otherwise
- * move ahead one in the parm spec. */
- if ( pSpec[1] == ':' ) {
- requiresParam = true;
- pSpec += 2;
- }
- else {
- requiresParam = false;
- pSpec += 1;
- }
-
- /* Do we have a match. */
- if ( argChar == pSpecChar ) {
- if ( requiresParam ) {
- if ( argOffset[1] == 0 ) {
- /* The param must follow. */
- if ( iCurArg + 1 == argc ) {
- /* We are the last arg so there
- * cannot be a parameter to it. */
- parameter = argChar;
- paramArg = 0;
- iCurArg += 1;
- argOffset = 0;
- state = invalid;
- return true;
- }
- else {
- /* the parameter to the arg is the next arg. */
- parameter = pSpecChar;
- paramArg = argv[iCurArg + 1];
- iCurArg += 2;
- argOffset = 0;
- state = match;
- return true;
- }
- }
- else {
- /* The param for the arg is built in. */
- parameter = pSpecChar;
- paramArg = argOffset + 1;
- iCurArg += 1;
- argOffset = 0;
- state = match;
- return true;
- }
- }
- else {
- /* Good, we matched the parm and no
- * arg is required. */
- parameter = pSpecChar;
- paramArg = 0;
- argOffset += 1;
- state = match;
- return true;
- }
- }
- }
-
- /* We did not find a match. Bad Argument. */
- parameter = argChar;
- paramArg = 0;
- argOffset += 1;
- state = invalid;
- return true;
-}
-
std::streamsize output_filter::countAndWrite( const char *s, std::streamsize n )
{
for ( int i = 0; i < n; i++ ) {
diff --git a/libfsm/inputdata.cc b/libfsm/inputdata.cc
deleted file mode 100644
index 66ec4afb..00000000
--- a/libfsm/inputdata.cc
+++ /dev/null
@@ -1,1150 +0,0 @@
-/*
- * Copyright 2008-2018 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "ragel.h"
-#include "common.h"
-#include "inputdata.h"
-#include "parsedata.h"
-#include "load.h"
-#include "rlscan.h"
-#include "reducer.h"
-#include "version.h"
-#include "pcheck.h"
-#include <colm/colm.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <iostream>
-#include <iomanip>
-#include <fstream>
-#include <unistd.h>
-#include <sstream>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#if defined(HAVE_SYS_WAIT_H)
-#include <sys/wait.h>
-#endif
-
-#ifdef _WIN32
-#include <windows.h>
-#include <psapi.h>
-#include <time.h>
-#include <io.h>
-#include <process.h>
-
-#if _MSC_VER
-#define S_IRUSR _S_IREAD
-#define S_IWUSR _S_IWRITE
-#endif
-#endif
-
-using std::istream;
-using std::ifstream;
-using std::ofstream;
-using std::stringstream;
-using std::ostream;
-using std::endl;
-using std::ios;
-
-InputData::~InputData()
-{
- inputItems.empty();
- parseDataList.empty();
- sectionList.empty();
-
- for ( Vector<const char**>::Iter fns = streamFileNames; fns.lte(); fns++ ) {
- const char **ptr = *fns;
- while ( *ptr != 0 ) {
- ::free( (void*)*ptr );
- ptr += 1;
- }
- free( (void*) *fns );
- }
-
- if ( outputFileName != 0 )
- delete[] outputFileName;
-
- if ( histogramFn != 0 )
- ::free( (void*)histogramFn );
-
- if ( histogram != 0 )
- delete[] histogram;
-
- for ( ArgsVector::Iter bl = breadthLabels; bl.lte(); bl++ )
- free( (void*) *bl );
-}
-
-void InputData::makeDefaultFileName()
-{
- if ( outputFileName == 0 )
- outputFileName = (hostLang->defaultOutFn)( inputFileName );
-}
-
-bool InputData::isBreadthLabel( const string &label )
-{
- for ( ArgsVector::Iter bl = breadthLabels; bl.lte(); bl++ ) {
- if ( label == *bl )
- return true;
- }
- return false;
-}
-
-void InputData::createOutputStream()
-{
- /* Make sure we are not writing to the same file as the input file. */
- if ( outputFileName != 0 ) {
- if ( strcmp( inputFileName, outputFileName ) == 0 ) {
- error() << "output file \"" << outputFileName <<
- "\" is the same as the input file" << endl;
- }
-
- /* Create the filter on the output and open it. */
- outFilter = new output_filter( outputFileName );
-
- /* Open the output stream, attaching it to the filter. */
- outStream = new ostream( outFilter );
- }
- else {
- /* Writing out to std out. */
- outStream = &std::cout;
- }
-}
-
-void InputData::openOutput()
-{
- if ( outFilter != 0 ) {
- outFilter->open( outputFileName, ios::out|ios::trunc );
- if ( !outFilter->is_open() ) {
- error() << "error opening " << outputFileName << " for writing" << endl;
- abortCompile( 1 );
- }
- }
-}
-
-void InputData::prepareSingleMachine()
-{
- ParseData *pd = 0;
- GraphDictEl *gdEl = 0;
-
- /* Locate a machine spec to generate dot output for. We can only emit.
- * Dot takes one graph at a time. */
- if ( machineSpec != 0 ) {
- /* Machine specified. */
- ParseDataDictEl *pdEl = parseDataDict.find( machineSpec );
- if ( pdEl == 0 )
- error() << "could not locate machine specified with -S and/or -M" << endp;
- pd = pdEl->value;
- }
- else {
- /* No machine spec given, generate the first one. */
- if ( parseDataList.length() == 0 )
- error() << "no machine specification to generate graphviz output" << endp;
-
- pd = parseDataList.head;
- }
-
- if ( machineName != 0 ) {
- gdEl = pd->graphDict.find( machineName );
- if ( gdEl == 0 )
- error() << "machine definition/instantiation not found" << endp;
- }
- else {
- /* We are using the whole machine spec. Need to make sure there
- * are instances in the spec. */
- if ( pd->instanceList.length() == 0 )
- error() << "no machine instantiations to generate graphviz output" << endp;
- }
-
- pd->prepareMachineGen( gdEl, hostLang );
- dotGenPd = pd;
-}
-
-void InputData::prepareAllMachines()
-{
- for ( ParseDataDict::Iter pdel = parseDataDict; pdel.lte(); pdel++ ) {
- ParseData *pd = pdel->value;
- if ( pd->instanceList.length() > 0 ) {
- pd->prepareMachineGen( 0, hostLang );
-
- pd->makeExports();
- }
-
- }
-}
-
-void InputData::generateReduced()
-{
- for ( ParseDataDict::Iter pdel = parseDataDict; pdel.lte(); pdel++ ) {
- ParseData *pd = pdel->value;
- if ( pd->instanceList.length() > 0 )
- pd->generateReduced( inputFileName, codeStyle, *outStream, hostLang );
- }
-}
-
-void InputData::verifyWriteHasData( InputItem *ii )
-{
- if ( ii->type == InputItem::Write ) {
- if ( ii->pd->cgd == 0 )
- error( ii->loc ) << ii->pd->sectionName << ": no machine instantiations to write" << endl;
- }
-}
-
-void InputData::verifyWritesHaveData()
-{
- for ( InputItemList::Iter ii = inputItems; ii.lte(); ii++ )
- verifyWriteHasData( ii );
-}
-
-void InputData::writeOutput( InputItem *ii )
-{
- /* If it is the first input item then check if we need to write the BOM. */
- if ( ii->prev == 0 && utf8BomPresent )
- *outStream << (uchar)0xEF << (uchar)0xBB << (uchar) 0xBF;
-
- switch ( ii->type ) {
- case InputItem::Write: {
- CodeGenData *cgd = ii->pd->cgd;
- cgd->writeStatement( ii->loc, ii->writeArgs.size(),
- ii->writeArgs, generateDot, hostLang );
- break;
- }
- case InputItem::HostData: {
- switch ( hostLang->backend ) {
- case Direct:
- if ( ii->loc.fileName != 0 ) {
- if ( ii->prev != 0 )
- *outStream << "\n";
- (*hostLang->genLineDirective)( *outStream, !noLineDirectives, ii->loc.line, ii->loc.fileName );
- }
-
- *outStream << ii->data.str();
- break;
- case Translated:
- openHostBlock( '@', this, *outStream, inputFileName, ii->loc.line );
- translatedHostData( *outStream, ii->data.str() );
- *outStream << "}@";
- break;
- }
- break;
- }
- case InputItem::EndSection: {
- break;
- }
- }
-}
-
-void InputData::closeOutput()
-{
- /* If writing to a file, delete the ostream, causing it to flush.
- * Standard out is flushed automatically. */
- if ( outputFileName != 0 ) {
- delete outStream;
- delete outFilter;
- }
-}
-
-void InputData::processDot()
-{
- /* Compiles the DOT machines. */
- prepareSingleMachine();
-
- if ( errorCount > 0 )
- abortCompile( 1 );
-
- createOutputStream();
-
- if ( errorCount > 0 )
- abortCompile( 1 );
-
- /*
- * From this point on we should not be reporting any errors.
- */
-
- openOutput();
- writeDot( *outStream );
- closeOutput();
-}
-
-bool InputData::checkLastRef( InputItem *ii )
-{
- if ( generateDot )
- return true;
-
- if ( errorCount > 0 )
- return false;
-
- /*
- * 1. Go forward to next last reference.
- * 2. Fully process that machine, mark as processed.
- * 3. Move forward through input items until no longer
- */
- if ( ii->section != 0 && ii->section->lastReference == ii ) {
- /* Fully Process. */
- ParseData *pd = ii->pd;
-
- if ( pd->instanceList.length() > 0 ) {
-#ifdef WITH_RAGEL_KELBT
- if ( ii->parser != 0 )
- ii->parser->terminateParser();
-#endif
-
- FsmRes res = pd->prepareMachineGen( 0, hostLang );
-
- /* Compute exports from the export definitions. */
- pd->makeExports();
-
- if ( !res.success() )
- return false;
-
- if ( errorCount > 0 )
- return false;
-
- pd->generateReduced( inputFileName, codeStyle, *outStream, hostLang );
-
- if ( errorCount > 0 )
- return false;
- }
-
- /* Mark all input items referencing the machine as processed. */
- InputItem *toMark = lastFlush;
- while ( true ) {
- toMark->processed = true;
-
- if ( toMark == ii )
- break;
-
- toMark = toMark->next;
- }
-
- /* Move forward, flushing input items until we get to an unprocessed
- * input item. */
- while ( lastFlush != 0 && lastFlush->processed ) {
- verifyWriteHasData( lastFlush );
-
- if ( errorCount > 0 )
- return false;
-
- /* Flush out. */
- writeOutput( lastFlush );
-
- lastFlush = lastFlush->next;
- }
- }
- return true;
-}
-
-void InputData::makeFirstInputItem()
-{
- /* Make the first input item. */
- InputItem *firstInputItem = new InputItem;
- firstInputItem->type = InputItem::HostData;
- firstInputItem->loc.fileName = inputFileName;
- firstInputItem->loc.line = 1;
- firstInputItem->loc.col = 1;
- inputItems.append( firstInputItem );
-}
-
-/* Send eof to all parsers. */
-void InputData::terminateAllParsers( )
-{
-#ifdef WITH_RAGEL_KELBT
- for ( ParserDict::Iter pdel = parserDict; pdel.lte(); pdel++ )
- pdel->value->terminateParser();
-#endif
-}
-
-void InputData::flushRemaining()
-{
- InputItem *item = inputItems.head;
-
- while ( item != 0 ) {
- checkLastRef( item );
- item = item->next;
- }
-
- /* Flush remaining items. */
- while ( lastFlush != 0 ) {
- /* Flush out. */
- writeOutput( lastFlush );
-
- lastFlush = lastFlush->next;
- }
-}
-
-void InputData::makeTranslateOutputFileName()
-{
- origOutputFileName = outputFileName;
- outputFileName = fileNameFromStem( outputFileName, ".ri" );
- genOutputFileName = outputFileName;
-}
-
-#ifdef WITH_RAGEL_KELBT
-void InputData::parseKelbt()
-{
- /*
- * Ragel Parser from ragel 6.
- */
- ifstream *inFileStream;
- istream *inStream;
-
- /* Open the input file for reading. */
- assert( inputFileName != 0 );
- inFileStream = new ifstream( inputFileName );
- if ( ! inFileStream->is_open() )
- error() << "could not open " << inputFileName << " for reading" << endp;
- inStream = inFileStream;
-
- makeFirstInputItem();
-
- Scanner scanner( this, inputFileName, *inStream, 0, 0, 0, false );
-
- scanner.sectionPass = true;
- scanner.do_scan();
-
- inStream->clear();
- inStream->seekg( 0, std::ios::beg );
- curItem = inputItems.head;
- lastFlush = inputItems.head;
-
- scanner.sectionPass = false;
- scanner.do_scan();
-
- /* Finished, final check for errors.. */
- if ( errorCount > 0 )
- abortCompile( 1 );
-
- /* Bail on above error. */
- if ( errorCount > 0 )
- abortCompile( 1 );
-
- delete inFileStream;
-}
-
-void InputData::processKelbt()
-{
- /* With the kelbt version we implement two parse passes. The first is used
- * to identify the last time that any given machine is referenced by a
- * ragel section. In the second pass we parse, compile, and emit as far
- * forward as possible when we encounter the last reference to a machine.
- * */
-
- if ( generateDot ) {
- parseKelbt();
- terminateAllParsers();
- processDot();
- }
- else {
- createOutputStream();
- openOutput();
- parseKelbt();
- flushRemaining();
- closeOutput();
- }
-
- assert( errorCount == 0 );
-}
-#endif
-
-bool InputData::parseReduce()
-{
- /*
- * Colm-based reduction parser introduced in ragel 7.
- */
-
- TopLevel *topLevel = new TopLevel( frontendSections, this, hostLang,
- minimizeLevel, minimizeOpt );
-
- /* Check input file. File is actually opened by colm code. We don't
- * need to perform the check if in libragel since it comes in via a
- * string. */
- if ( input == 0 ) {
- ifstream *inFile = new ifstream( inputFileName );
- if ( ! inFile->is_open() )
- error() << "could not open " << inputFileName << " for reading" << endp;
- delete inFile;
- }
-
- if ( errorCount )
- return false;
-
- makeFirstInputItem();
-
- curItem = inputItems.head;
- lastFlush = inputItems.head;
-
-
- topLevel->reduceFile( "rlparse", inputFileName );
-
- if ( errorCount )
- return false;
-
- bool success = topLevel->success;
-
- delete topLevel;
- return success;
-}
-
-bool InputData::processReduce()
-{
- if ( generateDot ) {
- parseReduce();
- processDot();
- return true;
- }
- else {
- createOutputStream();
- openOutput();
-
- bool success = parseReduce();
- if ( success )
- flushRemaining();
-
- closeOutput();
-
- if ( !success && outputFileName != 0 )
- unlink( outputFileName );
-
- return success;
- }
-}
-
-bool InputData::process()
-{
- switch ( frontend ) {
- case KelbtBased: {
-#ifdef WITH_RAGEL_KELBT
- processKelbt();
-#endif
- return true;
- }
- case ReduceBased: {
- return processReduce();
- }
- }
- return false;
-}
-
-/* Print a summary of the options. */
-void InputData::usage()
-{
- info() <<
-"usage: ragel [options] file\n"
-"general:\n"
-" -h, -H, -?, --help Print this usage and exit\n"
-" -v, --version Print version information and exit\n"
-" -o <file> Write output to <file>\n"
-" -s Print some statistics and compilation info to stderr\n"
-" -d Do not remove duplicates from action lists\n"
-" -I <dir> Add <dir> to the list of directories to search\n"
-" for included an imported files\n"
-" --rlhc Show the rlhc command used to compile\n"
-" --save-temps Do not delete intermediate file during compilation\n"
-" --no-intermediate Disable call to rlhc, leave behind intermediate\n"
-"error reporting format:\n"
-" --error-format=gnu file:line:column: message (default)\n"
-" --error-format=msvc file(line,column): message\n"
-"fsm minimization:\n"
-" -n Do not perform minimization\n"
-" -m Minimize at the end of the compilation\n"
-" -l Minimize after most operations (default)\n"
-" -e Minimize after every operation\n"
-"visualization:\n"
-" -V Generate a dot file for Graphviz\n"
-" -p Display printable characters on labels\n"
-" -S <spec> FSM specification to output (for graphviz output)\n"
-" -M <machine> Machine definition/instantiation to output (for\n"
-" graphviz output)\n"
-"host language:\n"
-" -C C, C++, Obj-C or Obj-C++ (default)\n"
-" All code styles supported.\n"
-" --asm --gas-x86-64-sys-v\n"
-" GNU AS, x86_64, System V ABI.\n"
-" Generated in a code style equivalent to -G2\n"
-" -D D All code styles supported\n"
-" -Z Go All code styles supported\n"
-" -A C# -T0 -T1 -F0 -F1 -G0 -G1\n"
-" -J Java -T0 -T1 -F0 -F1\n"
-" -R Ruby -T0 -T1 -F0 -F1\n"
-" -O OCaml -T0 -T1 -F0 -F1\n"
-" -U Rust -T0 -T1 -F0 -F1\n"
-" -Y Julia -T0 -T1 -F0 -F1\n"
-" -K Crack -T0 -T1 -F0 -F1\n"
-" -P JavaScript -T0 -T1 -F0 -F1\n"
-"line directives:\n"
-" -L Inhibit writing of #line directives\n"
-"code style:\n"
-" -T0 Binary search (default)\n"
-" -T1 Binary search with expanded actions \n"
-" -F0 Flat table\n"
-" -F1 Flat table with expanded actions\n"
-" -G0 Switch-driven\n"
-" -G1 Switch-driven with expanded actions\n"
-" -G2 Goto-driven with expanded actions\n"
-"large machines:\n"
-" --integral-tables Use integers for table data (default)\n"
-" --string-tables Encode table data into strings for faster host lang\n"
-" compilation\n"
-"analysis:\n"
-" --prior-interaction Search for condition-based general repetitions\n"
-" that will not function properly due to state mod\n"
-" overlap and must be NFA reps. \n"
-" --conds-depth=D Search for high-cost conditions inside a prefix\n"
-" of the machine (depth D from start state).\n"
-" --state-limit=L Report fail if number of states exceeds this\n"
-" during compilation.\n"
-" --breadth-check=E1,E2,.. Report breadth cost of named entry points and\n"
-" the start state.\n"
-" --input-histogram=FN Input char histogram for breadth check. If\n"
-" unspecified a flat histogram is used.\n"
-"testing:\n"
-" --kelbt-frontend Compile using original ragel + kelbt frontend\n"
-" Requires ragel be built with ragel + kelbt support\n"
-" --colm-frontend Compile using a colm-based recursive descent\n"
-" frontend\n"
-" --reduce-frontend Compile using a colm-based reducer (default)\n"
-" --var-backend Use the variable-based backend even if the host lang\n"
-" supports goto-based\n"
-" --supported-host-langs Show supported host languages by command line arg\n"
-" --supported-frontends Show supported frontends\n"
-" --supported-backends Show supported backends\n"
-" --force-libragel Cause mainline to behave like libragel\n"
- ;
-
- abortCompile( 0 );
-}
-
-/* Print version information and exit. */
-void InputData::version()
-{
- info() << "Ragel State Machine Compiler version " RAGEL_VERSION << " " RAGEL_PUBDATE << endl <<
- "Copyright (c) 2001-2019 by Adrian Thurston et al." << endl;
- abortCompile( 0 );
-}
-
-void InputData::showFrontends()
-{
- ostream &out = info();
- out << "--colm-frontend";
- out << " --reduce-frontend";
-#ifdef WITH_RAGEL_KELBT
- out << " --kelbt-frontend";
-#endif
- out << endl;
- abortCompile( 0 );
-}
-
-void InputData::showBackends()
-{
- info() <<
- "--direct-backend --colm-backend" << endl;
- abortCompile( 0 );
-}
-
-InputLoc makeInputLoc( const char *fileName, int line, int col )
-{
- InputLoc loc( fileName, line, col );
- return loc;
-}
-
-void escapeLineDirectivePath( std::ostream &out, char *path )
-{
- for ( char *pc = path; *pc != 0; pc++ ) {
- if ( *pc == '\\' )
- out << "\\\\";
- else
- out << *pc;
- }
-}
-
-void InputData::parseArgs( int argc, const char **argv )
-{
- ParamCheck pc( "o:dnmleabjkS:M:I:vHh?-:sT:F:W:G:LpV", argc, argv );
-
- /* Decide if we were invoked using a path variable, or with an explicit path. */
- const char *lastSlash = strrchr( argv[0], '/' );
- if ( lastSlash == 0 ) {
- /* Defualt to the the binary install location. */
- dirName = BINDIR;
- }
- else {
- /* Compute dirName from argv0. */
- dirName = string( argv[0], lastSlash - argv[0] );
- }
-
- /* FIXME: Need to check code styles VS langauge. */
-
- while ( pc.check() ) {
- switch ( pc.state ) {
- case ParamCheck::match:
- switch ( pc.parameter ) {
- case 'V':
- generateDot = true;
- break;
-
- /* Output. */
- case 'o':
- if ( *pc.paramArg == 0 )
- error() << "a zero length output file name was given" << endl;
- else if ( outputFileName != 0 )
- error() << "more than one output file name was given" << endl;
- else {
- /* Ok, remember the output file name. */
- outputFileName = new char[strlen(pc.paramArg)+1];
- strcpy( (char*)outputFileName, pc.paramArg );
- }
- break;
-
- /* Flag for turning off duplicate action removal. */
- case 'd':
- wantDupsRemoved = false;
- break;
-
- /* Minimization, mostly hidden options. */
- case 'n':
- minimizeOpt = MinimizeNone;
- break;
- case 'm':
- minimizeOpt = MinimizeEnd;
- break;
- case 'l':
- minimizeOpt = MinimizeMostOps;
- break;
- case 'e':
- minimizeOpt = MinimizeEveryOp;
- break;
- case 'a':
- #ifdef TO_UPGRADE_CONDS
- minimizeLevel = MinimizeApprox;
- #else
- error() << "minimize approx (-a) unsupported in this version" << endp;
- #endif
- break;
- case 'b':
- #ifdef TO_UPGRADE_CONDS
- minimizeLevel = MinimizeStable;
- #else
- error() << "minimize stable (-b) unsupported in this version" << endp;
- #endif
- break;
- case 'j':
- minimizeLevel = MinimizePartition1;
- break;
- case 'k':
- minimizeLevel = MinimizePartition2;
- break;
-
- /* Machine spec. */
- case 'S':
- if ( *pc.paramArg == 0 )
- error() << "please specify an argument to -S" << endl;
- else if ( machineSpec != 0 )
- error() << "more than one -S argument was given" << endl;
- else {
- /* Ok, remember the path to the machine to generate. */
- machineSpec = pc.paramArg;
- }
- break;
-
- /* Machine path. */
- case 'M':
- if ( *pc.paramArg == 0 )
- error() << "please specify an argument to -M" << endl;
- else if ( machineName != 0 )
- error() << "more than one -M argument was given" << endl;
- else {
- /* Ok, remember the machine name to generate. */
- machineName = pc.paramArg;
- }
- break;
-
- case 'I':
- if ( *pc.paramArg == 0 )
- error() << "please specify an argument to -I" << endl;
- else {
- includePaths.append( pc.paramArg );
- }
- break;
-
- /* Version and help. */
- case 'v':
- version();
- break;
- case 'H': case 'h': case '?':
- usage();
- break;
- case 's':
- printStatistics = true;
- break;
- case '-': {
- char *arg = strdup( pc.paramArg );
- char *eq = strchr( arg, '=' );
-
- if ( eq != 0 )
- *eq++ = 0;
-
- if ( strcmp( arg, "help" ) == 0 )
- usage();
- else if ( strcmp( arg, "version" ) == 0 )
- version();
- else if ( strcmp( arg, "error-format" ) == 0 ) {
- if ( eq == 0 )
- error() << "expecting '=value' for error-format" << endl;
- else if ( strcmp( eq, "gnu" ) == 0 )
- errorFormat = ErrorFormatGNU;
- else if ( strcmp( eq, "msvc" ) == 0 )
- errorFormat = ErrorFormatMSVC;
- else
- error() << "invalid value for error-format" << endl;
- }
- else if ( strcmp( arg, "rlhc" ) == 0 )
- rlhc = true;
- else if ( strcmp( arg, "no-intermediate" ) == 0 )
- noIntermediate = true;
-#ifdef WITH_RAGEL_KELBT
- else if ( strcmp( arg, "kelbt-frontend" ) == 0 ) {
- frontend = KelbtBased;
- frontendSpecified = true;
- }
-#else
- else if ( strcmp( arg, "kelbt-frontend" ) == 0 ) {
- error() << "--kelbt-frontend specified but, "
- "ragel not built with ragel+kelbt support" << endp;
- }
-#endif
- else if ( strcmp( arg, "reduce-frontend" ) == 0 ) {
- frontend = ReduceBased;
- frontendSpecified = true;
- }
- else if ( strcmp( arg, "string-tables" ) == 0 )
- stringTables = true;
- else if ( strcmp( arg, "integral-tables" ) == 0 )
- stringTables = false;
- else if ( strcmp( arg, "supported-frontends" ) == 0 )
- showFrontends();
- else if ( strcmp( arg, "supported-backends" ) == 0 )
- showBackends();
- else if ( strcmp( arg, "save-temps" ) == 0 )
- saveTemps = true;
-
- else if ( strcmp( arg, "prior-interaction" ) == 0 )
- checkPriorInteraction = true;
- else if ( strcmp( arg, "conds-depth" ) == 0 )
- condsCheckDepth = strtol( eq, 0, 10 );
- else if ( strcmp( arg, "state-limit" ) == 0 )
- stateLimit = strtol( eq, 0, 10 );
-
- else if ( strcmp( arg, "breadth-check" ) == 0 ) {
- char *ptr = 0;
- while ( true ) {
- char *label = strtok_r( eq, ",", &ptr );
- eq = NULL;
- if ( label == NULL )
- break;
- breadthLabels.append( strdup( label ) );
- }
- checkBreadth = true;
- }
- else if ( strcmp( arg, "input-histogram" ) == 0 )
- histogramFn = strdup(eq);
- else if ( strcmp( arg, "var-backend" ) == 0 )
- forceVar = true;
- else if ( strcmp( arg, "no-fork" ) == 0 )
- noFork = true;
- else {
- error() << "--" << pc.paramArg <<
- " is an invalid argument" << endl;
- }
- free( arg );
- break;
- }
-
- /* Passthrough args. */
- case 'T':
- if ( pc.paramArg[0] == '0' )
- codeStyle = GenBinaryLoop;
- else if ( pc.paramArg[0] == '1' )
- codeStyle = GenBinaryExp;
- else {
- error() << "-T" << pc.paramArg[0] <<
- " is an invalid argument" << endl;
- abortCompile( 1 );
- }
- break;
- case 'F':
- if ( pc.paramArg[0] == '0' )
- codeStyle = GenFlatLoop;
- else if ( pc.paramArg[0] == '1' )
- codeStyle = GenFlatExp;
- else {
- error() << "-F" << pc.paramArg[0] <<
- " is an invalid argument" << endl;
- abortCompile( 1 );
- }
- break;
- case 'G':
- if ( pc.paramArg[0] == '0' )
- codeStyle = GenGotoLoop;
- else if ( pc.paramArg[0] == '1' )
- codeStyle = GenGotoExp;
- else if ( pc.paramArg[0] == '2' )
- codeStyle = GenIpGoto;
- else if ( pc.paramArg[0] == 'T' && pc.paramArg[1] == '2' ) {
- codeStyle = GenIpGoto;
- maxTransitions = 32;
- } else {
- error() << "-G" << pc.paramArg[0] <<
- " is an invalid argument" << endl;
- abortCompile( 1 );
- }
- break;
- case 'W':
- if ( pc.paramArg[0] == '0' )
- codeStyle = GenSwitchLoop;
- else if ( pc.paramArg[0] == '1' )
- codeStyle = GenSwitchExp;
- else {
- error() << "-G" << pc.paramArg[0] <<
- " is an invalid argument" << endl;
- abortCompile( 1 );
- }
- break;
-
- case 'p':
- displayPrintables = true;
- break;
-
- case 'L':
- noLineDirectives = true;
- break;
- }
- break;
-
- case ParamCheck::invalid:
- error() << "-" << pc.parameter << " is an invalid argument" << endl;
- break;
-
- case ParamCheck::noparam:
- /* It is interpreted as an input file. */
- if ( *pc.curArg == 0 )
- error() << "a zero length input file name was given" << endl;
- else if ( inputFileName != 0 )
- error() << "more than one input file name was given" << endl;
- else {
- /* OK, Remember the filename. */
- inputFileName = pc.curArg;
- }
- break;
- }
- }
-}
-
-void InputData::loadHistogram()
-{
- const int alphsize = 256;
-
- /* Init a default. */
- histogram = new double[alphsize];
- ifstream h( histogramFn );
- if ( !h.is_open() )
- error() << "histogram read: failed to open file: " << histogramFn << endp;
-
- int i = 0;
- double value;
- while ( true ) {
- if ( h >> value ) {
- if ( i >= alphsize ) {
- /* Too many items. */
- error() << "histogram read: too many histogram values,"
- " expecting " << alphsize << " (for char alphabet)" << endp;
- }
- histogram[i] = value;
- i++;
- }
- else {
- /* Read failure. */
- if ( h.eof() ) {
- if ( i < alphsize ) {
- error() << "histogram read: fell short of " <<
- alphsize << " items" << endp;
- }
- break;
- }
- else {
- error() << "histogram read: error at item " << i << endp;
- }
- }
- }
-}
-
-void InputData::defaultHistogram()
-{
- /* Flat histogram. */
- const int alphsize = 256;
- histogram = new double[alphsize];
- for ( int i = 0; i < alphsize; i++ ) {
- histogram[i] = 1.0 / (double)alphsize;
- }
-}
-
-void InputData::checkArgs()
-{
- /* Require an input file. If we use standard in then we won't have a file
- * name on which to base the output. */
- if ( inputFileName == 0 )
- error() << "no input file given" << endl;
-
- /* Bail on argument processing errors. */
- if ( errorCount > 0 )
- abortCompile( 1 );
-
- /* Make sure we are not writing to the same file as the input file. */
- if ( inputFileName != 0 && outputFileName != 0 &&
- strcmp( inputFileName, outputFileName ) == 0 )
- {
- error() << "output file \"" << outputFileName <<
- "\" is the same as the input file" << endp;
- }
-
- if ( !frontendSpecified )
- frontend = ReduceBased;
-
- if ( checkBreadth ) {
- if ( histogramFn != 0 )
- loadHistogram();
- else
- defaultHistogram();
- }
-}
-
-char *InputData::readInput( const char *inputFileName )
-{
- struct stat st;
- int res = stat( inputFileName, &st );
- if ( res != 0 ) {
- error() << inputFileName << ": stat failed: " << strerror(errno) << endl;
- return 0;
- }
-
- std::ifstream in( inputFileName );
- if ( !in.is_open() ) {
- error() << inputFileName << ": could not open in force-libragel mode";
- return 0;
- }
-
- char *input = new char[st.st_size+1];
- in.read( input, st.st_size );
- if ( in.gcount() != st.st_size ) {
- error() << inputFileName << ": could not read in force-libragel mode";
- delete[] input;
- return 0;
- }
- input[st.st_size] = 0;
-
- return input;
-}
-
-int InputData::main( int argc, const char **argv )
-{
- int code = 0;
- try {
- parseArgs( argc, argv );
- checkArgs();
- if ( !generateDot )
- makeDefaultFileName();
-
- if ( !process() )
- abortCompile( 1 );
- }
- catch ( const AbortCompile &ac ) {
- code = ac.code;
- }
-
- return code;
-}
-
-int InputData::runFrontend( int argc, const char **argv )
-{
- if ( !process() )
- return -1;
- return 0;
-}
-
-int InputData::runRlhc( int argc, const char **argv )
-{
- struct colm_program *prg;
- int exit_status;
-
- prg = colm_new_program( rlhcSections );
- colm_set_debug( prg, 0 );
- colm_run_program( prg, argc, argv );
- exit_status = colm_delete_program( prg );
- return exit_status;
-}
-
-/* Run a job (frontend or backend). If we want forks then we return the result
- * via the process's exit code. otherwise it comes back on the stack. */
-int InputData::runJob( const char *what, IdProcess idProcess, int argc, const char **argv )
-{
-#if defined(HAVE_SYS_WAIT_H)
- if ( !noFork ) {
- pid_t pid = fork();
-
- if ( pid == 0 ) {
- int es = (this->*idProcess)( argc, argv );
- exit( es );
- }
-
- int status = 0;
- waitpid( pid, &status, 0 );
- if ( WIFSIGNALED(status) ) {
- error() << what << " stopped by signal: " << WTERMSIG(status) << std::endl;
- return -1;
- }
-
- return WEXITSTATUS( status );
- }
-#endif
- return (this->*idProcess)( argc, argv );
-}
-
-int InputData::rlhcMain( int argc, const char **argv )
-{
- parseArgs( argc, argv );
- checkArgs();
- makeDefaultFileName();
- makeTranslateOutputFileName();
-
- int es = runJob( "frontend", &InputData::runFrontend, 0, 0 );
-
- if ( es != 0 )
- return es;
-
- /* rlhc <input> <output> */
- const char *_argv[] = { "rlhc",
- genOutputFileName.c_str(),
- origOutputFileName.c_str(), 0 };
-
- return runJob( "rlhc", &InputData::runRlhc, 3, _argv );
-}
diff --git a/libfsm/libragel.h b/libfsm/libragel.h
deleted file mode 100644
index ad328e86..00000000
--- a/libfsm/libragel.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2016-2018 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef _LIBRAGEL_H
-#define _LIBRAGEL_H
-
-#ifdef __cplusplus
-#define EXTERN_C extern "C"
-#else
-#define EXTERN_C
-#endif
-
-#endif
diff --git a/libfsm/load.h b/libfsm/load.h
deleted file mode 100644
index 6ef7d57c..00000000
--- a/libfsm/load.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2013-2018 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef _LOAD_H
-#define _LOAD_H
-
-#include "ragel.h"
-
-struct LoadRagel;
-struct InputData;
-struct HostLang;
-
-LoadRagel *newLoadRagel( InputData &id, const HostLang *hostLang,
- MinimizeLevel minimizeLevel, MinimizeOpt minimizeOpt );
-void loadRagel( LoadRagel *lr, const char *inputFileName );
-void deleteLoadRagel( LoadRagel * );
-
-#endif
diff --git a/libfsm/pcheck.h b/libfsm/pcheck.h
deleted file mode 100644
index adc011b3..00000000
--- a/libfsm/pcheck.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2001-2018 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef _PCHECK_H
-#define _PCHECK_H
-
-class ParamCheck
-{
-public:
- ParamCheck( const char *paramSpec, int argc, const char **argv);
-
- bool check();
-
- const char *paramArg; /* The argument to the parameter. */
- char parameter; /* The parameter matched. */
- enum { match, invalid, noparam } state;
-
- const char *argOffset; /* If we are reading params inside an
- * arg this points to the offset. */
-
- const char *curArg; /* Pointer to the current arg. */
- int iCurArg; /* Index to the current arg. */
-
-private:
- const char *paramSpec; /* Parameter spec supplied by the coder. */
- int argc; /* Arguement data from the command line. */
- const char **argv;
-};
-
-#endif
diff --git a/libfsm/reducer.cc b/libfsm/reducer.cc
deleted file mode 100644
index 592dcfe1..00000000
--- a/libfsm/reducer.cc
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright 2015-2018 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "reducer.h"
-
-#include <colm/colm.h>
-#include <colm/tree.h>
-
-#include <errno.h>
-
-using std::endl;
-using std::ifstream;
-
-void TopLevel::loadMachineName( string data )
-{
- /* Make/get the priority key. The name may have already been referenced
- * and therefore exist. */
- PriorDictEl *priorDictEl;
- if ( pd->priorDict.insert( data, pd->fsmCtx->nextPriorKey, &priorDictEl ) )
- pd->fsmCtx->nextPriorKey += 1;
- pd->curDefPriorKey = priorDictEl->value;
-
- /* Make/get the local error key. */
- LocalErrDictEl *localErrDictEl;
- if ( pd->localErrDict.insert( data, pd->nextLocalErrKey, &localErrDictEl ) )
- pd->nextLocalErrKey += 1;
- pd->curDefLocalErrKey = localErrDictEl->value;
-}
-
-void TopLevel::tryMachineDef( const InputLoc &loc, std::string name,
- MachineDef *machineDef, bool isInstance )
-{
- GraphDictEl *newEl = pd->graphDict.insert( name );
- if ( newEl != 0 ) {
- /* New element in the dict, all good. */
- newEl->value = new VarDef( name, machineDef );
- newEl->isInstance = isInstance;
- newEl->loc = loc;
- newEl->value->isExport = exportContext[exportContext.length()-1];
-
- /* It it is an instance, put on the instance list. */
- if ( isInstance )
- pd->instanceList.append( newEl );
- }
- else {
- // Recover by ignoring the duplicate.
- pd->id->error(loc) << "fsm \"" << name << "\" previously defined" << endl;
- }
-}
-
-long TopLevel::tryLongScan( const InputLoc &loc, const char *data )
-{
- /* Convert the priority number to a long. Check for overflow. */
- long priorityNum;
- errno = 0;
-
- long aug = strtol( data, 0, 10 );
- if ( errno == ERANGE && aug == LONG_MAX ) {
- /* Priority number too large. Recover by setting the priority to 0. */
- pd->id->error(loc) << "priority number " << data <<
- " overflows" << endl;
- priorityNum = 0;
- }
- else if ( errno == ERANGE && aug == LONG_MIN ) {
- /* Priority number too large in the neg. Recover by using 0. */
- pd->id->error(loc) << "priority number " << data <<
- " underflows" << endl;
- priorityNum = 0;
- }
- else {
- /* No overflow or underflow. */
- priorityNum = aug;
- }
-
- return priorityNum;
-}
-
-void TopLevel::include( const InputLoc &incLoc, bool fileSpecified, string fileName, string machine )
-{
- /* Stash the current section name and pd. */
- string sectionName = pd->sectionName;
- ParseData *pd0 = pd;
-
- const char **includeChecks = 0;
- long found = 0;
-
- const char *inclSectionName = machine.c_str();
-
- /* Default the section name to the current section name. */
- if ( inclSectionName == 0 )
- inclSectionName = sectionName.c_str();
-
- /* Build the include checks. */
- if ( fileSpecified )
- includeChecks = pd->id->makeIncludePathChecks( curFileName, fileName.c_str() );
- else {
- char *test = new char[strlen(curFileName)+1];
- strcpy( test, curFileName );
-
- includeChecks = new const char*[2];
-
- includeChecks[0] = test;
- includeChecks[1] = 0;
- }
-
- /* Try to find the file. */
- ifstream *inFile = pd->id->tryOpenInclude( includeChecks, found );
- if ( inFile == 0 ) {
- id->error(incLoc) << "include: failed to locate file" << endl;
- const char **tried = includeChecks;
- while ( *tried != 0 )
- id->error(incLoc) << "include: attempted: \"" << *tried++ << '\"' << endl;
-
- return;
- }
-
- delete inFile;
-
-// /* Don't include anything that's already been included. */
-// if ( !pd->duplicateInclude( includeChecks[found], inclSectionName ) ) {
-// pd->includeHistory.push_back( IncludeHistoryItem(
-// includeChecks[found], inclSectionName ) );
-//
-// /* Either we are not in the lib, or a file was specifed, use the
-// * file-based include pass. */
-// includePass.reduceFile( includeChecks[found], id->hostLang );
-// }
-
- const char *targetMachine0 = targetMachine;
- const char *searchMachine0 = searchMachine;
-
- includeDepth += 1;
- pd = 0;
-
- targetMachine = sectionName.c_str();
- searchMachine = machine.c_str();
-
- // reduceFile( includeChecks[found] );
-
-// if ( includePass.incItems.length() == 0 ) {
-// pd->id->error(incLoc) << "could not find machine " << machine <<
-// " in " << fileName << endp;
-// }
-// else {
-// /* Load the data into include el. Save in the dict. */
-// loadIncludeData( el, includePass, includeChecks[found] );
-// id->includeDict.insert( el );
-// includePass.incItems.empty();
-// }
-
- pd = pd0;
- includeDepth -= 1;
-
- targetMachine = targetMachine0;
- searchMachine = searchMachine0;
-}
-
-void TopLevel::import( const InputLoc &loc, std::string name, Literal *literal )
-{
- MachineDef *machineDef = new MachineDef(
- new Join(
- new Expression(
- new Term(
- new FactorWithAug(
- new FactorWithRep(
- new FactorWithNeg( new Factor( literal ) )
- )
- )
- )
- )
- )
- );
-
- /* Generic creation of machine for instantiation and assignment. */
- tryMachineDef( loc, name, machineDef, false );
- machineDef->join->loc = loc;
-}
-
-void TopLevel::reduceFile( const char *cmd, const char *inputFileName )
-{
- const int baseN = 2;
- const char **argv = new const char*[baseN + id->includePaths.length() + 1];
- argv[0] = cmd;
- argv[1] = inputFileName;
- for ( int i = 0; i < id->includePaths.length(); i++ )
- argv[baseN + i] = id->includePaths.data[i];
- argv[baseN + id->includePaths.length()] = 0;
-
- const char *prevCurFileName = curFileName;
- curFileName = inputFileName;
-
- colm_program *program = colm_new_program( frontendSections );
- colm_set_debug( program, 0 );
- colm_set_reduce_clean( program, 0 );
- colm_set_reduce_ctx( program, this );
- colm_run_program( program, baseN + id->includePaths.length(), argv );
- id->streamFileNames.append( colm_extract_fns( program ) );
-
- int length = 0;
- const char *err = colm_error( program, &length );
- if ( err != 0 ) {
- // std::cout << "error" << std::endl;
- id->error_plain() << string( err, length ) << std::endl;
- }
-
- colm_delete_program( program );
-
- curFileName = prevCurFileName;
-
- delete[] argv;
-}
diff --git a/libfsm/reducer.h b/libfsm/reducer.h
deleted file mode 100644
index 0d0f1af1..00000000
--- a/libfsm/reducer.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2001-2018 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <colm/pdarun.h>
-#include <colm/bytecode.h>
-#include <colm/defs.h>
-#include <colm/input.h>
-#include <colm/tree.h>
-#include <colm/program.h>
-#include <colm/colm.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include <iostream>
-#include <vector>
-#include <string>
-
-#include "vector.h"
-#include "inputdata.h"
-#include "parsedata.h"
-
-#ifndef _REDUCER_H
-#define _REDUCER_H
-
-char *unescape( const char *s, int slen );
-char *unescape( const char *s );
-
-struct SectionPass;
-
-struct TopLevel
-{
- TopLevel( struct colm_sections *frontendSections, InputData *id, const HostLang *hostLang,
- MinimizeLevel minimizeLevel, MinimizeOpt minimizeOpt )
- :
- frontendSections(frontendSections),
- id(id),
- section(0),
- pd(0),
- machineSpec(0),
- machineName(0),
- includeDepth(0),
- hostLang(hostLang),
- minimizeLevel(minimizeLevel),
- minimizeOpt(minimizeOpt),
-
- /* Should be passed into the load, somehow. */
- targetMachine(0),
- searchMachine(0),
- paramList(0),
- success(true),
- isImport(false)
- {
- exportContext.append( false );
- }
-
- struct colm_sections *frontendSections;
- InputData *id;
- Section *section;
- SectionPass *sectionPass;
- ParseData *pd;
- char *machineSpec;
- char *machineName;
- int includeDepth;
- const HostLang *hostLang;
- MinimizeLevel minimizeLevel;
- MinimizeOpt minimizeOpt;
- std::vector<std::string> writeArgs;
-
- /* Should this go in the parse data? Probably. */
- Vector<bool> exportContext;
-
- const char *curFileName;
-
- const char *targetMachine;
- const char *searchMachine;
-
- ActionParamList *paramList;
- bool success;
-
- /* Generated and called by colm. */
- void commit_reduce_forward( program_t *prg, tree_t **root,
- struct pda_run *pda_run, parse_tree_t *pt );
- void read_reduce_forward( program_t *prg, FILE *file );
-
- void loadMachineName( string data );
- void tryMachineDef( const InputLoc &loc, std::string name,
- MachineDef *machineDef, bool isInstance );
- long tryLongScan( const InputLoc &loc, const char *data );
- void include( const InputLoc &incLoc, bool fileSpecified, string fileName, string machine );
- void reduceFile( const char *cmd, const char *inputFileName );
-
- void import( const InputLoc &loc, std::string name, Literal *literal );
- void importFile( std::string fileName );
-
- bool isImport;
-};
-
-#endif
diff --git a/libfsm/rlscan.h b/libfsm/rlscan.h
deleted file mode 100644
index e8b4047d..00000000
--- a/libfsm/rlscan.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 2007-2018 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef _RLSCAN_H
-#define _RLSCAN_H
-
-#include <iostream>
-#include "rlscan.h"
-#include "vector.h"
-#ifdef WITH_RAGEL_KELBT
-#include "rlparse.h"
-#endif
-#include "parsedata.h"
-#include "avltree.h"
-#include "vector.h"
-
-using std::istream;
-using std::ostream;
-
-extern char *Parser6_lelNames[];
-struct Section;
-
-struct Scanner
-{
- Scanner( InputData *id, const char *fileName, istream &input,
- Parser6 *inclToParser, char *inclSectionTarg,
- int includeDepth, bool importMachines )
- :
- id(id), fileName(fileName),
- input(input),
- inclToParser(inclToParser),
- inclSectionTarg(inclSectionTarg),
- includeDepth(includeDepth),
- importMachines(importMachines),
- cur_token(0),
- line(1), column(1), lastnl(0),
- parser(0), ignoreSection(false),
- parserExistsError(false),
- whitespaceOn(true),
- lastToken(0),
- section(0),
- sectionPass(false)
- {}
-
- void handleMachine();
- void handleInclude();
- void handleImport();
-
- void init();
- void token( int type, char *start, char *end );
- void token( int type, char c );
- void token( int type );
- void processToken( int type, char *tokdata, int toklen );
- void directToParser( Parser6 *toParser, const char *tokFileName, int tokLine,
- int tokColumn, int type, char *tokdata, int toklen );
- void flushImport( );
- void importToken( int type, char *start, char *end );
- void pass( int token, char *start, char *end );
- void pass();
- void updateCol();
- void startSection();
- void endSection();
- void do_scan();
- bool active();
- InputLoc scan_loc();
-
- InputData *id;
- const char *fileName;
- istream &input;
- Parser6 *inclToParser;
- char *inclSectionTarg;
- int includeDepth;
- bool importMachines;
-
- /* For import parsing. */
- int tok_cs, tok_act;
- int *tok_ts, *tok_te;
- int cur_token;
- static const int max_tokens = 32;
- int token_data[max_tokens];
- char *token_strings[max_tokens];
- int token_lens[max_tokens];
-
- /* For section processing. */
- int cs;
- char *word, *lit;
- int word_len, lit_len;
-
- /* For character scanning. */
- int line;
- InputLoc sectionLoc;
- char *ts, *te;
- int column;
- char *lastnl;
-
- /* Set by machine statements, these persist from section to section
- * allowing for unnamed sections. */
- Parser6 *parser;
- bool ignoreSection;
-
- /* This is set if ragel has already emitted an error stating that
- * no section name has been seen and thus no parser exists. */
- bool parserExistsError;
-
- /* This is for inline code. By default it is on. It goes off for
- * statements and values in inline blocks which are parsed. */
- bool whitespaceOn;
-
- /* Keeps a record of the previous token sent to the section parser. */
- int lastToken;
-
- Section *section;
- bool sectionPass;
-
-};
-
-#endif
diff --git a/libfsm/xmlparse.kh b/libfsm/xmlparse.kh
deleted file mode 100644
index 1b0b30ad..00000000
--- a/libfsm/xmlparse.kh
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright 2001-2007 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef _XMLPARSE_H
-#define _XMLPARSE_H
-
-#include "vector.h"
-#include "gendata.h"
-#include "buffer.h"
-#include <iostream>
-
-using std::istream;
-using std::ostream;
-
-#define XML_BUFSIZE 4096
-
-struct AttrMarker
-{
- char *id;
- int idLen;
- char *value;
- int valueLen;
-};
-
-struct Attribute
-{
- char *id;
- char *value;
-};
-
-typedef Vector<AttrMarker> AttrMkList;
-typedef Vector<Attribute> AttrList;
-struct XMLTagHashPair;
-
-struct XMLTag
-{
- enum TagType { Open, Close };
-
- XMLTag( XMLTagHashPair *tagId, TagType type ) :
- tagId(tagId), type(type),
- content(0), attrList(0) {}
-
- Attribute *findAttr( const char *id )
- {
- if ( attrList != 0 ) {
- for ( AttrList::Iter attr = *attrList; attr.lte(); attr++ ) {
- if ( strcmp( id, attr->id ) == 0 )
- return attr;
- }
- }
- return 0;
- }
-
- XMLTagHashPair *tagId;
- TagType type;
-
- /* Content is associtated with closing tags. */
- char *content;
-
- /* Attribute lists are associated with opening tags. */
- AttrList *attrList;
-};
-
-
-struct XMLTagHashPair
-{
- const char *name;
- int id;
-};
-
-struct Token;
-
-struct GenInlineItem;
-struct GenInlineList;
-
-struct LmSwitchVect;
-struct LmSwitchAction;
-
-struct XmlScanner
-{
- XmlScanner( const char *fileName, istream &input );
-
- int scan();
- void adjustAttrPointers( int distance );
- std::ostream &error();
-
- const char *fileName;
- istream &input;
-
- /* Scanner State. */
- int cs, act, have, curline, curcol;
- char *ts, *te;
- char *p, *pe;
- int done;
-
- /* Token data */
- char *data;
- int data_len;
- int value;
- AttrMkList attrMkList;
- Buffer buffer;
- char *tag_id_start;
- int tag_id_len;
- int token_col, token_line;
-
- char buf[XML_BUFSIZE];
-};
-
-
-struct XmlParser
-{
- %%{
- parser XmlParser;
-
- token TAG_unknown, TAG_ragel, TAG_ragel_def, TAG_host, TAG_state_list,
- TAG_state, TAG_trans_list, TAG_t, TAG_machine, TAG_start_state,
- TAG_error_state, TAG_action_list, TAG_action_table_list,
- TAG_action, TAG_action_table, TAG_alphtype, TAG_element,
- TAG_getkey, TAG_state_actions, TAG_entry_points, TAG_sub_action,
- TAG_cond_space_list, TAG_cond_space, TAG_cond_list, TAG_c,
- TAG_exports, TAG_ex;
-
- # Inline block tokens.
- token TAG_text, TAG_goto, TAG_call, TAG_next, TAG_goto_expr,
- TAG_call_expr, TAG_next_expr, TAG_ret, TAG_pchar, TAG_char,
- TAG_hold, TAG_exec, TAG_curs, TAG_targs, TAG_entry, TAG_data,
- TAG_lm_switch, TAG_init_act, TAG_set_act, TAG_set_tokend,
- TAG_get_tokend, TAG_init_tokstart, TAG_set_tokstart;
-
- token TAG_write, TAG_access, TAG_break, TAG_arg, TAG_cs_expr;
-
- token TAG_p_expr, TAG_pe_expr, TAG_eof_expr, TAG_cs_expr, TAG_top_expr,
- TAG_stack_expr, TAG_act_expr, TAG_tokstart_expr, TAG_tokend_expr,
- TAG_data_expr, TAG_prepush, TAG_postpop, TAG_eof_t;
- }%%
-
- %% write instance_data;
-
- void init();
- int parseLangEl( int type, const Token *token );
-
- XmlParser( const char *sourceFileName, const char *xmlFileName, bool outputActive, bool wantComplete ) :
- sourceFileName(sourceFileName),
- fileName(xmlFileName),
- outStream(0),
- outputActive(outputActive),
- wantComplete(wantComplete),
- cgd(0) { }
-
- int token( int tokenId, Token &token );
- int token( int tokenId, int col, int line );
- int token( XMLTag *tag, int col, int line );
-
- void openOutput();
-
- /* Report an error encountered by the parser. */
- ostream &warning( const InputLoc &loc );
- ostream &error();
- ostream &error( const InputLoc &loc );
- ostream &parser_error( int tokId, Token &token );
- ostream &source_error( const InputLoc &loc );
-
- /* The name of the root section, this does not change during an include. */
- const char *sourceFileName;
- const char *fileName;
- ostream *outStream;
- bool outputActive;
- bool wantComplete;
-
- /* Collected during parsing. */
- char *attrKey;
- char *attrValue;
- int curAction;
- int curActionTable;
- int curTrans;
- int curState;
- int curCondSpace;
- int curStateCond;
-
- CodeGenData *cgd;
- CodeGenMap codeGenMap;
-
- Vector <char*> writeOptions;
-};
-
-%% write token_defs;
-
-int xml_parse( std::istream &input, const char *fileName,
- bool outputActive, bool wantComplete,
- XmlScanner &scanner, XmlParser &parser );
-
-#endif
diff --git a/libfsm/xmlparse.kl b/libfsm/xmlparse.kl
deleted file mode 100644
index 04d95b83..00000000
--- a/libfsm/xmlparse.kl
+++ /dev/null
@@ -1,1006 +0,0 @@
-/*
- * Copyright 2001-2007 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "xmlparse.h"
-#include "common.h"
-#include "gendata.h"
-#include "version.h"
-#include <iostream>
-#include <stdlib.h>
-
-using std::ostream;
-using std::istream;
-using std::cerr;
-using std::endl;
-
-Key readKey( char *td, char **end );
-long readOffsetPtr( char *td, char **end );
-unsigned long readLength( char *td );
-
-struct Token
-{
- XMLTag *tag;
- InputLoc loc;
-};
-
-%%{
-
-parser XmlParser;
-
-include "xmlparse.kh";
-
-start: tag_ragel;
-start:
- final {
- /* If we get no input the assumption is that the frontend died and
- * emitted an error. This forces the backend to return a non-zero
- * exit status, but does not print an error. */
- gblErrorCount += 1;
- };
-
-tag_ragel: tag_ragel_head ragel_def_list host_or_write_list '/' TAG_ragel;
-
-tag_ragel_head: TAG_ragel
- final {
- /* Check version used to generated the intermediate file. */
- Attribute *versionAttr = $1->tag->findAttr( "version" );
- if ( versionAttr == 0 )
- error($1->loc) << "tag <ragel> requires a version attribute" << endp;
- if ( strcmp( versionAttr->value, VERSION ) != 0 )
- error($1->loc) << "version mismatch between frontend and backend" << endp;
-
- /* Check for file name attribute. */
- Attribute *fileNameAttr = $1->tag->findAttr( "filename" );
- if ( fileNameAttr == 0 )
- error($1->loc) << "tag <ragel> requires a filename attribute" << endp;
- sourceFileName = fileNameAttr->value;
-
- /* Check for language attribute. */
- Attribute *langAttr = $1->tag->findAttr( "lang" );
- if ( langAttr == 0 )
- error($1->loc) << "tag <ragel> requires a lang attribute" << endp;
-
- if ( generateDot )
- outStream = dotOpenOutput( sourceFileName );
- else if ( strcmp( langAttr->value, "C" ) == 0 ) {
- hostLang = &hostLangC;
- outStream = cdOpenOutput( sourceFileName );
- }
- else if ( strcmp( langAttr->value, "D" ) == 0 ) {
- hostLang = &hostLangD;
- outStream = cdOpenOutput( sourceFileName );
- }
- else if ( strcmp( langAttr->value, "Java" ) == 0 ) {
- hostLang = &hostLangJava;
- outStream = javaOpenOutput( sourceFileName );
- }
- else if ( strcmp( langAttr->value, "Ruby" ) == 0 ) {
- hostLang = &hostLangRuby;
- outStream = rubyOpenOutput( sourceFileName );
- }
- else if ( strcmp( langAttr->value, "C#" ) == 0 ) {
- hostLang = &hostLangCSharp;
- outStream = csharpOpenOutput( sourceFileName );
- }
- else {
- error($1->loc) << "expecting lang attribute to be "
- "one of C, D, Java, Ruby or C#" << endp;
- }
- };
-
-ragel_def_list: ragel_def_list ragel_def;
-ragel_def_list: ;
-
-host_or_write_list: host_or_write_list host_or_write;
-host_or_write_list: ;
-
-host_or_write: tag_host;
-host_or_write: tag_write;
-
-tag_host:
- TAG_host '/' TAG_host
- final {
- Attribute *lineAttr = $1->tag->findAttr( "line" );
- if ( lineAttr == 0 )
- error($1->loc) << "tag <host> requires a line attribute" << endp;
- else {
- int line = atoi( lineAttr->value );
- if ( outputActive )
- lineDirective( *outStream, sourceFileName, line );
- }
-
- if ( outputActive )
- *outStream << $3->tag->content;
- };
-
-ragel_def:
- tag_ragel_def_head ragel_def_item_list '/' TAG_ragel_def
- final {
- /* Do this before distributing transitions out to singles and defaults
- * makes life easier. */
- cgd->redFsm->maxKey = cgd->findMaxKey();
-
- cgd->redFsm->assignActionLocs();
-
- /* Find the first final state (The final state with the lowest id). */
- cgd->redFsm->findFirstFinState();
-
- /* Call the user's callback. */
- cgd->finishRagelDef();
- };
-
-tag_ragel_def_head: TAG_ragel_def
- final {
- char *fsmName = 0;
- Attribute *nameAttr = $1->tag->findAttr( "name" );
- if ( nameAttr != 0 ) {
- fsmName = nameAttr->value;
-
- CodeGenMapEl *mapEl = codeGenMap.find( fsmName );
- if ( mapEl != 0 )
- cgd = mapEl->value;
- else {
- cgd = makeCodeGen( sourceFileName, fsmName, *outStream, wantComplete );
- codeGenMap.insert( fsmName, cgd );
- }
- }
- else {
- cgd = makeCodeGen( sourceFileName, fsmName,
- *outStream, wantComplete );
- }
-
- ::keyOps = &cgd->thisKeyOps;
- };
-
-ragel_def_item_list: ragel_def_item_list ragel_def_item;
-ragel_def_item_list: ;
-
-ragel_def_item: tag_alph_type;
-ragel_def_item: tag_getkey_expr;
-ragel_def_item: tag_access_expr;
-ragel_def_item: tag_prepush_expr;
-ragel_def_item: tag_postpop_expr;
-ragel_def_item: tag_export_list;
-ragel_def_item: tag_machine;
-ragel_def_item: tag_p_expr;
-ragel_def_item: tag_pe_expr;
-ragel_def_item: tag_eof_expr;
-ragel_def_item: tag_cs_expr;
-ragel_def_item: tag_top_expr;
-ragel_def_item: tag_stack_expr;
-ragel_def_item: tag_act_expr;
-ragel_def_item: tag_tokstart_expr;
-ragel_def_item: tag_tokend_expr;
-ragel_def_item: tag_data_expr;
-
-tag_export_list: TAG_exports export_list '/' TAG_exports;
-
-export_list: export_list tag_export;
-export_list: ;
-
-tag_export: TAG_ex '/' TAG_ex
- final {
- Attribute *nameAttr = $1->tag->findAttr( "name" );
- if ( nameAttr == 0 )
- error($1->loc) << "tag <ex> requires a name attribute" << endp;
- else {
- char *td = $3->tag->content;
- Key exportKey = readKey( td, &td );
- cgd->exportList.append( new Export( nameAttr->value, exportKey ) );
- }
- };
-
-tag_alph_type: TAG_alphtype '/' TAG_alphtype
- final {
- if ( ! cgd->setAlphType( $3->tag->content ) )
- error($1->loc) << "tag <alphtype> specifies unknown alphabet type" << endp;
- };
-
-tag_getkey_expr: TAG_getkey inline_list '/' TAG_getkey
- final {
- cgd->getKeyExpr = $2->inlineList;
- };
-
-tag_access_expr: TAG_access inline_list '/' TAG_access
- final {
- cgd->accessExpr = $2->inlineList;
- };
-
-tag_prepush_expr: TAG_prepush inline_list '/' TAG_prepush
- final {
- cgd->prePushExpr = $2->inlineList;
- };
-
-tag_postpop_expr: TAG_postpop inline_list '/' TAG_postpop
- final {
- cgd->postPopExpr = $2->inlineList;
- };
-
-tag_p_expr: TAG_p_expr inline_list '/' TAG_p_expr
- final { cgd->pExpr = $2->inlineList; };
-tag_pe_expr: TAG_pe_expr inline_list '/' TAG_pe_expr
- final { cgd->peExpr = $2->inlineList; };
-tag_eof_expr: TAG_eof_expr inline_list '/' TAG_eof_expr
- final { cgd->eofExpr = $2->inlineList; };
-tag_cs_expr: TAG_cs_expr inline_list '/' TAG_cs_expr
- final { cgd->csExpr = $2->inlineList; };
-tag_top_expr: TAG_top_expr inline_list '/' TAG_top_expr
- final { cgd->topExpr = $2->inlineList; };
-tag_stack_expr: TAG_stack_expr inline_list '/' TAG_stack_expr
- final { cgd->stackExpr = $2->inlineList; };
-tag_act_expr: TAG_act_expr inline_list '/' TAG_act_expr
- final { cgd->actExpr = $2->inlineList; };
-tag_tokstart_expr: TAG_tokstart_expr inline_list '/' TAG_tokstart_expr
- final { cgd->tokstartExpr = $2->inlineList; };
-tag_tokend_expr: TAG_tokend_expr inline_list '/' TAG_tokend_expr
- final { cgd->tokendExpr = $2->inlineList; };
-tag_data_expr: TAG_data_expr inline_list '/' TAG_data_expr
- final { cgd->dataExpr = $2->inlineList; };
-
-
-tag_write: tag_write_head write_option_list '/' TAG_write
- final {
- /* Terminate the options list and call the write statement handler. */
- writeOptions.append(0);
- cgd->writeStatement( $1->loc, writeOptions.length()-1, writeOptions.data );
-
- /* Clear the options in prep for the next write statement. */
- writeOptions.empty();
- };
-
-nonterm tag_write_head
-{
- InputLoc loc;
-};
-
-tag_write_head: TAG_write
- final {
- Attribute *nameAttr = $1->tag->findAttr( "def_name" );
- Attribute *lineAttr = $1->tag->findAttr( "line" );
- Attribute *colAttr = $1->tag->findAttr( "col" );
-
- if ( nameAttr == 0 )
- error($1->loc) << "tag <write> requires a def_name attribute" << endp;
- if ( lineAttr == 0 )
- error($1->loc) << "tag <write> requires a line attribute" << endp;
- if ( colAttr == 0 )
- error($1->loc) << "tag <write> requires a col attribute" << endp;
-
- if ( nameAttr != 0 && lineAttr != 0 && colAttr != 0 ) {
- $$->loc.line = atoi(lineAttr->value);
- $$->loc.col = atoi(colAttr->value);
-
- CodeGenMapEl *mapEl = codeGenMap.find( nameAttr->value );
- if ( mapEl == 0 ) {
- source_error($$->loc) << "write statement given "
- "but there are no machine instantiations" << endp;
- }
- else {
- cgd = mapEl->value;
- ::keyOps = &cgd->thisKeyOps;
- }
- }
- };
-
-
-write_option_list: write_option_list tag_arg;
-write_option_list: ;
-
-nonterm tag_arg
-{
- char *option;
-};
-
-tag_arg: TAG_arg '/' TAG_arg
- final {
- writeOptions.append( $3->tag->content );
- };
-
-tag_machine: tag_machine_head machine_item_list '/' TAG_machine
- final {
- cgd->closeMachine();
- };
-
-tag_machine_head: TAG_machine
- final {
- cgd->createMachine();
- };
-
-machine_item_list: machine_item_list machine_item;
-machine_item_list: ;
-
-machine_item: tag_start_state;
-machine_item: tag_error_state;
-machine_item: tag_entry_points;
-machine_item: tag_state_list;
-machine_item: tag_action_list;
-machine_item: tag_action_table_list;
-machine_item: tag_cond_space_list;
-
-#
-# States.
-#
-
-tag_start_state: TAG_start_state '/' TAG_start_state
- final {
- unsigned long startState = strtoul( $3->tag->content, 0, 10 );
- cgd->setStartState( startState );
- };
-
-tag_error_state: TAG_error_state '/' TAG_error_state
- final {
- unsigned long errorState = strtoul( $3->tag->content, 0, 10 );
- cgd->setErrorState( errorState );
- };
-
-tag_entry_points: TAG_entry_points entry_point_list '/' TAG_entry_points
- final {
- Attribute *errorAttr = $1->tag->findAttr( "error" );
- if ( errorAttr != 0 )
- cgd->setForcedErrorState();
- };
-
-entry_point_list: entry_point_list tag_entry;
-entry_point_list: ;
-
-tag_entry: TAG_entry '/' TAG_entry
- final {
- Attribute *nameAttr = $1->tag->findAttr( "name" );
- if ( nameAttr == 0 ) {
- error($1->loc) << "tag <entry_points>::<entry> "
- "requires a name attribute" << endp;
- }
- else {
- char *data = $3->tag->content;
- unsigned long entry = strtoul( data, &data, 10 );
- cgd->addEntryPoint( nameAttr->value, entry );
- }
- };
-
-tag_state_list: tag_state_list_head state_list '/' TAG_state_list;
-
-tag_state_list_head: TAG_state_list
- final {
- Attribute *lengthAttr = $1->tag->findAttr( "length" );
- if ( lengthAttr == 0 )
- error($1->loc) << "tag <state_list> requires a length attribute" << endp;
- else {
- unsigned long length = strtoul( lengthAttr->value, 0, 10 );
- cgd->initStateList( length );
- curState = 0;
- }
- };
-
-state_list: state_list tag_state;
-state_list: ;
-
-tag_state: TAG_state state_item_list '/' TAG_state
- final {
- Attribute *idAttr = $1->tag->findAttr( "id" );
- if ( idAttr == 0 )
- error($1->loc) << "tag <state> requires an id attribute" << endp;
- else {
- int id = atoi( idAttr->value );
- cgd->setId( curState, id );
- }
-
- Attribute *lengthAttr = $1->tag->findAttr( "final" );
- if ( lengthAttr != 0 )
- cgd->setFinal( curState );
- curState += 1;
- };
-
-state_item_list: state_item_list state_item;
-state_item_list: ;
-
-state_item: tag_state_actions;
-state_item: tag_eof_t;
-state_item: tag_state_cond_list;
-state_item: tag_trans_list;
-
-tag_state_actions: TAG_state_actions '/' TAG_state_actions
- final {
- char *ad = $3->tag->content;
-
- long toStateAction = readOffsetPtr( ad, &ad );
- long fromStateAction = readOffsetPtr( ad, &ad );
- long eofAction = readOffsetPtr( ad, &ad );
-
- cgd->setStateActions( curState, toStateAction,
- fromStateAction, eofAction );
- };
-
-tag_eof_t: TAG_eof_t '/' TAG_eof_t
- final {
- char *et = $3->tag->content;
- long targ = readOffsetPtr( et, &et );
- long eofAction = readOffsetPtr( et, &et );
-
- cgd->setEofTrans( curState, targ, eofAction );
- };
-
-tag_state_cond_list: tag_state_cond_list_head state_cond_list '/' TAG_cond_list;
-
-tag_state_cond_list_head: TAG_cond_list
- final {
- Attribute *lengthAttr = $1->tag->findAttr( "length" );
- if ( lengthAttr == 0 )
- error($1->loc) << "tag <cond_list> requires a length attribute" << endp;
- else {
- ulong length = readLength( lengthAttr->value );
- cgd->initStateCondList( curState, length );
- curStateCond = 0;
- }
- };
-
-state_cond_list: state_cond_list state_cond;
-state_cond_list: ;
-
-state_cond: TAG_c '/' TAG_c
- final {
- char *td = $3->tag->content;
- Key lowKey = readKey( td, &td );
- Key highKey = readKey( td, &td );
- long condId = readOffsetPtr( td, &td );
- cgd->addStateCond( curState, lowKey, highKey, condId );
- };
-
-tag_trans_list: tag_trans_list_head trans_list '/' TAG_trans_list
- final {
- cgd->finishTransList( curState );
- };
-
-tag_trans_list_head: TAG_trans_list
- final {
- Attribute *lengthAttr = $1->tag->findAttr( "length" );
- if ( lengthAttr == 0 )
- error($1->loc) << "tag <trans_list> requires a length attribute" << endp;
- else {
- unsigned long length = strtoul( lengthAttr->value, 0, 10 );
- cgd->initTransList( curState, length );
- curTrans = 0;
- }
- };
-
-trans_list: trans_list tag_trans;
-trans_list: ;
-
-tag_trans: TAG_t '/' TAG_t
- final {
- char *td = $3->tag->content;
- Key lowKey = readKey( td, &td );
- Key highKey = readKey( td, &td );
- long targ = readOffsetPtr( td, &td );
- long action = readOffsetPtr( td, &td );
-
- cgd->newTrans( curState, curTrans++, lowKey, highKey, targ, action );
- };
-
-#
-# Action Lists.
-#
-
-tag_action_list: tag_action_list_head action_list '/' TAG_action_list;
-
-tag_action_list_head: TAG_action_list
- final {
- Attribute *lengthAttr = $1->tag->findAttr( "length" );
- if ( lengthAttr == 0 )
- error($1->loc) << "tag <action_list> requires a length attribute" << endp;
- else {
- unsigned long length = strtoul( lengthAttr->value, 0, 10 );
- cgd->initActionList( length );
- curAction = 0;
- }
- };
-
-action_list: action_list tag_action;
-action_list: ;
-
-#
-# Actions.
-#
-
-tag_action: TAG_action inline_list '/' TAG_action
- final {
- Attribute *lineAttr = $1->tag->findAttr( "line" );
- Attribute *colAttr = $1->tag->findAttr( "col" );
- Attribute *nameAttr = $1->tag->findAttr( "name" );
- if ( lineAttr == 0 || colAttr == 0)
- error($1->loc) << "tag <action> requires a line and col attributes" << endp;
- else {
- unsigned long line = strtoul( lineAttr->value, 0, 10 );
- unsigned long col = strtoul( colAttr->value, 0, 10 );
-
- char *name = 0;
- if ( nameAttr != 0 )
- name = nameAttr->value;
-
- cgd->newAction( curAction++, name, line, col, $2->inlineList );
- }
- };
-
-nonterm inline_list
-{
- GenInlineList *inlineList;
-};
-
-
-inline_list: inline_list inline_item
- final {
- /* Append the item to the list, return the list. */
- $1->inlineList->append( $2->inlineItem );
- $$->inlineList = $1->inlineList;
- };
-
-inline_list:
- final {
- /* Start with empty list. */
- $$->inlineList = new GenInlineList;
- };
-
-nonterm inline_item_type
-{
- GenInlineItem *inlineItem;
-};
-
-nonterm inline_item uses inline_item_type;
-
-inline_item: tag_text final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_goto final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_call final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_next final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_goto_expr final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_call_expr final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_next_expr final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_ret final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_break final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_pchar final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_char final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_hold final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_exec final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_curs final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_targs final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_il_entry final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_init_tokstart final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_init_act final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_get_tokend final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_set_tokstart final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_set_tokend final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_set_act final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_sub_action final { $$->inlineItem = $1->inlineItem; };
-inline_item: tag_lm_switch final { $$->inlineItem = $1->inlineItem; };
-
-nonterm tag_text uses inline_item_type;
-nonterm tag_goto uses inline_item_type;
-nonterm tag_call uses inline_item_type;
-nonterm tag_next uses inline_item_type;
-nonterm tag_goto_expr uses inline_item_type;
-nonterm tag_call_expr uses inline_item_type;
-nonterm tag_next_expr uses inline_item_type;
-nonterm tag_ret uses inline_item_type;
-nonterm tag_break uses inline_item_type;
-nonterm tag_pchar uses inline_item_type;
-nonterm tag_char uses inline_item_type;
-nonterm tag_hold uses inline_item_type;
-nonterm tag_exec uses inline_item_type;
-nonterm tag_curs uses inline_item_type;
-nonterm tag_targs uses inline_item_type;
-nonterm tag_il_entry uses inline_item_type;
-nonterm tag_init_tokstart uses inline_item_type;
-nonterm tag_init_act uses inline_item_type;
-nonterm tag_get_tokend uses inline_item_type;
-nonterm tag_set_tokstart uses inline_item_type;
-nonterm tag_set_tokend uses inline_item_type;
-nonterm tag_set_act uses inline_item_type;
-nonterm tag_sub_action uses inline_item_type;
-nonterm tag_lm_switch uses inline_item_type;
-
-tag_text: TAG_text '/' TAG_text
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::Text );
- $$->inlineItem->data = $3->tag->content;
- };
-
-tag_goto: TAG_goto '/' TAG_goto
- final {
- int targ = strtol( $3->tag->content, 0, 10 );
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::Goto );
- $$->inlineItem->targId = targ;
- };
-
-tag_call: TAG_call '/' TAG_call
- final {
- int targ = strtol( $3->tag->content, 0, 10 );
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::Call );
- $$->inlineItem->targId = targ;
- };
-
-tag_next: TAG_next '/' TAG_next
- final {
- int targ = strtol( $3->tag->content, 0, 10 );
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::Next );
- $$->inlineItem->targId = targ;
- };
-
-tag_goto_expr: TAG_goto_expr inline_list '/' TAG_goto_expr
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::GotoExpr );
- $$->inlineItem->children = $2->inlineList;
- };
-
-tag_call_expr: TAG_call_expr inline_list '/' TAG_call_expr
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::CallExpr );
- $$->inlineItem->children = $2->inlineList;
- };
-
-tag_next_expr: TAG_next_expr inline_list '/' TAG_next_expr
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::NextExpr );
- $$->inlineItem->children = $2->inlineList;
- };
-
-tag_ret: TAG_ret '/' TAG_ret
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::Ret );
- };
-
-tag_break: TAG_break '/' TAG_break
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::Break );
- };
-
-tag_pchar: TAG_pchar '/' TAG_pchar
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::PChar );
- };
-
-tag_char: TAG_char '/' TAG_char
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::Char );
- };
-
-tag_hold: TAG_hold '/' TAG_hold
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::Hold );
- };
-
-tag_exec: TAG_exec inline_list '/' TAG_exec
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::Exec );
- $$->inlineItem->children = $2->inlineList;
- };
-
-tag_curs: TAG_curs '/' TAG_curs
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::Curs );
- };
-
-tag_targs: TAG_targs '/' TAG_targs
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::Targs );
- };
-
-tag_il_entry: TAG_entry '/' TAG_entry
- final {
- int targ = strtol( $3->tag->content, 0, 10 );
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::Entry );
- $$->inlineItem->targId = targ;
- };
-
-tag_init_tokstart: TAG_init_tokstart '/' TAG_init_tokstart
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::LmInitTokStart );
- };
-
-tag_init_act: TAG_init_act '/' TAG_init_act
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::LmInitAct );
- };
-
-tag_get_tokend: TAG_get_tokend '/' TAG_get_tokend
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::LmGetTokEnd );
- };
-
-tag_set_tokstart: TAG_set_tokstart '/' TAG_set_tokstart
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::LmSetTokStart );
- cgd->hasLongestMatch = true;
- };
-
-tag_set_tokend: TAG_set_tokend '/' TAG_set_tokend
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::LmSetTokEnd );
- $$->inlineItem->offset = strtol( $3->tag->content, 0, 10 );
- };
-
-tag_set_act: TAG_set_act '/' TAG_set_act
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::LmSetActId );
- $$->inlineItem->lmId = strtol( $3->tag->content, 0, 10 );
- };
-
-tag_sub_action: TAG_sub_action inline_list '/' TAG_sub_action
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::SubAction );
- $$->inlineItem->children = $2->inlineList;
- };
-
-# Action switches.
-tag_lm_switch: TAG_lm_switch lm_action_list '/' TAG_lm_switch
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::LmSwitch );
- $$->inlineItem->children = $2->inlineList;
- };
-
-nonterm lm_action_list
-{
- GenInlineList *inlineList;
-};
-
-lm_action_list: lm_action_list tag_inline_action
- final {
- $$->inlineList = $1->inlineList;
- $$->inlineList->append( $2->inlineItem );
- };
-lm_action_list:
- final {
- $$->inlineList = new GenInlineList;
- };
-
-nonterm tag_inline_action uses inline_item_type;
-
-tag_inline_action: TAG_sub_action inline_list '/' TAG_sub_action
- final {
- $$->inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::SubAction );
- $$->inlineItem->children = $2->inlineList;
-
- Attribute *idAttr = $1->tag->findAttr( "id" );
- if ( idAttr != 0 ) {
- unsigned long id = strtoul( idAttr->value, 0, 10 );
- $$->inlineItem->lmId = id;
- }
- };
-
-#
-# Lists of Actions.
-#
-
-tag_action_table_list:
- tag_action_table_list_head action_table_list '/' TAG_action_table_list;
-
-tag_action_table_list_head: TAG_action_table_list
- final {
- Attribute *lengthAttr = $1->tag->findAttr( "length" );
- if ( lengthAttr == 0 ) {
- error($1->loc) << "tag <action_table_list> requires "
- "a length attribute" << endp;
- }
- else {
- unsigned long length = strtoul( lengthAttr->value, 0, 10 );
- cgd->initActionTableList( length );
- curActionTable = 0;
- }
- };
-
-action_table_list: action_table_list tag_action_table;
-action_table_list: ;
-
-tag_action_table: TAG_action_table '/' TAG_action_table
- final {
- /* Find the length of the action table. */
- Attribute *lengthAttr = $1->tag->findAttr( "length" );
- if ( lengthAttr == 0 )
- error($1->loc) << "tag <at> requires a length attribute" << endp;
- else {
- unsigned long length = strtoul( lengthAttr->value, 0, 10 );
-
- /* Collect the action table. */
- RedAction *redAct = cgd->allActionTables + curActionTable;
- redAct->actListId = curActionTable;
- redAct->key.setAsNew( length );
- char *ptr = $3->tag->content;
- int pos = 0;
- while ( *ptr != 0 ) {
- unsigned long actionId = strtoul( ptr, &ptr, 10 );
- redAct->key[pos].key = 0;
- redAct->key[pos].value = cgd->allActions+actionId;
- pos += 1;
- }
-
- /* Insert into the action table map. */
- cgd->redFsm->actionMap.insert( redAct );
- }
-
- curActionTable += 1;
- };
-
-#
-# Conditions.
-#
-
-tag_cond_space_list: tag_cond_space_list_head cond_space_list '/' TAG_cond_space_list;
-
-tag_cond_space_list_head: TAG_cond_space_list
- final {
- Attribute *lengthAttr = $1->tag->findAttr( "length" );
- if ( lengthAttr == 0 ) {
- error($1->loc) << "tag <cond_space_list> "
- "requires a length attribute" << endp;
- }
- else {
- ulong length = readLength( lengthAttr->value );
- cgd->initCondSpaceList( length );
- curCondSpace = 0;
- }
- };
-
-cond_space_list: cond_space_list tag_cond_space;
-cond_space_list: tag_cond_space;
-
-tag_cond_space: TAG_cond_space '/' TAG_cond_space
- final {
- Attribute *lengthAttr = $1->tag->findAttr( "length" );
- Attribute *idAttr = $1->tag->findAttr( "id" );
- if ( lengthAttr == 0 )
- error($1->loc) << "tag <cond_space> requires a length attribute" << endp;
- else {
- if ( lengthAttr == 0 )
- error($1->loc) << "tag <cond_space> requires an id attribute" << endp;
- else {
- unsigned long condSpaceId = strtoul( idAttr->value, 0, 10 );
- ulong length = readLength( lengthAttr->value );
-
- char *td = $3->tag->content;
- Key baseKey = readKey( td, &td );
-
- cgd->newCondSpace( curCondSpace, condSpaceId, baseKey );
- for ( ulong a = 0; a < length; a++ ) {
- long actionOffset = readOffsetPtr( td, &td );
- cgd->condSpaceItem( curCondSpace, actionOffset );
- }
- curCondSpace += 1;
- }
- }
- };
-
-}%%
-
-%%{
- write types;
- write data;
-}%%
-
-void XmlParser::init()
-{
- %% write init;
-}
-
-int XmlParser::parseLangEl( int type, const Token *token )
-{
- %% write exec;
- return errCount == 0 ? 0 : -1;
-}
-
-
-unsigned long readLength( char *td )
-{
- return strtoul( td, 0, 10 );
-}
-
-Key readKey( char *td, char **end )
-{
- if ( keyOps->isSigned )
- return Key( strtol( td, end, 10 ) );
- else
- return Key( strtoul( td, end, 10 ) );
-}
-
-long readOffsetPtr( char *td, char **end )
-{
- while ( *td == ' ' || *td == '\t' )
- td++;
-
- if ( *td == 'x' ) {
- if ( end != 0 )
- *end = td + 1;
- return -1;
- }
-
- return strtol( td, end, 10 );
-}
-
-ostream &XmlParser::warning( const InputLoc &loc )
-{
- cerr << fileName << ":" << loc.line << ":" << loc.col << ": warning: ";
- return cerr;
-}
-
-ostream &XmlParser::error( const InputLoc &loc )
-{
- gblErrorCount += 1;
- assert( fileName != 0 );
- cerr << fileName << ":" << loc.line << ":" << loc.col << ": ";
- return cerr;
-}
-
-
-ostream &XmlParser::parser_error( int tokId, Token &token )
-{
- gblErrorCount += 1;
- assert( fileName != 0 );
- cerr << fileName << ":" << token.loc.line << ":" << token.loc.col;
- if ( token.tag != 0 ) {
- if ( token.tag->tagId == 0 )
- cerr << ": at unknown tag";
- else
- cerr << ": at tag <" << token.tag->tagId->name << ">";
- }
- cerr << ": ";
-
- return cerr;
-}
-
-ostream &XmlParser::source_error( const InputLoc &loc )
-{
- gblErrorCount += 1;
- assert( sourceFileName != 0 );
- cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": ";
- return cerr;
-}
-
-
-int XmlParser::token( int tokenId, Token &tok )
-{
- int res = parseLangEl( tokenId, &tok );
- if ( res < 0 )
- parser_error( tokenId, tok ) << "parse error" << endp;
- return res;
-}
-
-int XmlParser::token( int tokenId, int col, int line )
-{
- Token tok;
- tok.loc.col = col;
- tok.loc.line = line;
- tok.tag = 0;
- return token( tokenId, tok );
-}
-
-int XmlParser::token( XMLTag *tag, int col, int line )
-{
- Token tok;
- tok.loc.col = col;
- tok.loc.line = line;
- tok.tag = tag;
-
- if ( tag->type == XMLTag::Close ) {
- int res = token( '/', tok );
- if ( res < 0 )
- return res;
- }
-
- tok.tag = tag;
- return token( tag->tagId != 0 ? tag->tagId->id : TAG_unknown, tok );
-}
diff --git a/libfsm/xmlscan.rl b/libfsm/xmlscan.rl
deleted file mode 100644
index 4e9ee4e2..00000000
--- a/libfsm/xmlscan.rl
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright 2001-2007 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <iostream>
-#include <string.h>
-#include "vector.h"
-#include "xmlparse.h"
-
-using std::istream;
-using std::cout;
-using std::cerr;
-using std::endl;
-
-%%{
- machine XmlScanner;
- write data;
-}%%
-
-class Perfect_Hash
-{
-private:
- static inline unsigned int hash (const char *str, unsigned int len);
-
-public:
- static struct XMLTagHashPair *in_word_set (const char *str, unsigned int len);
-};
-
-XmlScanner::XmlScanner( const char *fileName, istream &input ) :
- fileName(fileName),
- input(input),
- curline(1),
- curcol(1),
- p(0), pe(0),
- done(false),
- data(0), data_len(0),
- value(0)
-{
- %%{
- machine XmlScanner;
- write init;
- }%%
-}
-
-#define TK_NO_TOKEN (-1)
-#define TK_ERR 1
-#define TK_SPACE 2
-#define TK_EOF 3
-#define TK_OpenTag 4
-#define TK_CloseTag 5
-
-#define ret_tok( _tok ) token = (_tok); data = ts
-
-void XmlScanner::adjustAttrPointers( int distance )
-{
- for ( AttrMkList::Iter attr = attrMkList; attr.lte(); attr++ ) {
- attr->id -= distance;
- attr->value -= distance;
- }
-}
-
-/* There is no claim that this is a proper XML parser, but it is good
- * enough for our purposes. */
-%%{
- machine XmlScanner;
-
- action colup { curcol++; }
- action start_tok { token_col = curcol; token_line = curline; }
- NL = '\n' @{ curcol = 0; curline++; };
-
- WS = [\r\t ] | NL;
- id = [_a-zA-Z][_a-zA-Z0-9]*;
- literal = '"' ( [^"] | NL )* '"';
-
- # Attribute identifiers.
- action start_attr_id { attr_id_start = p; }
- action leave_attr_id { attr_id_len = p - attr_id_start; }
-
- attr_id = id >start_attr_id %leave_attr_id;
-
- # Attribute values
- action start_attr_value { attr_value_start = p; }
- action leave_attr_value
- {
- attr_value_len = p - attr_value_start;
-
- AttrMarker newAttr;
- newAttr.id = attr_id_start;
- newAttr.idLen = attr_id_len;
- newAttr.value = attr_value_start;
- newAttr.valueLen = attr_value_len;
- attrMkList.append( newAttr );
- }
-
- attr_value = literal >start_attr_value %leave_attr_value;
-
- # Attribute list.
- attribute = attr_id WS* '=' WS* attr_value WS*;
-
- # Tag identifiers.
- action tag_id_start { tag_id_start = p; }
- action leave_tag_id { tag_id_len = p - tag_id_start; }
-
- tag_id = id >tag_id_start %leave_tag_id;
-
- main := |*
- # Tags
- ( '<' WS* tag_id ( WS+ attribute* )? '>' ) >start_tok $colup
- => { ret_tok( TK_OpenTag ); fbreak; };
-
- ( '<' WS* '/' WS* tag_id WS* '>' ) >start_tok $colup
- => { ret_tok( TK_CloseTag ); fbreak; };
-
- # Data in between tags.
- ( [^<&\0] | NL ) $colup
- => { buffer.append( *p ); };
-
- # Specials.
- "&amp;" $colup
- => { buffer.append( '&' ); };
- "&lt;" $colup
- => { buffer.append( '<' ); };
- "&gt;" $colup
- => { buffer.append( '>' ); };
-
- # EOF
- 0 >start_tok => { ret_tok( TK_EOF ); fbreak; };
-
- *|;
-}%%
-
-int XmlScanner::scan( )
-{
- int token = TK_NO_TOKEN;
- int space = 0, readlen = 0;
- char *attr_id_start = 0;
- char *attr_value_start = 0;
- int attr_id_len = 0;
- int attr_value_len = 0;
-
- attrMkList.empty();
- buffer.clear();
-
- while ( 1 ) {
- if ( p == pe ) {
- //printf("scanner: need more data\n");
-
- if ( ts == 0 )
- have = 0;
- else {
- /* There is data that needs to be shifted over. */
- //printf("scanner: buffer broken mid token\n");
- have = pe - ts;
- memmove( buf, ts, have );
-
- int distance = ts - buf;
- te -= distance;
- tag_id_start -= distance;
- attr_id_start -= distance;
- attr_value_start -= distance;
- adjustAttrPointers( distance );
- ts = buf;
- }
-
- p = buf + have;
- space = XML_BUFSIZE - have;
-
- if ( space == 0 ) {
- /* We filled up the buffer trying to scan a token. */
- return TK_SPACE;
- }
-
- if ( done ) {
- //printf("scanner: end of file\n");
- p[0] = 0;
- readlen = 1;
- }
- else {
- input.read( p, space );
- readlen = input.gcount();
- if ( input.eof() ) {
- //printf("scanner: setting done flag\n");
- done = 1;
- }
- }
-
- pe = p + readlen;
- }
-
- %% write exec;
-
- if ( cs == XmlScanner_error )
- return TK_ERR;
-
- if ( token != TK_NO_TOKEN ) {
- data_len = p - data;
- return token;
- }
- }
-}
-
-int xml_parse( std::istream &input, const char *fileName,
- bool outputActive, bool wantComplete,
- XmlScanner &scanner, XmlParser &parser )
-{
- while ( 1 ) {
- int token = scanner.scan();
- if ( token == TK_NO_TOKEN ) {
- cerr << "xmlscan: interal error: scanner returned NO_TOKEN" << endl;
- exit(1);
- }
- else if ( token == TK_EOF ) {
- parser.token( XmlParser_tk_eof, scanner.token_col, scanner.token_line );
- break;
- }
- else if ( token == TK_ERR ) {
- scanner.error() << "scanner error" << endl;
- break;
- }
- else if ( token == TK_SPACE ) {
- scanner.error() << "scanner is out of buffer space" << endl;
- break;
- }
- else {
- /* All other tokens are either open or close tags. */
- XMLTagHashPair *tagId = Perfect_Hash::in_word_set(
- scanner.tag_id_start, scanner.tag_id_len );
-
- XMLTag *tag = new XMLTag( tagId, token == TK_OpenTag ?
- XMLTag::Open : XMLTag::Close );
-
- if ( tagId != 0 ) {
- /* Get attributes for open tags. */
- if ( token == TK_OpenTag && scanner.attrMkList.length() > 0 ) {
- tag->attrList = new AttrList;
- for ( AttrMkList::Iter attr = scanner.attrMkList;
- attr.lte(); attr++ )
- {
- Attribute newAttr;
- newAttr.id = new char[attr->idLen+1];
- memcpy( newAttr.id, attr->id, attr->idLen );
- newAttr.id[attr->idLen] = 0;
-
- /* Exclude the surrounding quotes. */
- newAttr.value = new char[attr->valueLen-1];
- memcpy( newAttr.value, attr->value+1, attr->valueLen-2 );
- newAttr.value[attr->valueLen-2] = 0;
-
- tag->attrList->append( newAttr );
- }
- }
-
- /* Get content for closing tags. */
- if ( token == TK_CloseTag ) {
- switch ( tagId->id ) {
- case TAG_host: case TAG_arg:
- case TAG_t: case TAG_alphtype:
- case TAG_text: case TAG_goto:
- case TAG_call: case TAG_next:
- case TAG_entry: case TAG_set_tokend:
- case TAG_set_act: case TAG_start_state:
- case TAG_error_state: case TAG_state_actions:
- case TAG_action_table: case TAG_cond_space:
- case TAG_c: case TAG_ex: case TAG_eof_t:
- tag->content = new char[scanner.buffer.length+1];
- memcpy( tag->content, scanner.buffer.data,
- scanner.buffer.length );
- tag->content[scanner.buffer.length] = 0;
- break;
- }
- }
- }
-
- #if 0
- cerr << "parser_driver: " << (tag->type == XMLTag::Open ? "open" : "close") <<
- ": " << (tag->tagId != 0 ? tag->tagId->name : "<unknown>") << endl;
- if ( tag->attrList != 0 ) {
- for ( AttrList::Iter attr = *tag->attrList; attr.lte(); attr++ )
- cerr << " " << attr->id << ": " << attr->value << endl;
- }
- if ( tag->content != 0 )
- cerr << " content: " << tag->content << endl;
- #endif
-
- parser.token( tag, scanner.token_col, scanner.token_line );
- }
- }
-
- return 0;
-}
-
-std::ostream &XmlScanner::error()
-{
- gblErrorCount += 1;
- cerr << fileName << ":" << curline << ":" << curcol << ": ";
- return cerr;
-}
diff --git a/libfsm/xmltags.gperf b/libfsm/xmltags.gperf
deleted file mode 100644
index 1ca544f7..00000000
--- a/libfsm/xmltags.gperf
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2005 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-
-%{
-#include <string.h>
-#include "xmlparse.h"
-%}
-%compare-strncmp
-struct XMLTagHashPair;
-%%
-ragel, TAG_ragel
-ragel_def, TAG_ragel_def
-host, TAG_host
-state_list, TAG_state_list
-state, TAG_state
-trans_list, TAG_trans_list
-t, TAG_t
-machine, TAG_machine
-start_state, TAG_start_state
-error_state, TAG_error_state
-action_list, TAG_action_list
-action, TAG_action
-action_table_list, TAG_action_table_list
-action_table, TAG_action_table
-alphtype, TAG_alphtype
-getkey, TAG_getkey
-state_actions, TAG_state_actions
-entry_points, TAG_entry_points
-text, TAG_text
-goto, TAG_goto
-call, TAG_call
-next, TAG_next
-goto_expr, TAG_goto_expr
-call_expr, TAG_call_expr
-next_expr, TAG_next_expr
-ret, TAG_ret
-pchar, TAG_pchar
-char, TAG_char
-hold, TAG_hold
-exec, TAG_exec
-curs, TAG_curs
-targs, TAG_targs
-entry, TAG_entry
-data, TAG_data
-lm_switch, TAG_lm_switch
-sub_action, TAG_sub_action
-init_act, TAG_init_act
-set_act, TAG_set_act
-get_tokend, TAG_get_tokend
-set_tokend, TAG_set_tokend
-init_tokstart, TAG_init_tokstart
-set_tokstart, TAG_set_tokstart
-write, TAG_write
-access, TAG_access
-break, TAG_break
-arg, TAG_arg
-cond_space_list, TAG_cond_space_list
-cond_space, TAG_cond_space
-cond_list, TAG_cond_list
-c, TAG_c
-exports, TAG_exports
-ex, TAG_ex
-p_expr, TAG_p_expr
-pe_expr, TAG_pe_expr
-eof_expr, TAG_eof_expr
-cs_expr, TAG_cs_expr
-top_expr, TAG_top_expr
-stack_expr, TAG_stack_expr
-act_expr, TAG_act_expr
-tokstart_expr, TAG_tokstart_expr
-tokend_expr, TAG_tokend_expr
-data_expr, TAG_data_expr
-prepush, TAG_prepush
-postpop, TAG_postpop
-eof_t, TAG_eof_t