1$C  /* Generate Compiler Module */
2COMPILER CR
3/**************************************************************************
4   COCO/R for C grammar used to generate COCO/R itself
5   1.17 Last modified Fri  09-06-02
6**************************************************************************/
7
8#include "crt.h"
9#include "crf.h"
10#include "cra.h"
11#include "crp.h"
12#include "crs.h"
13#include <string.h>
14#include <stdlib.h>
15
16static void FixString(char *name)
17{
18  int i, j, len, spaces, start;
19  len = strlen(name);
20  if (len == 2) { SemError(129); return; }
21  if (ignore_case) upcase(name);
22  spaces = FALSE; start = name[0];
23  for (i = 1; i <= len-2; i++) {
24    if (name[i] > 0 && name[i] <= ' ') spaces = TRUE;
25    if (name[i] == '\\') {
26      if (name[i+1] == '\\' || name[i+1] == '\'' || name[i+1] == '\"') {
27        for (j = i; j < len; j++) name[j] = name[j+1]; len--;
28      }
29    }
30  }
31  if (spaces) SemError(124);
32}
33
34static void MatchLiteral (int sp)
35/* store string either as token or as literal */
36{
37  PTermNode sn, sn1;
38  int matched_sp;
39
40  sn = GetTermP(sp);
41  matched_sp = MatchDFA((unsigned char *) sn->name, sp);
42  if (matched_sp != 0) {
43    sn1 = GetTermP(matched_sp);
44    sn1->type = T_CLASSLITTOKEN;
45    sn->type  = T_LITTOKEN;
46  } else sn->type= T_CLASSTOKEN;
47}
48
49static void SetCtx (int gp)
50/* set transition code to contextTrans */
51{
52  PGraphNode gn;
53  while (gp > 0) {
54    gn = GetGraphP(gp);
55    if (gn->type == T_CHAR || gn->type == T_CLASS)
56      gn->CONTEXT = T_CONTEXT;
57    else
58      if (gn->type == T_OPT || gn->type == T_REP)
59      SetCtx(gn->INNER);
60      else
61      if (gn->type == T_ALT) {
62      SetCtx(gn->INNER); SetCtx(gn->ALT);
63      }
64    gp = gn->next;
65  }
66}
67
68static void StringClass(char *s, Set *items)
69{
70  s[strlen(s)-1]=0;  s++;  /* Ignore First and Last character */
71  while (*s) Set_AddItem(items, *s++);
72}
73
74/**************************************************************************/
75
76CHARACTERS
77  letter   = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_" .
78  digit    = "0123456789" .
79  cntl     = CHR(0)..CHR(31).
80  tab      = CHR(9) .
81  eol      = CHR(13).
82  lf       = CHR(10) .
83  back     = CHR(92) .
84  noQuote1 = ANY - '"' - cntl - back .
85  noQuote2 = ANY - "'" - cntl - back .
86  graphic  = ANY - cntl .
87
88IGNORE tab + eol + lf
89
90TOKENS
91  ident     = letter {letter | digit} .
92  string    =   '"' {noQuote1 | back graphic } '"'
93              | "'" {noQuote2 | back graphic } "'" .
94  badstring =   '"' {noQuote1 | back graphic } ( eol | lf )
95              | "'" {noQuote2 | back graphic } ( eol | lf ) .
96  number    = digit {digit} .
97
98NAMES
99  Range   = "..".
100
101PRAGMAS
102  Options = "$" {letter}.
103                                (. char s[100];
104                                   LookAheadString(s, sizeof(s)-1);
105                                   SetOptions(s); .)
106
107COMMENTS
108  FROM "/*" TO "*/" NESTED
109
110PRODUCTIONS
111
112CR =                            (. Name name1;
113                                   int  attr, sem, exp, is_new, sp, type;
114                                   int startedDFA = FALSE;
115                                   PNTermNode sn; .)
116
117   "COMPILER"
118   Ident<compiler_name>         (. global_defs.pos  = S_NextPos;
119                                   global_defs.line = S_NextLine; .)
120   { ANY }                      (. global_defs.len  =
121                                     (int) (S_NextPos-global_defs.pos); .)
122   { Declaration<&startedDFA> }
123   SYNC                         (. if (Successful()) { /* No Errors so far */
124                                     if (!MakeDeterministic()) SemError(127);
125                                   } .)
126   "PRODUCTIONS"
127   {                            (. attr = NIL; sem = NIL; .)
128      Ident<name1>              (. if ((sp = FindSym(name1, &type)) != UNDEF) {
129                                     is_new = FALSE;
130                                     if (type != T_NT) { SemError(108); return; }
131                                     else {
132                                       sn = GetNTermP(sp);
133                                       if (sn->graph) SemError(107);
134                                       sn->line_dec = S_Line;
135                                     }
136                                   } else {
137                                     sp = NewSym(name1, T_NT);
138                                     sn = GetNTermP(sp); is_new = TRUE;
139                                     sn->line_dec = S_Line;
140                                   } .)
141      [ Attribs<&attr> ]        (. if (!is_new) {
142                                     if (sn->has_attr && !attr) SemError(105);
143                                     if (!sn->has_attr && attr) SemError(105);
144                                   }
145                                   if (attr) {
146                                     sn->attr = attr; sn->has_attr = TRUE;
147                                   } .)
148      WEAK "="
149      [ SemText<&sem> ]
150      Expression<&exp>          (. if (sem) {
151                                     (void) LinkGraph(sem, exp); exp = sem;
152                                   } .)
153      WEAK "."                  (. sn = GetNTermP(sp); /* reload */
154                                   sn->graph = exp; .)
155      SYNC
156   }
157   "END" Ident<name1>           (. if (strcmp(name1, compiler_name)) SemError(117);
158                                   if((sp = FindSym(compiler_name, &type)) != UNDEF) {
159                                     if (type!=T_NT) SemError(108);
160                                     else {
161                                       sn = GetNTermP(sp);
162                                       if (sn->has_attr) SemError(112);
163                                       sn->reachable=TRUE;
164                                     }
165                                   } else SemError(111);
166                                   no_sym = NewSym("not", T_T); .)
167   "."                          (. if (dirty_DFA && !MakeDeterministic()) SemError(127); .)
168   .
169
170Declaration<int *startedDFA> =
171                                (. Set ignore;
172                                   int n1, n2, nested = FALSE; .)
173  (
174      "CHARACTERS" { SetDecl }
175    | "TOKENS"   { TokenDecl<T_T> }
176    | "NAMES"    { NameDecl }
177    | "PRAGMAS"  { TokenDecl<T_P> }
178    | "COMMENTS"
179      "FROM" TokenExpr<&n1>
180      "TO"   TokenExpr<&n2>
181      [ "NESTED"                (. nested = TRUE; .)
182      ]                         (. if (n1 * n2) NewComment(n1, n2, nested); .)
183    | "IGNORE"
184      ( "CASE"                  (. if (*startedDFA) SemError(130);
185                                   ignore_case = TRUE; .)
186       |                        (. Set_Init(&ignore); .)
187        CompSet<&ignore>        (. AddIgnore(&ignore);
188                                   if (Set_IsItem(&ignore,0)) SemError(119);
189                                   Set_Done(&ignore); .)
190      )
191   )                            (. *startedDFA = TRUE; .)
192   .
193
194SetDecl =
195                                (. Name name;
196                                   Set  items;
197                                   Set_Init(&items); .)
198
199   Ident<name>                  (. if (FindClass(name) != UNDEF) SemError(107); .)
200   "=" CompSet<&items> "."      (. if (Set_Empty(&items)) SemError(101);
201                                   (void) NewClass(name, &items);
202                                   Set_Done(&items); .)
203   .
204
205CompSet<PSet items> =
206                                (. Set set1, set2;
207                                   Set_Init(&set1); Set_Init(&set2); .)
208   SimSet<&set1>
209   { (  "+" SimSet<&set2>       (. Set_Union(&set1, &set2); .)
210      | "-" SimSet<&set2>       (. Set_Diference(&set1, &set2); .)
211     )                          (. Set_Clean(&set2); .)
212   }                            (. Set_Union(items, &set1);
213                                   Set_Done(&set1); Set_Done(&set2); .)
214   .
215
216SimSet<PSet items> =
217                                (. Name name;
218                                   char str[MAX_STR_LEN];
219                                   int n1, n2; .)
220
221     Ident<name>                (. if (FindClass(name) == UNDEF) SemError(115);
222                                   GetClassWithName(name, items); .)
223   | String<str>                (. StringClass(str, items); .)
224   | ChrSet<&n1>
225     ( ".." ChrSet<&n2>         (. Set_AddRange(items, n1, n2); .)
226      |                         (. Set_AddItem(items, n1); .)
227     )
228   | "ANY"                      (. Set_Union(items, &ANY_SET); .)
229   .
230
231ChrSet<int *n> =
232                                (. char str[5]; int x; .)
233   "CHR" "("
234   (   number                   (. LexString(str, sizeof(str)-1);
235                                   x = atoi(str);
236                                   if (x > 255) { SemError(118); x = 0; }
237                                   *n = x; .)
238     | string                   (. LexString(str, sizeof(str)-1);
239                                   if (strlen(str) != 3) SemError(118);
240                                   *n = str[1]; .)
241   ) ")"
242   .
243
244TokenDecl<int sec_type> =
245                                (. char name[MAX_STR_LEN];
246                                   int p = 0, sp, type; .)
247
248   (  Ident<name>               (. if ((sp = FindSym(name, &type)) != UNDEF) SemError(107);
249                                   else sp = NewSym(name, sec_type); .)
250      SYNC
251      ( "=" TokenExpr<&p>       (. if (sec_type == T_T) ConvertToStates(p, sp);
252                                   else  ConvertToStates(p, sp+FIRST_PRAGMA); .)
253        "."
254      |                         (. P_option = TRUE; .)
255      )
256    | String<name>              (. P_option = TRUE;
257                                   if ((sp = FindSym(name, &type)) != UNDEF) SemError(107);
258                                   else sp = NewSym(name, sec_type); .)
259   )
260
261   [ SemText<&p>                (. if (sec_type == T_T) SemError(114);
262                                   else SetPragmaText(sp, p); .)
263   ]
264   .
265
266Expression<int *n> =
267                                (. int n0 = NIL, n1, n2, SX_Line; .)
268   Term<&n1>
269   {  WEAK "|"                  (. if (n0 == NIL)
270                                     n0 = n1 = MakeGraph(T_ALT, n1);
271                                   SX_Line = S_Line; .)
272      Term<&n2>                 (. n2 = MakeGraph(T_ALT, n2);
273                                   SetGraphLine(n2,SX_Line);
274                                   n1 = LinkAltGraph(n1, n2); .)
275   }                            (. *n = (n0 ? n0 : n1); .)
276   .
277
278Term<int *n> =
279                                (. int n0 = NIL, n1, n2; .)
280   (  Factor<&n1>               (. n0 = n1; .)
281      { Factor<&n2>             (. n1 = LinkGraph(n1, n2); .)
282      }
283   |  /*Empty*/                 (. n0 = MakeSemGraph(T_SEM, -1, 0, S_Line, S_Col); .)
284   )                            (. *n = n0; .)
285   .
286
287Factor<int *n>  =
288                                (. char name1[MAX_STR_LEN];
289                                   int weak = 0, SX_Line;
290                                   int n1, n2 = NIL;
291                                   int sp, is_new, type;
292                                   PNTermNode snt; .)
293   (
294     ["WEAK"                    (. weak = 1; .)
295     ]
296     Symbol<name1>              (. sp = FindSym(name1, &type);
297                                   if (type == T_CLASS) SemError(104);
298                                   if (weak && type == T_T) type = T_WT;
299                                   if (weak && type == T_NT) SemError(123);
300                                   n1 = MakeGraph(type, sp);
301                                   if (type == T_NT) {
302                                     snt = GetNTermP(sp);
303                                     is_new = snt->graph == 0;
304                                     snt->line_use = S_Line;
305                                     snt->reachable = TRUE;
306                                   } .)
307     (  Attribs<&n2>            (. (void) LinkAltGraph(n1, n2);
308                                   if (type != T_NT) SemError(103);
309                                   else {
310                                     if(!is_new && !snt->has_attr) SemError(105);
311                                     if (is_new) snt->has_attr = TRUE;
312                                   } .)
313       |                        (. if (type == T_NT)
314                                   if (!is_new && snt->has_attr) SemError(105); .)
315     )
316   | "(" Expression<&n1> ")"
317   | "["                        (. SX_Line = S_Line .)
318      Expression<&n1> "]"       (. n1 = MakeGraph(T_OPT, n1);
319                                   SetGraphLine(n1,SX_Line) .)
320   | "{"                        (. SX_Line = S_Line .)
321      Expression<&n1> "}"       (. n1 = MakeGraph(T_REP, n1);
322                                   SetGraphLine(n1,SX_Line) .)
323   | SemText<&n1>
324   | "ANY"                      (. n1 = MakeGraph(T_ANY, 0); .)
325   | "SYNC"                     (. n1 = MakeGraph(T_SYNC, 0); .)
326   )                            (. *n = n1; .)
327   .
328
329TokenExpr<int *n> =
330                                (. int n0 = NIL, n1, n2; .)
331   TokenTerm<&n1>
332   { WEAK "|"                   (. if (n0 == NIL)
333                                   n0 = n1 = MakeGraph(T_ALT, n1); .)
334     TokenTerm<&n2>             (. n2 = MakeGraph(T_ALT, n2);
335                                   n1 = LinkAltGraph(n1, n2); .)
336   }                            (. *n = (n0 ? n0 : n1); .)
337   .
338
339TokenTerm<int *n> =
340                                (. int n0 = NIL, n1, n2; .)
341   TokenFactor<&n1>             (. n0 = n1; .)
342   { TokenFactor<&n2>           (. n1 = LinkGraph(n1, n2); .)
343   }
344   [ "CONTEXT"
345     "(" TokenExpr<&n2> ")"     (. SetCtx(n2); n1 = LinkGraph(n1, n2); .)
346   ]
347                                (. *n = n0; .)
348   .
349
350TokenFactor<int *n> =
351                                (. char name[MAX_STR_LEN];
352                                   int p = 0; .)
353
354   (  Ident<name>               (. if ((p = FindClass(name)) == UNDEF) {
355                                     /* Just Create a valid node */
356                                     p = MakeGraph(T_CHAR, 0);
357                                     SemError(115);
358                                   } else p = MakeGraph(T_CLASS, p); .)
359    | String<name>              (. p = StrToGraph((unsigned char *) name); .)
360    | "(" TokenExpr<&p> ")"
361    | "[" TokenExpr<&p> "]"     (. p = MakeGraphOp(T_OPT, p); .)
362    | "{" TokenExpr<&p> "}"     (. p = MakeGraphOp(T_REP, p); .)
363   )                            (. *n = p; .)
364   .
365
366Symbol<char *name> =
367                                (. int sp, type; .)
368    ( Ident<name>               (. sp = FindSym(name, &type);
369                                   if (sp == UNDEF) sp = NewSym(name, T_NT); .)
370    | String<name>              (. sp = FindSym(name, &type);
371                                   if (sp == UNDEF) {
372                                     sp = NewSym(name, T_T);
373                                     MatchLiteral(sp);
374                                   } .)
375    )
376    .
377
378Ident<char *s> =
379   ident                        (. LexString(s, MAX_ID_LEN-1) .)
380   .
381
382String<char *s> =
383   string                       (. LexString(s, MAX_STR_LEN-1);
384                                   FixString(s); .)
385   .
386
387Attribs<int *n> =
388                                (. long P;
389                                   int Len, Line, Col; .)
390     "<"                          (. P = S_Pos+1; Line = S_Line; Col = S_Col; .)
391     { ANY | badstring            (. SemError(102); .)
392     }
393     ">"                          (. Len = (int) (S_Pos - P);
394                                     *n = MakeSemGraph(T_ATTR, P, Len, Line, Col); .)
395   |
396     "<."                         (. P = S_Pos+2; Line = S_Line; Col = S_Col; .)
397     { ANY | badstring            (. SemError(102); .)
398     }
399     ".>"                         (. Len = (int) (S_Pos - P);
400                                     *n = MakeSemGraph(T_ATTR, P, Len, Line, Col); .)
401   .
402
403SemText<int *n> =
404                                (. long P;
405                                   int Len, Line, Col; .)
406   "(."                         (. P = S_Pos+2; Line = S_Line; Col = S_Col; .)
407   {   ANY
408     | badstring                (. SemError(102); .)
409     | "(."                     (. SemError(109); .)
410   }
411   ".)"                         (. Len = (int) (S_Pos - P);
412                                   *n = MakeSemGraph(T_SEM, P, Len, Line, Col); .)
413   .
414
415NameDecl =
416                                (. Name username, name; .)
417   Ident<username>
418   "="
419   (Ident<name> | String<name>)
420   "."                          (. NewName(name, username); .)
421   .
422
423END CR.
424