]> ocean-lang.org Git - ocean/commitdiff
parsergen: add --tag option.
authorNeilBrown <neilb@suse.de>
Sun, 11 May 2014 04:21:26 +0000 (14:21 +1000)
committerNeilBrown <neilb@suse.de>
Sun, 15 Jun 2014 07:10:49 +0000 (17:10 +1000)
Normally parsergen extracts three secctions: header, code, and grammar.
With "--tag foo", it will ignore anything that doesn't start "foo:",
will extract "foo: header", "foo: code", and "foo: grammar", and only
complain if there are other "foo:" headers.

Signed-off-by: NeilBrown <neilb@suse.de>
csrc/parsergen.mdc

index 2cfcb45491d6f91f54e3dab24124c076c95e40b1..a7d107cfa168d2deb8895321fbfc930a3b5eba20 100644 (file)
@@ -58,6 +58,12 @@ sections: `header`, `code`, and `grammar`.  The first two will be
 literally copied into the generated `.c` and `.h`. files.  The last
 contains the grammar.  This is tokenised with "[scanner][]".
 
+If the `--tag` option is given, then any top level header that doesn't
+start with the tag is ignored, and the tag is striped from the rest.  So
+`--tag Foo`
+means that the three needed sections must be `Foo: header`, `Foo: code`,
+and `Foo: grammar`.
+
 [mdcode]: mdcode.html
 [scanner]: scanner.html
 
@@ -103,6 +109,9 @@ comparing we define `text_is` and `prtxt`, which should possibly go in
 `mdcode`.  `scanner` does provide `text_dump` which is useful for strings
 which might contain control characters.
 
+`strip_tag` is a bit like `strncmp`, but adds a test for a colon,
+because that is what we need to detect tags.
+
 ###### functions
        static int text_is(struct text t, char *s)
        {
@@ -114,6 +123,20 @@ which might contain control characters.
                printf("%.*s", t.len, t.txt);
        }
 
+       static int strip_tag(struct text *t, char *tag)
+       {
+               int skip = strlen(tag) + 1;
+               if (skip >= t->len ||
+                   strncmp(t->txt, tag, skip-1) != 0 ||
+                   t->txt[skip-1] != ':')
+                       return 0;
+               while (skip < t->len && t->txt[skip] == ' ')
+                       skip++;
+               t->len -= skip;
+               t->txt += skip;
+               return 1;
+       }
+
 ### Symbols
 
 Productions are comprised primarily of symbols - terminal and
@@ -2069,17 +2092,19 @@ grammar file).
                { "SLR",        0, NULL, 'S' },
                { "LALR",       0, NULL, 'L' },
                { "LR1",        0, NULL, '1' },
+               { "tag",        1, NULL, 't' },
                { "report",     0, NULL, 'R' },
                { "output",     1, NULL, 'o' },
                { NULL,         0, NULL, 0   }
        };
-       const char *options = "05SL1Ro:";
+       const char *options = "05SL1t:Ro:";
 
 ###### process arguments
        int opt;
        char *outfile = NULL;
        char *infile;
        char *name;
+       char *tag = NULL;
        int report = 1;
        enum grammar_type type = LR05;
        while ((opt = getopt_long(argc, argv, options,
@@ -2099,6 +2124,8 @@ grammar file).
                        report = 2; break;
                case 'o':
                        outfile = optarg; break;
+               case 't':
+                       tag = optarg; break;
                default:
                        fprintf(stderr, "Usage: parsergen ...\n");
                        exit(1);
@@ -2164,11 +2191,14 @@ parser with neither. "grammar" must be provided.
        struct code_node *code = NULL;
        struct code_node *gram = NULL;
        for (s = table; s; s = s->next) {
-               if (text_is(s->section, "header"))
+               struct text sec = s->section;
+               if (tag && !strip_tag(&sec, tag))
+                       continue;
+               if (text_is(sec, "header"))
                        hdr = s->code;
-               else if (text_is(s->section, "code"))
+               else if (text_is(sec, "code"))
                        code = s->code;
-               else if (text_is(s->section, "grammar"))
+               else if (text_is(sec, "grammar"))
                        gram = s->code;
                else {
                        fprintf(stderr, "Unknown content section: %.*s\n",