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