/************************************************************************ * grammer - src/manip.c * Copyright (C) 2002 Marcello Barnaba * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 1, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * misc grammar manipulation functions . . . */ #include "manip.h" #include "parse.h" __inline char * print_part(Part *p) { static char bf[64]; p->n ? snprintf(bf, sizeof(bf), "%c%d", p->id, p->n) : snprintf(bf, sizeof(bf), "%c", p->id); return bf; } void __print_list(List *l, char c, bool p, char *sep) { register List *trav; if(p) outf("%c = { ", c); for(trav = l; trav; trav = trav->next) outf("%s%s", print_part(trav->item), trav->next ? sep : ""); if(p) outf(" }\n"); } __inline void print_2list(List *l1, List *l2) { outf("\t"); print_list_quiet(l1); outf(" -> "); print_list_quiet(l2); outf("\n"); } void print_prod(Prod *p) { register Prod *trav; outf("P = {\n"); for(trav = p; trav; trav = trav->next) print_2list(trav->sx, trav->dx); outf("}\n"); } void add_part(List **arr, Part **p) { List *na = xmalloc(sizeof(List)); na->item = *p; na->next = *arr; *arr = na; } Part *find_part(List *haystack, Part *needle) { register List *p = haystack; if(p->item) for(p = haystack; p && p->item; p = p->next) if(p->item->id == needle->id && p->item->n == needle->n) return p->item; return NULL; } bool verify_grammar(Grammar *g) { register Prod *ptrv; register List *ltrv; int foulness = 0; bool mNT, mS = true; for(ptrv = g->P; ptrv; NEXT(ptrv)) { mNT = true; for(ltrv = ptrv->sx; ltrv; NEXT(ltrv)) { if(IS_OR_SYMBOL(ltrv)) continue; if(mNT && find_part(g->V, ltrv->item)) mNT = false; if(mS && find_part(ltrv, g->S)) mS = false; if(!(find_part(g->X, ltrv->item) || find_part(g->V, ltrv->item))) { outf("%s not found in g->X or g->V . .\n", print_part(ltrv->item)); foulness++; } } if(mNT) { outf("NTless production in sx part:\n"); print_2list(ptrv->sx, ptrv->dx); foulness++; } for(ltrv = ptrv->dx; ltrv; NEXT(ltrv)) { if(IS_OR_SYMBOL(ltrv)) continue; if(!(find_part(g->X, ltrv->item) || find_part(g->V, ltrv->item))) { outf("%s not found in g->X or g->V . .\n", print_part(ltrv->item)); foulness++; } } } if(mS) { outf("Grammar doesn`t have any production with the start symbol (%s) in the sx part !\n", print_part(g->S)); foulness++; } return foulness ? false : true; }