]> granicus.if.org Git - re2c/commitdiff
- Add -t switch to generate header with all types
authorhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Sun, 22 Apr 2007 14:56:40 +0000 (14:56 +0000)
committerhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Sun, 22 Apr 2007 14:56:40 +0000 (14:56 +0000)
re2c/bootstrap/parser.cc
re2c/bootstrap/scanner.cc
re2c/code.cc
re2c/main.cc
re2c/parser.h
re2c/parser.y
re2c/re.h
re2c/run_tests.sh.in
re2c/test/condition_05.cgtcondition_05.cgt.h.c [new file with mode: 0755]
re2c/test/condition_05.cgtcondition_05.cgt.h.h [new file with mode: 0755]
re2c/test/condition_05.cgtcondition_05.cgt.h.re [new file with mode: 0755]

index 753b9de1176a287a289cc5b5f1af8d770218f1e7..062e990800cd0744a1630435681d081a9f4530d9 100644 (file)
@@ -1822,7 +1822,7 @@ int yylex(){
 namespace re2c
 {
 
-void parse(Scanner& i, std::ostream& o)
+void parse(Scanner& i, std::ostream& o, std::ostream* h)
 {
        in = &i;
 
@@ -1870,6 +1870,10 @@ void parse(Scanner& i, std::ostream& o)
                                assert(it->second.second);
                                genCode(o, topIndent, it->second.second, &specMap, it->first, !--nCount);
                        }
+                       if (h)
+                       {
+                               genHeader(*h, 0, specMap);
+                       }
                }
                else if(spec)
                {
index 19ff702ca407c028868369a9a1d91ea433d05a59..fc4425c87a638d216e23441041412864423b1a0b 100644 (file)
@@ -1,4 +1,4 @@
-/* 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>
index 8268b5dc5a76a1649e5d25d40e7a908ae6fc18cf..ea5dc4cd7802f413a1d36c0dd4a1df7e2cc1a854 100644 (file)
@@ -1587,9 +1587,9 @@ void DFA::emit(std::ostream &o, uint& ind, const RegExpMap* specMap, const std::
        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()))
@@ -1663,13 +1663,13 @@ void genGetState(std::ostream &o, uint& ind, uint start_label)
        }
 }
 
-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";
                }
@@ -1677,7 +1677,7 @@ void genCondTable(std::ostream &o, uint ind, const RegExpMap* specMap)
        }
 }
 
-void genCondGoto(std::ostream &o, uint ind, const RegExpMap* specMap)
+void genCondGoto(std::ostream &o, uint ind, const RegExpMap& specMap)
 {
        if (cFlag && !bWroteCondCheck)
        {
@@ -1688,7 +1688,7 @@ void genCondGoto(std::ostream &o, uint ind, const RegExpMap* specMap)
                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";
                        }
@@ -1698,6 +1698,25 @@ void genCondGoto(std::ostream &o, uint ind, const RegExpMap* specMap)
        }
 }
 
+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)
@@ -1784,6 +1803,7 @@ void Scanner::config(const Str& cfg, const Str& val)
                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");
index cc1004410c56686c4122715ca221aac4629fa078..6cf792375643bd8f2c4af7baa89ba3fed23e9da5 100644 (file)
@@ -90,6 +90,7 @@ static const mbo_opt_struct OPTIONS[] =
        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"),
@@ -132,6 +133,8 @@ static void usage()
        "-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"
@@ -159,6 +162,7 @@ int main(int argc, char *argv[])
        int c;
        const char *sourceFileName = 0;
        const char *outputFileName = 0;
+       const char *headerFileName = 0;
 
        if (argc == 1)
        {
@@ -192,10 +196,6 @@ int main(int argc, char *argv[])
 
                        case 'f':
                        fFlag = true;
-                       if (bSinglePass) {
-                               std::cerr << "re2c: error: cannot combine -1 and -f switch\n";
-                               return 1;
-                       }
                        break;
 
                        case 'g':
@@ -215,6 +215,10 @@ int main(int argc, char *argv[])
                        case 's':
                        sFlag = true;
                        break;
+
+                       case 't':
+                       headerFileName = opt_arg;
+                       break;
                        
                        case '1':
                        bSinglePass = true;
@@ -247,11 +251,6 @@ int main(int argc, char *argv[])
                        }
                        
                        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;
@@ -260,7 +259,6 @@ int main(int argc, char *argv[])
                        case 'u':
                        nRealChars = 0x110000; /* 17 times w-Flag */
                        sFlag = true;
-                       wFlag = true;
                        uFlag = true;
                        break;
          
@@ -276,17 +274,33 @@ int main(int argc, char *argv[])
                }
        }
 
