void writeMachines( std::ostream &out, std::string hostData, char *inputFileName );
void xmlEscapeHost( std::ostream &out, char *data, int len );
-
-/* Size of the include stack. */
-#define INCLUDE_STACK_SIZE 32
-
#endif /* _RAGEL_H */
/*
- * Copyright 2006 Adrian Thurston <thurston@cs.queensu.ca>
+ * Copyright 2006-2007 Adrian Thurston <thurston@cs.queensu.ca>
*/
/* This file is part of Ragel.
action write_command
{
- if ( active ) {
- if ( strcmp( tokdata, "data" ) != 0 &&
- strcmp( tokdata, "init" ) != 0 &&
- strcmp( tokdata, "exec" ) != 0 &&
- strcmp( tokdata, "eof" ) != 0 )
- {
- scan_error() << "unknown write command" << endl;
- }
-
- if ( machineSpec == 0 && machineName == 0 ) {
- output << "<write def_name=\"" << parser->sectionName <<
- "\" what=\"" << tokdata << "\">";
- }
+ if ( active && machineSpec == 0 && machineName == 0 ) {
+ output << "<write"
+ " def_name=\"" << parser->sectionName << "\""
+ " line=\"" << line << "\""
+ " col=\"" << column << "\""
+ ">";
}
}
- action write_option
+ action write_arg
{
- if ( active )
- output << "<option>" << tokdata << "</option>";
+ if ( active && machineSpec == 0 && machineName == 0 )
+ output << "<arg>" << tokdata << "</arg>";
}
+
action write_close
{
if ( active && machineSpec == 0 && machineName == 0 )
}
write_stmt =
- ( KW_Write TK_Word @write_command
- ( TK_Word @write_option )* ';' @write_close )
+ ( KW_Write @write_command
+ ( TK_Word @write_arg )+ ';' @write_close )
<>err write_err <>eof write_err;
action handle_token
using std::cerr;
using std::endl;
-CodeGenData *makeCodeGen( char *fileName, char *fsmName, ostream &out, bool wantComplete )
+CodeGenData *makeCodeGen( char *sourceFileName, char *fsmName,
+ ostream &out, bool wantComplete )
{
FsmCodeGen *codeGen = 0;
switch ( hostLangType ) {
break;
}
- codeGen->fileName = fileName;
+ codeGen->sourceFileName = sourceFileName;
codeGen->fsmName = fsmName;
codeGen->wantComplete = wantComplete;
void FsmCodeGen::ACTION( ostream &ret, Action *action, int targState, bool inFinish )
{
/* Write the preprocessor line info for going into the source file. */
- lineDirective( ret, fileName, action->loc.line );
+ lineDirective( ret, sourceFileName, action->loc.line );
/* Write the block and close it off. */
ret << "\t{";
void FsmCodeGen::CONDITION( ostream &ret, Action *condition )
{
ret << "\n";
- lineDirective( ret, fileName, condition->loc.line );
+ lineDirective( ret, sourceFileName, condition->loc.line );
INLINE_LIST( ret, condition->inlineList, 0, false );
}
}
}
-void FsmCodeGen::writeStatement( char *what, int nopts, char **options )
+void FsmCodeGen::writeStatement( InputLoc &loc, int nargs, char **args )
{
- /* Read the options. FIXME: These should be parsed according to each
- * particualr function below. */
- for ( int i = 0; i < nopts; i++ ) {
- if ( strcmp( options[i], "noend" ) == 0 )
- hasEnd = false;
- else if ( strcmp( options[i], "noerror" ) == 0 )
- writeErr = false;
- else if ( strcmp( options[i], "noprefix" ) == 0 )
- dataPrefix = false;
- else if ( strcmp( options[i], "nofinal" ) == 0 )
- writeFirstFinal = false;
- else {
- //warning($1->loc) << "unrecognized write option" << endl;
- }
- }
-
if ( outputFormat == OutCode ) {
/* Force a newline. */
out << "\n";
genLineDirective( out );
- if ( strcmp( what, "data" ) == 0 ) {
+ if ( strcmp( args[0], "data" ) == 0 ) {
+ for ( int i = 1; i < nargs; i++ ) {
+ if ( strcmp( args[i], "noerror" ) == 0 )
+ writeErr = false;
+ else if ( strcmp( args[i], "noprefix" ) == 0 )
+ dataPrefix = false;
+ else if ( strcmp( args[i], "nofinal" ) == 0 )
+ writeFirstFinal = false;
+ else {
+ source_warning(loc) << "unrecognized write option \"" <<
+ args[i] << "\"" << endl;
+ }
+ }
writeOutData();
}
- else if ( strcmp( what, "init" ) == 0 ) {
+ else if ( strcmp( args[0], "init" ) == 0 ) {
+ for ( int i = 1; i < nargs; i++ ) {
+ source_warning(loc) << "unrecognized write option \"" <<
+ args[i] << "\"" << endl;
+ }
writeOutInit();
}
- else if ( strcmp( what, "exec" ) == 0 ) {
+ else if ( strcmp( args[0], "exec" ) == 0 ) {
+ for ( int i = 1; i < nargs; i++ ) {
+ if ( strcmp( args[i], "noend" ) == 0 )
+ hasEnd = false;
+ else {
+ source_warning(loc) << "unrecognized write option \"" <<
+ args[i] << "\"" << endl;
+ }
+ }
+
/* Must set labels immediately before writing because we may depend
* on the noend write option. */
setLabelsNeeded();
writeOutExec();
}
- else if ( strcmp( what, "eof" ) == 0 ) {
+ else if ( strcmp( args[0], "eof" ) == 0 ) {
+ for ( int i = 1; i < nargs; i++ ) {
+ source_warning(loc) << "unrecognized write option \"" <<
+ args[i] << "\"" << endl;
+ }
writeOutEOF();
}
else {
void prepareMachine();
virtual void finishRagelDef();
- void writeStatement( char *what, int nopts, char **options );
+ virtual void writeStatement( InputLoc &loc, int nargs, char **args );
/* Determine if we should use indicies. */
virtual void calcIndexSize() {}
CodeGenData::CodeGenData( ostream &out )
:
- fileName(0),
+ sourceFileName(0),
fsmName(0),
out(out),
redFsm(0),
setValueLimits();
}
+ostream &CodeGenData::source_warning( const InputLoc &loc )
+{
+ cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": warning: ";
+ return cerr;
+}
+
+ostream &CodeGenData::source_error( const InputLoc &loc )
+{
+ gblErrorCount += 1;
+ assert( sourceFileName != 0 );
+ cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": ";
+ return cerr;
+}
+
+
void lineDirective( ostream &out, char *fileName, int line )
{
* Collecting the machine.
*/
- char *fileName;
+ char *sourceFileName;
char *fsmName;
ostream &out;
RedFsmAp *redFsm;
void prepareMachine();
bool hasBeenPrepared;
+ ostream &source_warning(const InputLoc &loc);
+ ostream &source_error(const InputLoc &loc);
+
/* The interface to the code generator. */
virtual void finishRagelDef() {}
- virtual void writeStatement( char *what, int nopts, char **options ) {}
+ virtual void writeStatement( InputLoc &loc, int nargs, char **args ) {}
};
void lineDirective( ostream &out, char *fileName, int line );
void genLineDirective( ostream &out );
-CodeGenData *makeCodeGen( char *fileName, char *fsmName, ostream &out, bool wantComplete );
+CodeGenData *makeCodeGen( char *sourceFileName,
+ char *fsmName, ostream &out, bool wantComplete );
#endif /* _GENDATA_H */
for ( int p = 0; p < redFsm->nParts; p++ ) {
char suffix[10];
sprintf( suffix, suffFormat, p );
- char *fn = fileNameFromStem( fileName, suffix );
- char *include = fileNameFromStem( fileName, ".h" );
+ char *fn = fileNameFromStem( sourceFileName, suffix );
+ char *include = fileNameFromStem( sourceFileName, ".h" );
/* Create the filter on the output and open it. */
output_filter *partFilter = new output_filter( fn );
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, TAG_write, TAG_curstate, TAG_access, TAG_break,
- TAG_option;
+ TAG_arg;
}%%
%% write instance_data;
}
}
else {
- cgd = makeCodeGen( sourceFileName, fsmName, *outStream, wantComplete );
+ cgd = makeCodeGen( sourceFileName, fsmName,
+ *outStream, wantComplete );
}
::keyOps = &cgd->thisKeyOps;
tag_write: tag_write_head write_option_list '/' TAG_write
final {
- Attribute *what = $1->tag->findAttr( "what" );
- if ( what == 0 ) {
- error($1->loc) << "tag <write> requires a what attribute" << endl;
- }
- else {
- writeOptions.append(0);
- cgd->writeStatement( what->value, writeOptions.length()-1, writeOptions.data );
- writeOptions.empty();
- }
+ writeOptions.append(0);
+ cgd->writeStatement( $1->loc, writeOptions.length()-1, writeOptions.data );
+ writeOptions.empty();
};
nonterm tag_write_head
{
- XMLTag *tag;
InputLoc loc;
};
tag_write_head: TAG_write
final {
Attribute *nameAttr = $1->tag->findAttr( "def_name" );
- if ( nameAttr == 0 ) {
+ 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" << endl;
- }
- else {
- CodeGenMapEl *mapEl = codeGenMap.find( nameAttr->value );
- assert( mapEl != 0 );
- cgd = mapEl->value;
- }
+ if ( lineAttr == 0 )
+ error($1->loc) << "tag <write> requires a line attribute" << endl;
+ if ( colAttr == 0 )
+ error($1->loc) << "tag <write> requires a col attribute" << endl;
- ::keyOps = &cgd->thisKeyOps;
+ if ( nameAttr != 0 && lineAttr != 0 && colAttr != 0 ) {
+ CodeGenMapEl *mapEl = codeGenMap.find( nameAttr->value );
+ if ( mapEl == 0 )
+ error($1->loc) << "internal error: cannot find codeGen" << endl;
+ else {
+ cgd = mapEl->value;
+ ::keyOps = &cgd->thisKeyOps;
+ }
- $$->tag = $1->tag;
- $$->loc = $1->loc;
+ $$->loc.line = atoi(lineAttr->value);
+ $$->loc.col = atoi(colAttr->value);
+ }
};
-write_option_list: write_option_list tag_option;
+write_option_list: write_option_list tag_arg;
write_option_list: ;
-nonterm tag_option
+nonterm tag_arg
{
char *option;
};
-tag_option: TAG_option '/' TAG_option
+tag_arg: TAG_arg '/' TAG_arg
final {
writeOptions.append( $3->tag->content );
};
/* Get content for closing tags. */
if ( token == TK_CloseTag ) {
switch ( tagId->id ) {
- case TAG_host: case TAG_option:
+ case TAG_host: case TAG_arg:
case TAG_t: case TAG_alphtype:
case TAG_text: case TAG_goto:
case TAG_call: case TAG_next:
curstate, TAG_curstate
access, TAG_access
break, TAG_break
-option, TAG_option
+arg, TAG_arg
cond_space_list, TAG_cond_space_list
cond_space, TAG_cond_space
cond_list, TAG_cond_list