namespace re2c
{
-void parse(Scanner& i, std::ostream& o)
+void parse(Scanner& i, std::ostream& o, std::ostream* h)
{
in = &i;
assert(it->second.second);
genCode(o, topIndent, it->second.second, &specMap, it->first, !--nCount);
}
+ if (h)
+ {
+ genHeader(*h, 0, specMap);
+ }
}
else if(spec)
{
-/* Generated by re2c 0.13.0.dev on Wed Apr 18 16:04:00 2007 */
+/* Generated by re2c 0.11.1.dev on Sat Apr 21 11:15:09 2007 */
#line 1 "scanner.re"
/* $Id$ */
#include <stdlib.h>
if (bProlog)
{
- genCondTable(o, ind, specMap);
+ genCondTable(o, ind, *specMap);
genGetState(o, ind, start_label);
- genCondGoto(o, ind, specMap);
+ genCondGoto(o, ind, *specMap);
}
if (cFlag && (bFlag || !condName.empty()))
}
}
-void genCondTable(std::ostream &o, uint ind, const RegExpMap* specMap)
+void genCondTable(std::ostream &o, uint ind, const RegExpMap& specMap)
{
if (cFlag && !bWroteCondCheck && gFlag)
{
- o << indent(ind++) << "static void *" << mapCodeName["yyctable"] << "[" << specMap->size() << "] = {\n";
+ o << indent(ind++) << "static void *" << mapCodeName["yyctable"] << "[" << specMap.size() << "] = {\n";
- for(RegExpMap::const_iterator it = specMap->begin(); it != specMap->end(); ++it)
+ for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it)
{
o << indent(ind) << "&&" << condPrefix << it->first << ",\n";
}
}
}
-void genCondGoto(std::ostream &o, uint ind, const RegExpMap* specMap)
+void genCondGoto(std::ostream &o, uint ind, const RegExpMap& specMap)
{
if (cFlag && !bWroteCondCheck)
{
else
{
o << indent(ind) << "switch(" << mapCodeName["YYCONDITION"] << ") {\n";
- for(RegExpMap::const_iterator it = specMap->begin(); it != specMap->end(); ++it)
+ for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it)
{
o << indent(ind) << "case " << it->first << ": goto " << condPrefix << it->first << ";\n";
}
}
}
+void genHeader(std::ostream &o, uint ind, const RegExpMap& specMap)
+{
+ o << "/* Generated by re2c " PACKAGE_VERSION;
+ if (!bNoGenerationDate)
+ {
+ o << " on ";
+ time_t now = time(&now);
+ o.write(ctime(&now), 24);
+ }
+ o << " */\n";
+ //TODO: o << headerFileInfo;
+ o << indent(ind++) << "enum " << mapCodeName["YYCONDTYPE"] << " {\n";
+ for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it)
+ {
+ o << indent(ind) << it->first << ",\n";
+ }
+ o << indent(--ind) << "}\n";
+}
+
std::ostream& operator << (std::ostream& o, const file_info& li)
{
if (li.ln && !iFlag)
mapVariableKeys.insert("variable:yyctable");
mapVariableKeys.insert("variable:yytarget");
mapDefineKeys.insert("define:YYCONDITION");
+ mapDefineKeys.insert("define:YYCONDTYPE");
mapDefineKeys.insert("define:YYCTXMARKER");
mapDefineKeys.insert("define:YYCTYPE");
mapDefineKeys.insert("define:YYCURSOR");
mbo_opt_struct('i', 0, "no-debug-info"),
mbo_opt_struct('o', 1, "output"),
mbo_opt_struct('s', 0, "nested-ifs"),
+ mbo_opt_struct('t', 1, "header"),
mbo_opt_struct('u', 0, "unicode"),
mbo_opt_struct('v', 0, "version"),
mbo_opt_struct('V', 0, "vernum"),
"-s --nested-ifs Generate nested ifs for some switches. Many compilers\n"
" need this assist to generate better code.\n"
"\n"
+ "-t --header Generate a header file with type definitions.\n"
+ "\n"
"-u --unicode Implies -w but supports the full Unicode character set.\n"
"\n"
"-v --version Show version information.\n"
int c;
const char *sourceFileName = 0;
const char *outputFileName = 0;
+ const char *headerFileName = 0;
if (argc == 1)
{
case 'f':
fFlag = true;
- if (bSinglePass) {
- std::cerr << "re2c: error: cannot combine -1 and -f switch\n";
- return 1;
- }
break;
case 'g':
case 's':
sFlag = true;
break;
+
+ case 't':
+ headerFileName = opt_arg;
+ break;
case '1':
bSinglePass = true;
}
case 'w':
- if (uFlag)
- {
- std::cerr << "re2c: error: cannot combine -w and -u switch\n";
- return 1;
- }
nRealChars = (1<<16); /* 0x10000 */
sFlag = true;
wFlag = true;
case 'u':
nRealChars = 0x110000; /* 17 times w-Flag */
sFlag = true;
- wFlag = true;
uFlag = true;
break;
}
}
- if (bFlag && bSinglePass) {
- std::cerr << "re2c: error: cannot combine -1 and -f switch\n";
+ if ((bFlag || fFlag) && bSinglePass) {
+ std::cerr << "re2c: error: Cannot combine -1 and -b or -f switch\n";
return 1;
}
+ if (!cFlag && headerFileName)
+ {
+ std::cerr << "re2c: error: Can only output a header file when using -c switch\n";
+ return 2;
+ }
if (wFlag && eFlag)
{
- usage();
+ std::cerr << "re2c: error: Cannot combine -e with -w or -u switch\n";
+ return 2;
+ }
+ if (wFlag && uFlag)
+ {
+ std::cerr << "re2c: error: Cannot combine -u with -w switch\n";
return 2;
}
- else if (argc == opt_ind + 1)
+
+ if (uFlag)
+ {
+ wFlag = true;
+ }
+
+ if (argc == opt_ind + 1)
{
sourceFileName = argv[opt_ind];
}
// set up the output stream
re2c::ofstream_lc output;
+ re2c::ofstream_lc header;
if (outputFileName == 0 || (sourceFileName[0] == '-' && sourceFileName[1] == '\0'))
{
cerr << "re2c: error: cannot open " << outputFileName << "\n";
return 1;
}
+ if (headerFileName)
+ {
+ if (!header.open(headerFileName).is_open())
+ {
+ cerr << "re2c: error: cannot open " << headerFileName << "\n";
+ return 1;
+ }
+ }
Scanner scanner(source, output);
sourceFileInfo = file_info(sourceFileName, &scanner);
outputFileInfo = file_info(outputFileName, &output);
null_stream null_dev;
Scanner null_scanner(null_source, null_dev);
- parse(null_scanner, null_dev);
+ parse(null_scanner, null_dev, NULL);
next_label = 0;
next_fill_index = 0;
bWroteGetState = false;
}
bLastPass = true;
- parse(scanner, output);
+ parse(scanner, output, header.is_open() ? &header : NULL);
return 0;
}
#endif
};
-void parse(Scanner&, std::ostream&);
+extern void parse(Scanner&, std::ostream&, std::ostream*);
} // end namespace re2c
namespace re2c
{
-void parse(Scanner& i, std::ostream& o)
+void parse(Scanner& i, std::ostream& o, std::ostream* h)
{
in = &i;
assert(it->second.second);
genCode(o, topIndent, it->second.second, &specMap, it->first, !--nCount);
}
+ if (h)
+ {
+ genHeader(*h, 0, specMap);
+ }
}
else if(spec)
{
extern void genCode(std::ostream&, uint&, RegExp*, const RegExpMap*, const std::string&, bool);
extern void genGetState(std::ostream&, uint&, uint);
-extern void genCondTable(std::ostream &o, uint, const RegExpMap*);
-extern void genCondGoto(std::ostream &o, uint, const RegExpMap*);
+extern void genCondTable(std::ostream &o, uint, const RegExpMap&);
+extern void genCondGoto(std::ostream &o, uint, const RegExpMap&);
+extern void genHeader(std::ostream &o, uint, const RegExpMap&);
extern RegExp *mkDiff(RegExp*, RegExp*);
extern RegExp *mkAlt(RegExp*, RegExp*);
result=0
errcnt=0
tstcnt=0;
+#diff='diff -u -I "#line [0-9]*"'
+diff='diff -u'
for x in @top_srcdir@/test/*.re `find @top_srcdir@/lessons -name '*.re'|sort`; do
tstcnt=$(($tstcnt+1))
switches=`basename $x|sed -e 's/^[^.]*\.\(.*\)\.re$/-\1/g' -e 's/^[^-].*//g'`
- genname=`echo $switches|sed -e 's,^.[^o]*$,,g' -e 's,^-[^o]*o\(.*\),@builddir@/test/\1,g'`
- switches=`echo $switches|sed -e 's,^-\([^o]*\)o\(.*\)$,-\1o@builddir@/test/\2,g'`
+ genname=`echo $switches|sed -e 's,^.[^o]*$,,g' -e 's,^[^ot]*t.*o.*$,,g' -e 's,^-[^o]*o\(.*\),@builddir@/test/\1,g'`
+ headers=`echo $switches|sed -e 's,^.[^t]*$,,g' -e 's,^[^ot]*o.*t.*$,,g' -e 's,^-[^t]*t\(.*\),@builddir@/test/\1,g'`
+ switches=`echo $switches|sed -e 's,^-\([^ot]*[ot]\)\(.*\)$,-\1@builddir@/test/\2,g'`
# don't use the -o flag, since it makes it harder to diff.
echo $x: $switches
- outname=@builddir@/test/`basename ${x%.re}.temp`
- difname=@builddir@/test/`basename ${x%.re}.diff`
+ outname=@builddir@/test/`basename ${x%.re}.c.temp`
+ outdiff=@builddir@/test/`basename ${x%.re}.c.diff`
+ typname=@builddir@/test/`basename ${x%.re}.h.temp`
+ typdiff=@builddir@/test/`basename ${x%.re}.h.diff`
@builddir@/re2c $switches $x 2>&1 | sed -e "s,$x,`basename $x`,g" -e "s,/\* Generated by re2c .*\*/,/\* Generated by re2c \*/,g" > $outname
if test -n "$genname"; then
cat $genname | sed -e 's,@builddir@/test/,,g' -e "s,/\* Generated by re2c .*\*/,/\* Generated by re2c \*/,g" > $outname
rm $genname
fi
-# if diff -u -I '#line [0-9]*' ${x%.re}.c $outname > $difname; then
- if diff -u ${x%.re}.c $outname > $difname; then
- echo "Passed."
+ ok=1
+ if test -n "$headers"; then
+ cat $headers | sed -e 's,@builddir@/test/,,g' -e "s,/\* Generated by re2c .*\*/,/\* Generated by re2c \*/,g" > $typname
+ rm $headers
+ if ${diff} ${x%.re}.h $typname > $typdiff; then
+ echo "Passed header test."
+ else
+ echo "Failed: ${x%.re}.h ${x%.re}.h.temp differ."
+ result=1
+ errcnt=$(($errcnt+$ok))
+ ok=0
+ fi
+ fi
+ if ${diff} ${x%.re}.c $outname > $outdiff; then
+ if test $ok = 1; then
+ echo "Passed."
+ fi
rm $outname
else
- echo "Failed: ${x%.re}.c ${x%.re}.temp differ."
+ echo "Failed: ${x%.re}.c ${x%.re}.c.temp differ."
result=1
- errcnt=$(($errcnt+1))
+ errcnt=$(($errcnt+$ok))
fi
- test -f $difname -a ! -s $difname && rm -f $difname
+ test -f $outdiff -a ! -s $outdiff && rm -f $outdiff
+ test -f $typdiff -a ! -s $typdiff && rm -f $typdiff
done
if test $result = 0; then
echo "All $tstcnt tests passed successfully."
--- /dev/null
+/* Generated by re2c */
+#line 1 "condition_05.cgtcondition_05.cgt.h.re"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define BSIZE 8192
+
+typedef struct Scanner
+{
+ FILE *fp;
+ unsigned char *cur, *tok, *lim, *eof;
+ unsigned char buffer[BSIZE];
+} Scanner;
+
+int fill(Scanner *s, int len)
+{
+ if (!len)
+ {
+ s->cur = s->tok = s->lim = s->buffer;
+ s->eof = 0;
+ }
+ if (!s->eof)
+ {
+ int got, cnt = s->tok - s->buffer;
+
+ if (cnt > 0)
+ {
+ memcpy(s->buffer, s->tok, s->lim - s->tok);
+ s->tok -= cnt;
+ s->cur -= cnt;
+ s->lim -= cnt;
+ }
+ cnt = BSIZE - cnt;
+ if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
+ {
+ s->eof = &s->lim[got];
+ }
+ s->lim += got;
+ }
+ else if (s->cur + len > s->eof)
+ {
+ return 0; /* not enough input data */
+ }
+ return -1;
+}
+
+char scan(Scanner *s)
+{
+ int state = 1;
+
+ fill(s, 0);
+
+ for(;;)
+ {
+ s->tok = s->cur;
+
+#line 59 "<stdout>"
+ {
+ unsigned char yych;
+ static void *yyctable[2] = {
+ &&yyc_comment,
+ &&yyc_normal,
+ };
+ goto *yyctable[state];
+/* *********************************** */
+yyc_comment:
+
+ if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; };
+ yych = *s->cur;
+ if(yych != '*') goto yy4;
+ ++s->cur;
+ if((yych = *s->cur) == '/') goto yy5;
+yy3:
+#line 80 "condition_05.cgtcondition_05.cgt.h.re"
+ {
+ goto yyc_comment;
+ }
+#line 80 "<stdout>"
+yy4:
+ yych = *++s->cur;
+ goto yy3;
+yy5:
+ ++s->cur;
+#line 76 "condition_05.cgtcondition_05.cgt.h.re"
+ {
+ continue;
+ }
+#line 90 "<stdout>"
+/* *********************************** */
+yyc_normal:
+ if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; };
+ yych = *s->cur;
+ if(yych != '/') goto yy11;
+ ++s->cur;
+ if((yych = *s->cur) == '*') goto yy12;
+yy10:
+#line 71 "condition_05.cgtcondition_05.cgt.h.re"
+ {
+ fputc(*s->tok, stdout);
+ continue;
+ }
+#line 104 "<stdout>"
+yy11:
+ yych = *++s->cur;
+ goto yy10;
+yy12:
+ ++s->cur;
+#line 67 "condition_05.cgtcondition_05.cgt.h.re"
+ {
+ goto yyc_comment;
+ }
+#line 114 "<stdout>"
+ }
+#line 84 "condition_05.cgtcondition_05.cgt.h.re"
+
+ }
+}
+
+int main(int argc, char **argv)
+{
+ Scanner in;
+ char c;
+
+ if (argc != 2)
+ {
+ fprintf(stderr, "%s <file>\n", argv[0]);
+ return 1;;
+ }
+
+ memset((char*) &in, 0, sizeof(in));
+
+ if (!strcmp(argv[1], "-"))
+ {
+ in.fp = stdin;
+ }
+ else if ((in.fp = fopen(argv[1], "r")) == NULL)
+ {
+ fprintf(stderr, "Cannot open file '%s'\n", argv[1]);
+ return 1;
+ }
+
+ scan(&in);
+
+ if (in.fp != stdin)
+ {
+ fclose(in.fp);
+ }
+ return 0;
+}
--- /dev/null
+/* Generated by re2c */
+enum YYCONDTYPE {
+ comment,
+ normal,
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define BSIZE 8192
+
+typedef struct Scanner
+{
+ FILE *fp;
+ unsigned char *cur, *tok, *lim, *eof;
+ unsigned char buffer[BSIZE];
+} Scanner;
+
+int fill(Scanner *s, int len)
+{
+ if (!len)
+ {
+ s->cur = s->tok = s->lim = s->buffer;
+ s->eof = 0;
+ }
+ if (!s->eof)
+ {
+ int got, cnt = s->tok - s->buffer;
+
+ if (cnt > 0)
+ {
+ memcpy(s->buffer, s->tok, s->lim - s->tok);
+ s->tok -= cnt;
+ s->cur -= cnt;
+ s->lim -= cnt;
+ }
+ cnt = BSIZE - cnt;
+ if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
+ {
+ s->eof = &s->lim[got];
+ }
+ s->lim += got;
+ }
+ else if (s->cur + len > s->eof)
+ {
+ return 0; /* not enough input data */
+ }
+ return -1;
+}
+
+char scan(Scanner *s)
+{
+ int state = 1;
+
+ fill(s, 0);
+
+ for(;;)
+ {
+ s->tok = s->cur;
+/*!re2c
+
+re2c:define:YYCTYPE = "unsigned char";
+re2c:define:YYCURSOR = s->cur;
+re2c:define:YYLIMIT = s->lim;
+re2c:define:YYMARKER = s->ptr;
+re2c:define:YYFILL = "{ if(fill(s, 2) >= 0) break; }";
+re2c:define:YYCONDITION = state;
+re2c:yyfill:parameter = 0;
+re2c:indent:top = 2;
+
+<normal> "/*"
+ {
+ goto yyc_comment;
+ }
+<normal> [^]
+ {
+ fputc(*s->tok, stdout);
+ continue;
+ }
+<comment> "*" "/"
+ {
+ continue;
+ }
+<comment> [^]
+ {
+ goto yyc_comment;
+ }
+
+*/
+ }
+}
+
+int main(int argc, char **argv)
+{
+ Scanner in;
+ char c;
+
+ if (argc != 2)
+ {
+ fprintf(stderr, "%s <file>\n", argv[0]);
+ return 1;;
+ }
+
+ memset((char*) &in, 0, sizeof(in));
+
+ if (!strcmp(argv[1], "-"))
+ {
+ in.fp = stdin;
+ }
+ else if ((in.fp = fopen(argv[1], "r")) == NULL)
+ {
+ fprintf(stderr, "Cannot open file '%s'\n", argv[1]);
+ return 1;
+ }
+
+ scan(&in);
+
+ if (in.fp != stdin)
+ {
+ fclose(in.fp);
+ }
+ return 0;
+}