-       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];
        }
@@ -317,6 +331,7 @@ int main(int argc, char *argv[])
 
        // set up the output stream
        re2c::ofstream_lc output;
+       re2c::ofstream_lc header;
 
        if (outputFileName == 0 || (sourceFileName[0] == '-' && sourceFileName[1] == '\0'))
        {
@@ -328,6 +343,14 @@ int main(int argc, char *argv[])
                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);
@@ -346,7 +369,7 @@ int main(int argc, char *argv[])
 
                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;
@@ -356,6 +379,6 @@ int main(int argc, char *argv[])
        }
 
        bLastPass = true;
-       parse(scanner, output);
+       parse(scanner, output, header.is_open() ? &header : NULL);
        return 0;
 }
index 210fa6766b0c59e7d79f57cbaf332c4e846c3498..ed916656f5792a3a8e466dfe2c5d826b6018179e 100644 (file)
@@ -53,7 +53,7 @@ private:
 #endif
 };
 
-void parse(Scanner&, std::ostream&);
+extern void parse(Scanner&, std::ostream&, std::ostream*);
 
 } // end namespace re2c
 
index 09b0b9a131ed349d3713ee0f6623b485306fa6f0..0fe0b13dff23850a80eadbfba030dc292f824a6d 100644 (file)
@@ -351,7 +351,7 @@ int yylex(){
 namespace re2c
 {
 
-void parse(Scanner& i, std::ostream& o)
+void parse(Scanner& i, std::ostream& o, std::ostream* h)
 {
        in = &i;
 
@@ -399,6 +399,10 @@ void parse(Scanner& i, std::ostream& o)
                                assert(it->second.second);
                                genCode(o, topIndent, it->second.second, &specMap, it->first, !--nCount);
                        }
+                       if (h)
+                       {
+                               genHeader(*h, 0, specMap);
+                       }
                }
                else if(spec)
                {
index 19186b92460ba8f2b47b800f0423ca513fa5e83d..89c4d0fc78675057e36cd965558df605c514985b 100644 (file)
--- a/re2c/re.h
+++ b/re2c/re.h
@@ -493,8 +493,9 @@ typedef std::list<RuleOp*>              RuleOpList;
 
 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*);
index 2f67717c7d82a306cfae8ed7ef21ee50413fa88d..d2d3e89caf7eb2bb03ce4b05839f0e45009a8e9c 100644 (file)
@@ -3,30 +3,50 @@ _XPG=1
 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."
diff --git a/re2c/test/condition_05.cgtcondition_05.cgt.h.c b/re2c/test/condition_05.cgtcondition_05.cgt.h.c
new file mode 100755 (executable)
index 0000000..cd13ece
--- /dev/null
@@ -0,0 +1,150 @@
+/* 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;
+}
diff --git a/re2c/test/condition_05.cgtcondition_05.cgt.h.h b/re2c/test/condition_05.cgtcondition_05.cgt.h.h
new file mode 100755 (executable)
index 0000000..767b013
--- /dev/null
@@ -0,0 +1,5 @@
+/* Generated by re2c */
+enum YYCONDTYPE {
+       comment,
+       normal,
+}
diff --git a/re2c/test/condition_05.cgtcondition_05.cgt.h.re b/re2c/test/condition_05.cgtcondition_05.cgt.h.re
new file mode 100755 (executable)
index 0000000..7c702fa
--- /dev/null
@@ -0,0 +1,118 @@
+#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;
+}