"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/inputdata.cc" between
ragel-7.0.0.9.tar.gz and ragel-7.0.0.10.tar.gz

About:

inputdata.cc  (ragel-7.0.0.9):inputdata.cc  (ragel-7.0.0.10)
/* /*
* Copyright 2008-2016 Adrian Thurston <thurston@complang.org> * Copyright 2008-2016 Adrian Thurston <thurston@colm.net>
*/
/* This file is part of Ragel.
* *
* Ragel is free software; you can redistribute it and/or modify * Permission is hereby granted, free of charge, to any person obtaining a copy
* it under the terms of the GNU General Public License as published by * of this software and associated documentation files (the "Software"), to
* the Free Software Foundation; either version 2 of the License, or * deal in the Software without restriction, including without limitation the
* (at your option) any later version. * 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:
* *
* Ragel is distributed in the hope that it will be useful, * The above copyright notice and this permission notice shall be included in al
* but WITHOUT ANY WARRANTY; without even the implied warranty of l
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * copies or substantial portions of the Software.
* GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* along with Ragel; if not, write to the Free Software * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 "ragel.h"
#include "common.h" #include "common.h"
#include "inputdata.h" #include "inputdata.h"
#include "parsedata.h" #include "parsedata.h"
#include "load.h" #include "load.h"
#include "rlscan.h" #include "rlscan.h"
#include "reducer.h" #include "reducer.h"
#include <iostream> #include <iostream>
#include <unistd.h> #include <unistd.h>
using std::istream; using std::istream;
using std::ifstream; using std::ifstream;
using std::stringstream; using std::stringstream;
using std::ostream; using std::ostream;
using std::endl; using std::endl;
using std::ios; using std::ios;
extern colm_sections rlhc_object;
InputData::~InputData() InputData::~InputData()
{ {
includeDict.empty();
inputItems.empty(); inputItems.empty();
parseDataList.empty(); parseDataList.empty();
sectionList.empty(); sectionList.empty();
for ( Vector<const char**>::Iter fns = streamFileNames; fns.lte(); fns++ ) { for ( Vector<const char**>::Iter fns = streamFileNames; fns.lte(); fns++ ) {
const char **ptr = *fns; const char **ptr = *fns;
while ( *ptr != 0 ) { while ( *ptr != 0 ) {
::free( (void*)*ptr ); ::free( (void*)*ptr );
ptr += 1; ptr += 1;
} }
skipping to change at line 72 skipping to change at line 70
::free( (void*)histogramFn ); ::free( (void*)histogramFn );
if ( histogram != 0 ) if ( histogram != 0 )
delete[] histogram; delete[] histogram;
for ( ArgsVector::Iter bl = breadthLabels; bl.lte(); bl++ ) for ( ArgsVector::Iter bl = breadthLabels; bl.lte(); bl++ )
free( (void*) *bl ); free( (void*) *bl );
} }
/* Invoked by the parser when the root element is opened. */ /* Invoked by the parser when the root element is opened. */
void InputData::cdDefaultFileName( const char *inputFile ) void InputData::cDefaultFileName( const char *inputFile )
{ {
/* If the output format is code and no output file name is given, then /* If the output format is code and no output file name is given, then
* make a default. */ * make a default. */
if ( outputFileName == 0 ) { if ( outputFileName == 0 ) {
const char *ext = findFileExtension( inputFile ); const char *ext = findFileExtension( inputFile );
if ( ext != 0 && strcmp( ext, ".rh" ) == 0 ) if ( ext != 0 && strcmp( ext, ".rh" ) == 0 )
outputFileName = fileNameFromStem( inputFile, ".h" ); outputFileName = fileNameFromStem( inputFile, ".h" );
else { else {
const char *defExtension = 0; const char *defExtension = 0;
switch ( hostLang->lang ) { switch ( hostLang->lang ) {
case HostLang::C: defExtension = ".c"; break; case HostLang::C: defExtension = ".c"; break;
case HostLang::D: defExtension = ".d"; break;
default: break; default: break;
} }
outputFileName = fileNameFromStem( inputFile, defExtensio n ); outputFileName = fileNameFromStem( inputFile, defExtensio n );
} }
} }
} }
/* Invoked by the parser when the root element is opened. */
void InputData::goDefaultFileName( const char *inputFile )
{
/* If the output format is code and no output file name is given, then
* make a default. */
if ( outputFileName == 0 )
outputFileName = fileNameFromStem( inputFile, ".go" );
}
/* Invoked by the parser when the root element is opened. */
void InputData::javaDefaultFileName( const char *inputFile )
{
/* If the output format is code and no output file name is given, then
* make a default. */
if ( outputFileName == 0 )
outputFileName = fileNameFromStem( inputFile, ".java" );
}
/* Invoked by the parser when the root element is opened. */
void InputData::rubyDefaultFileName( const char *inputFile )
{
/* If the output format is code and no output file name is given, then
* make a default. */
if ( outputFileName == 0 )
outputFileName = fileNameFromStem( inputFile, ".rb" );
}
/* Invoked by the parser when the root element is opened. */
void InputData::csharpDefaultFileName( const char *inputFile )
{
/* If the output format is code and no output file name is given, then
* make a default. */
if ( outputFileName == 0 ) {
const char *ext = findFileExtension( inputFile );
if ( ext != 0 && strcmp( ext, ".rh" ) == 0 )
outputFileName = fileNameFromStem( inputFile, ".h" );
else
outputFileName = fileNameFromStem( inputFile, ".cs" );
}
}
/* Invoked by the parser when the root element is opened. */
void InputData::ocamlDefaultFileName( const char *inputFile )
{
/* If the output format is code and no output file name is given, then
* make a default. */
if ( outputFileName == 0 )
outputFileName = fileNameFromStem( inputFile, ".ml" );
}
/* Invoked by the parser when the root element is opened. */
void InputData::crackDefaultFileName( const char *inputFile )
{
/* If the output format is code and no output file name is given, then
* make a default. */
if ( outputFileName == 0 )
outputFileName = fileNameFromStem( inputFile, ".crk" );
}
void InputData::asmDefaultFileName( const char *inputFile ) void InputData::asmDefaultFileName( const char *inputFile )
{ {
if ( outputFileName == 0 ) if ( outputFileName == 0 )
outputFileName = fileNameFromStem( inputFile, ".s" ); outputFileName = fileNameFromStem( inputFile, ".s" );
} }
void InputData::rustDefaultFileName( const char *inputFile )
{
if ( outputFileName == 0 )
outputFileName = fileNameFromStem( inputFile, ".rs" );
}
void InputData::juliaDefaultFileName( const char *inputFile )
{
if ( outputFileName == 0 )
outputFileName = fileNameFromStem( inputFile, ".jl" );
}
void InputData::jsDefaultFileName( const char *inputFile )
{
/* If the output format is code and no output file name is given, then
* make a default. */
if ( outputFileName == 0 )
outputFileName = fileNameFromStem( inputFile, ".js" );
}
void InputData::makeDefaultFileName() void InputData::makeDefaultFileName()
{ {
switch ( hostLang->lang ) { switch ( hostLang->lang ) {
case HostLang::C: case HostLang::C:
case HostLang::D: cDefaultFileName( inputFileName );
cdDefaultFileName( inputFileName );
break;
case HostLang::Java:
javaDefaultFileName( inputFileName );
break;
case HostLang::Go:
goDefaultFileName( inputFileName );
break;
case HostLang::Ruby:
rubyDefaultFileName( inputFileName );
break;
case HostLang::CSharp:
csharpDefaultFileName( inputFileName );
break;
case HostLang::OCaml:
ocamlDefaultFileName( inputFileName );
break;
case HostLang::Crack:
crackDefaultFileName( inputFileName );
break; break;
case HostLang::Asm: case HostLang::Asm:
asmDefaultFileName( inputFileName ); asmDefaultFileName( inputFileName );
break; break;
case HostLang::Rust:
rustDefaultFileName( inputFileName );
break;
case HostLang::Julia:
juliaDefaultFileName( inputFileName );
break;
case HostLang::JS:
jsDefaultFileName( inputFileName );
break;
} }
} }
bool InputData::isBreadthLabel( const string &label ) bool InputData::isBreadthLabel( const string &label )
{ {
for ( ArgsVector::Iter bl = breadthLabels; bl.lte(); bl++ ) { for ( ArgsVector::Iter bl = breadthLabels; bl.lte(); bl++ ) {
if ( label == *bl ) if ( label == *bl )
return true; return true;
} }
return false; return false;
skipping to change at line 322 skipping to change at line 212
ParseData *pd = pdel->value; ParseData *pd = pdel->value;
if ( pd->instanceList.length() > 0 ) if ( pd->instanceList.length() > 0 )
pd->generateReduced( inputFileName, codeStyle, *outStream , hostLang ); pd->generateReduced( inputFileName, codeStyle, *outStream , hostLang );
} }
} }
void InputData::verifyWriteHasData( InputItem *ii ) void InputData::verifyWriteHasData( InputItem *ii )
{ {
if ( ii->type == InputItem::Write ) { if ( ii->type == InputItem::Write ) {
if ( ii->pd->cgd == 0 ) if ( ii->pd->cgd == 0 )
error( ii->loc ) << "no machine instantiations to write" << endl; error( ii->loc ) << ii->pd->sectionName << ": no machine instantiations to write" << endl;
} }
} }
void InputData::verifyWritesHaveData() void InputData::verifyWritesHaveData()
{ {
for ( InputItemList::Iter ii = inputItems; ii.lte(); ii++ ) for ( InputItemList::Iter ii = inputItems; ii.lte(); ii++ )
verifyWriteHasData( ii ); verifyWriteHasData( ii );
} }
void InputData::writeOutput( InputItem *ii ) void InputData::writeOutput( InputItem *ii )
{ {
switch ( ii->type ) { switch ( ii->type ) {
case InputItem::Write: { case InputItem::Write: {
CodeGenData *cgd = ii->pd->cgd; CodeGenData *cgd = ii->pd->cgd;
cgd->writeStatement( ii->loc, ii->writeArgs.size(), cgd->writeStatement( ii->loc, ii->writeArgs.size(),
ii->writeArgs, generateDot, hostLang ); ii->writeArgs, generateDot, hostLang );
break; break;
} }
case InputItem::HostData: { case InputItem::HostData: {
switch ( backend ) { if ( hostLang->lang == HostLang::C ) {
case Direct: if ( ii->loc.fileName != 0 ) {
if ( hostLang->lang == HostLang::C ) { if ( !noLineDirectives ) {
if ( ii->loc.fileName != 0 ) { *outStream << "\n#line " << ii->l
if ( !noLineDirectives ) oc.line <<
{ " \"" << ii->loc.
*outStream << "\n fileName << "\"\n";
#line " << ii->loc.line <<
"
\"" << ii->loc.fileName << "\"\n";
}
}
} }
}
*outStream << ii->data.str();
break;
case Translated:
openHostBlock( '@', this, *outStream, inp
utFileName, ii->loc.line );
translatedHostData( *outStream, ii->data.
str() );
*outStream << "}@";
break;
} }
*outStream << ii->data.str();
break; break;
} }
case InputItem::EndSection: { case InputItem::EndSection: {
break; break;
} }
} }
} }
void InputData::writeOutput() void InputData::writeOutput()
{ {
skipping to change at line 407 skipping to change at line 288
/* /*
* From this point on we should not be reporting any errors. * From this point on we should not be reporting any errors.
*/ */
openOutput(); openOutput();
writeDot( *outStream ); writeDot( *outStream );
closeOutput(); closeOutput();
} }
void InputData::runRlhc()
{
if ( backend != Translated || noIntermediate )
return;
string rlhc = dirName + "/rlhc " +
origOutputFileName + " " +
genOutputFileName + " " +
hostLang->rlhcArg;
if ( rlhcShowCmd )
info() << rlhc << std::endl;
const char *argv[5];
argv[0] = "rlhc";
argv[1] = origOutputFileName.c_str();
argv[2] = genOutputFileName.c_str();
argv[3] = hostLang->rlhcArg;
argv[4] = 0;
colm_program *program = colm_new_program( &rlhc_object );
colm_set_debug( program, 0 );
colm_run_program( program, 4, argv );
int es = program->exit_status;
streamFileNames.append( colm_extract_fns( program ) );
colm_delete_program( program );
if ( !saveTemps )
unlink( genOutputFileName.c_str() );
/* Translation step shouldn't fail, but it can if there is an
* internal error. Pass it up. */
if ( es != 0 )
abortCompile( es );
}
void InputData::processCode()
{
/* Compiles machines. */
prepareAllMachines();
if ( errorCount > 0 )
abortCompile( 1 );
makeDefaultFileName();
makeTranslateOutputFileName();
createOutputStream();
/* Generates the reduced machine, which we use to write output. */
generateReduced();
if ( errorCount > 0 )
abortCompile( 1 );
verifyWritesHaveData();
if ( errorCount > 0 )
abortCompile( 1 );
/*
* From this point on we should not be reporting any errors.
*/
openOutput();
writeOutput();
closeOutput();
runRlhc();
}
bool InputData::checkLastRef( InputItem *ii ) bool InputData::checkLastRef( InputItem *ii )
{ {
if ( generateDot ) if ( generateDot )
return true; return true;
if ( errorCount > 0 ) if ( errorCount > 0 )
return false; return false;
/* /*
* 1. Go forward to next last reference. * 1. Go forward to next last reference.
skipping to change at line 542 skipping to change at line 350
* input item. */ * input item. */
while ( lastFlush != 0 && lastFlush->processed ) { while ( lastFlush != 0 && lastFlush->processed ) {
verifyWriteHasData( lastFlush ); verifyWriteHasData( lastFlush );
if ( errorCount > 0 ) if ( errorCount > 0 )
return false; return false;
/* Flush out. */ /* Flush out. */
writeOutput( lastFlush ); writeOutput( lastFlush );
/* If this is the last reference to a pd, we can now clea
r the
* memory for it. */
if ( lastFlush->pd != 0 && lastFlush->section->lastRefere
nce == lastFlush ) {
if ( lastFlush->pd->instanceList.length() > 0 ) {
lastFlush->pd->clear();
#ifdef WITH_RAGEL_KELBT
if ( lastFlush->parser != 0 )
lastFlush->parser->clear();
#endif
}
}
lastFlush = lastFlush->next; lastFlush = lastFlush->next;
} }
} }
return true; return true;
} }
void InputData::makeFirstInputItem() void InputData::makeFirstInputItem()
{ {
/* Make the first input item. */ /* Make the first input item. */
InputItem *firstInputItem = new InputItem; InputItem *firstInputItem = new InputItem;
skipping to change at line 583 skipping to change at line 378
void InputData::terminateAllParsers( ) void InputData::terminateAllParsers( )
{ {
#ifdef WITH_RAGEL_KELBT #ifdef WITH_RAGEL_KELBT
for ( ParserDict::Iter pdel = parserDict; pdel.lte(); pdel++ ) for ( ParserDict::Iter pdel = parserDict; pdel.lte(); pdel++ )
pdel->value->terminateParser(); pdel->value->terminateParser();
#endif #endif
} }
void InputData::flushRemaining() void InputData::flushRemaining()
{ {
InputItem *item = inputItems.head;
while ( item != 0 ) {
checkLastRef( item );
item = item->next;
}
/* Flush remaining items. */ /* Flush remaining items. */
while ( lastFlush != 0 ) { while ( lastFlush != 0 ) {
/* Flush out. */ /* Flush out. */
writeOutput( lastFlush ); writeOutput( lastFlush );
lastFlush = lastFlush->next; lastFlush = lastFlush->next;
} }
} }
void InputData::makeTranslateOutputFileName() void InputData::makeTranslateOutputFileName()
{ {
if ( backend == Translated ) { if ( false ) {
origOutputFileName = outputFileName; origOutputFileName = outputFileName;
outputFileName = fileNameFromStem( inputFileName, ".ri" ); outputFileName = fileNameFromStem( inputFileName, ".ri" );
genOutputFileName = outputFileName; genOutputFileName = outputFileName;
} }
} }
#ifdef WITH_RAGEL_KELBT #ifdef WITH_RAGEL_KELBT
void InputData::parseKelbt() void InputData::parseKelbt()
{ {
/* /*
skipping to change at line 676 skipping to change at line 478
processDot(); processDot();
} }
else { else {
makeDefaultFileName(); makeDefaultFileName();
makeTranslateOutputFileName(); makeTranslateOutputFileName();
createOutputStream(); createOutputStream();
openOutput(); openOutput();
parseKelbt(); parseKelbt();
flushRemaining(); flushRemaining();
closeOutput(); closeOutput();
runRlhc();
} }
assert( errorCount == 0 ); assert( errorCount == 0 );
} }
#endif #endif
void InputData::processColm()
{
/*
* Colm-based parser introduced in ragel 7. Uses more memory.
*/
/* Check input file. */
ifstream *inFile = new ifstream( inputFileName );
if ( ! inFile->is_open() )
error() << "could not open " << inputFileName << " for reading" <
< endp;
delete inFile;
makeFirstInputItem();
LoadRagel *lr = newLoadRagel( *this, hostLang, minimizeLevel, minimizeOpt
);
loadRagel( lr, inputFileName );
deleteLoadRagel( lr );
/* Bail on above error. */
if ( errorCount > 0 )
abortCompile( 1 );
if ( generateDot )
processDot();
else
processCode();
assert( errorCount == 0 );
}
bool InputData::parseReduce() bool InputData::parseReduce()
{ {
/* /*
* Colm-based reduction parser introduced in ragel 7. * Colm-based reduction parser introduced in ragel 7.
*/ */
SectionPass *sectionPass = new SectionPass( this ); TopLevel *topLevel = new TopLevel( this, hostLang,
TopLevel *topLevel = new TopLevel( this, sectionPass, hostLang,
minimizeLevel, minimizeOpt ); minimizeLevel, minimizeOpt );
if ( ! inLibRagel ) { /* Check input file. File is actually opened by colm code. We don't
/* Check input file. File is actually opened by colm code. We don * need to perform the check if in libragel since it comes in via a
't * string. */
* need to perform the check if in libragel since it comes in via if ( input == 0 ) {
a ifstream *inFile = new ifstream( inputFileName );
* string. */ if ( ! inFile->is_open() )
if ( input == 0 ) { error() << "could not open " << inputFileName << " for re
ifstream *inFile = new ifstream( inputFileName ); ading" << endp;
if ( ! inFile->is_open() ) delete inFile;
error() << "could not open " << inputFileName <<
" for reading" << endp;
delete inFile;
}
} }
makeFirstInputItem();
if ( inLibRagel )
sectionPass->reduceStr( inputFileName, input );
else
sectionPass->reduceFile( inputFileName );
if ( errorCount ) if ( errorCount )
return false; return false;
makeFirstInputItem();
curItem = inputItems.head; curItem = inputItems.head;
lastFlush = inputItems.head; lastFlush = inputItems.head;
if ( inLibRagel ) topLevel->reduceFile( inputFileName, false );
topLevel->reduceStr( inputFileName, input );
else
topLevel->reduceFile( inputFileName );
if ( errorCount ) if ( errorCount )
return false; return false;
bool success = topLevel->success; bool success = topLevel->success;
delete topLevel; delete topLevel;
delete sectionPass;
return success; return success;
} }
bool InputData::processReduce() bool InputData::processReduce()
{ {
if ( generateDot ) { if ( generateDot ) {
parseReduce(); parseReduce();
processDot(); processDot();
return true; return true;
} }
skipping to change at line 783 skipping to change at line 541
makeTranslateOutputFileName(); makeTranslateOutputFileName();
createOutputStream(); createOutputStream();
openOutput(); openOutput();
bool success = parseReduce(); bool success = parseReduce();
if ( success ) if ( success )
flushRemaining(); flushRemaining();
closeOutput(); closeOutput();
if ( success ) if ( !success && outputFileName != 0 )
runRlhc(); unlink( outputFileName );
return success; return success;
} }
} }
bool InputData::process() bool InputData::process()
{ {
switch ( frontend ) { switch ( frontend ) {
case KelbtBased: { case KelbtBased: {
#ifdef WITH_RAGEL_KELBT #ifdef WITH_RAGEL_KELBT
processKelbt(); processKelbt();
#endif #endif
return true; return true;
} }
case ColmBased: {
processColm();
return true;
}
case ReduceBased: { case ReduceBased: {
return processReduce(); return processReduce();
} }
} }
return false; return false;
} }
 End of changes. 30 change blocks. 
308 lines changed or deleted 53 lines changed or added

Home  |  About  |  All  |  Newest  |  Fossies Dox  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTPS