source: trunk/athena/etc/track/sub_gram.y @ 14093

Revision 14093, 3.8 KB checked in by danw, 25 years ago (diff)
autoconfiscate
Line 
1%token ARROW WHITESPACE COLON BACKSLASH NEWLINE BACKNEW BANG WORD GEXCEPT ENDOFFILE
2%{
3#include "bellcore-copyright.h"
4#include "mit-copyright.h"
5#include "track.h"
6extern FILE *yyin, *yyout;
7char linebuf[2048];
8char wordbuf[256];
9char *wordp;
10int wordcnt = 0;
11Entry* e = &entries[ 0];
12%}
13%%
14
15sublist : opt_space header entrylist
16        {
17            entnum = 0; /* signifies to printmsg() that parse is complete. */
18        }
19        ;
20header  :
21        {
22            clear_ent();
23            entrycnt = 1;
24            e = clear_ent();
25        }
26        | GEXCEPT opt_space COLON except COLON opt_space
27        {
28            savestr( &e->fromfile, "GLOBAL_EXCEPTIONS");
29
30            /* cram compiled-in default exceptions onto lists:
31             */
32            while ( wordp = next_def_except()) {
33                if ( file_pat( wordp))
34                     add_list_elt( wordp, DONT_TRACK, &e->patterns);
35                else add_list_elt( wordp,         DONT_TRACK, LIST( e->names));
36            }
37            /* XXX: global names should match both entry-children and
38             * should match occurences which are deep in an entry.
39             * it's ok to use linebuf for this,
40             * because we've processed linebuf's contents already.
41             */
42            for ( wordp = TEXT( e->names.table); wordp;
43                  wordp = TEXT( NEXT( wordp))) {
44                strcpy( linebuf, "*/");
45                strcat( linebuf, wordp);
46                add_list_elt( linebuf, DONT_TRACK, &e->patterns);
47            }
48            if ( e->names.table) { /* lie, to make extra-roomy global table */
49                 e->names.shift *= 8;
50                 list2hashtable( &e->names);
51            }
52            entrycnt++;
53            e = clear_ent();
54        }
55        ;
56entrylist :
57          |     entrylist entry opt_space
58        ;
59entry   : ARROW opt_space fromname COLON toname COLON shellcmd
60        {
61            savestr( &e->cmpfile, writeflag ? e->fromfile : e->tofile);
62            e->islink = 1;
63            entrycnt++;
64            e = clear_ent();
65        }
66        | fromname COLON toname COLON cmpname COLON except COLON shellcmd
67        {
68            if ( e->names.table) list2hashtable( &e->names);
69            entrycnt++;
70            e = clear_ent();
71        }
72        ;
73fromname: WORD opt_space
74        {
75            char *r = wordbuf;
76            while ( '/' == *r) r++;
77            savestr(&e->fromfile,r);
78            KEYCPY( e->sortkey, r);
79            e->keylen = strlen( r);
80            doreset();
81        }
82        ;
83toname  : opt_space
84        {
85            char *defname;
86
87            defname = e->fromfile;
88
89            savestr( &e->tofile, defname);
90            doreset();
91        }
92        | opt_word
93        {
94            char *r = wordbuf;
95            while ( '/' == *r) r++;
96            savestr(&e->tofile,r);
97            doreset();
98        }
99        ;
100cmpname : opt_space
101        {
102            savestr( &e->cmpfile, writeflag ? e->fromfile : e->tofile);
103            doreset();
104        }
105        | opt_word
106        {
107            char *r = wordbuf;
108            while ( '/' == *r) r++;
109            savestr(&e->cmpfile,r);
110            doreset();
111        }
112        ;
113except  : opt_space
114        | opt_space exlist opt_space
115        {
116            doreset();
117        }
118        ;
119exlist: exceptword
120        | exlist opt_space exceptword
121        ;
122exceptword:   WORD
123        {
124            wordp = wordbuf;            /* XXX lex returns longest match. */
125            wordcnt = DONT_TRACK;       /*     ->foo will thus come here. */
126            if ( ! strncmp( wordp, "->", 2)) {
127                 wordp += 2;
128                 wordcnt = FORCE_LINK;
129            }
130            if ( file_pat( wordp))
131                 add_list_elt( wordp, wordcnt, &e->patterns);
132            else add_list_elt( wordp,           wordcnt, LIST( e->names));
133        }
134        | ARROW opt_space WORD
135        {
136            /* set force_links bit, add to e->names.
137             */
138            if ( file_pat( wordbuf))
139                 add_list_elt( wordbuf, FORCE_LINK, &e->patterns);
140            else add_list_elt( wordbuf,           FORCE_LINK, LIST( e->names));
141        }
142        ;
143shellcmd: nullcmd NEWLINE
144        {
145            savestr(&e->cmdbuf,"");
146            doreset();
147        }
148        | nullcmd shline NEWLINE
149        {
150            savestr(&e->cmdbuf,linebuf);
151            doreset();
152        }
153        ;
154nullcmd:
155        | nullcmd WHITESPACE
156        | nullcmd BACKNEW
157        ;
158shline:   black
159        | shline black
160        | shline WHITESPACE
161        | shline BACKNEW
162        ;
163black:    WORD
164        | COLON
165        | BANG
166        | BACKSLASH
167        ;
168opt_word: opt_space WORD opt_space
169        ;
170opt_space:
171        | opt_space opt_ele
172        ;
173opt_ele : NEWLINE | WHITESPACE
174        ;
175%%
176
177#include "lex.yy.c"
178
179int
180yyerror(s)
181char *s;
182{
183        if ( parseflag) justshow();
184        sprintf(errmsg,"parser error -- '%s'.\n   bad element was near: %s\n",
185                s, wordbuf);
186        do_panic();
187}
Note: See TracBrowser for help on using the repository browser.