⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gram.c

📁 Ripper 分类算法
💻 C
字号:
/****************************************************************************** gram.c - load and print grammars******************************************************************************/#include <stdio.h>#include "ripper.h"/*****************************************************************************//* global data managed in this file */vec_t *Grammar = NULL;int Max_priority;/* how to print operators */static char *Op_name[] = { "(null op)", "=", "!=", "<=", ">=", " ~ ", " !~ "};/*****************************************************************************//* recursive-descent parser for grammars syntax: grammar_file ::- rule* rule ::- atom --> rhs rhs ::- stop rhs ::- gsym (',' gsym)* gsym ::- !atom gsym ::- atom [ op atom ] op ::- '='  op ::- '!='  op ::- '>='  op ::- '<='  convention: everything except ld_rule advances past the last token   of the constituent*/static void ld_rule(atom_t *,vec_t *);static vec_t *ld_rhs(atom_t *);static gsym_t *ld_condition(atom_t *);static symbol_t *operator(atom_t *);static int mark_priority(symbol_t *);/* punctuation -- used globally */static BOOL Initialized=FALSE;static symbol_t *Arrow,*Bar,*Stop,*Sep,*Wildcard;BOOL ld_grammar(file,is_default,data)char *file;int is_default;vec_t *data;{    vec_t *grammar;    atom_t *tok;    symbol_t *op;    if (!Initialized) {	Initialized=TRUE;	Wildcard = intern("*"); Wildcard->kind = WILDCARD;	Arrow = intern("-->");	Bar = intern("|");	Stop = intern(".");	Sep = intern(",");	op = intern("=");	op->kind = OPERATOR; op->index = OPEQ;	op = intern("!=");	op->kind = OPERATOR; op->index = OPNEQ;	op = intern("<=");	op->kind = OPERATOR; op->index = OPLE;	op = intern(">=");	op->kind = OPERATOR; op->index = OPGE;	op = intern("~");	op->kind = OPERATOR; op->index = OPIN;	op = intern("!~");	op->kind = OPERATOR; op->index = OPOUT;    }    if (!Grammar) Grammar = new_vec(grule_t);    else clear_vec(grule_t,Grammar);    Max_priority = 0;    if (!lex_open(file) && !is_default) {	warning("can't open grammar file %s--using defaults",file) ;    } else {	while ((tok=lex())!=NULL) {	    ld_rule(tok,Grammar);	}	lex_close();    }    if (!complete_grammar(data)) {	error("grammar is incomplete");	return FALSE;    }    if (!index_grammar(data)) {	error("problem in indexing grammar");	return FALSE;    }    return TRUE;}static void ld_rule(tok,grammar)atom_t *tok;vec_t *grammar;{    grule_t rule;    int p;    BOOL badrule = FALSE;    if ((p = mark_priority(tok->nom))!=0) {        rule.priority = p;	if (p > Max_priority) Max_priority = p;	tok = safe_lex();    } else {	rule.priority = 0;    }    if (!tok->nom) {	lex_error("grammar rule right-hand side must be a symbol");	rule.lhs = intern("???");	badrule = TRUE;    } else {	rule.lhs = tok->nom;    }    if (tok->nom->kind && tok->nom->kind!=NONTERM) {	lex_error("symbol '%s' from grammar file is used elsewhere",		  tok->nom->name);	warning("rules for grammar symbol '%s' will be ignored",		tok->nom->name);	badrule = TRUE;    } else {	rule.lhs->kind = NONTERM;    }    tok = safe_lex();     lex_verify(tok,Arrow);    tok = safe_lex();    rule.rhs = ld_rhs(tok);    if (!badrule) {	ext_vec(grule_t,grammar,&rule);    }    while ((tok=last_lex())->nom==Bar) {	tok=safe_lex();	rule.rhs = ld_rhs(tok);	if (!badrule) {	    ext_vec(grule_t,grammar,&rule);	}    }    lex_verify(tok,Stop);}static vec_t *ld_rhs(tok)atom_t *tok;{    vec_t *rhs;    gsym_t *s;    rhs = new_vec(gsym_t);    if (tok->nom!=Stop) {	s = ld_condition(tok);	if (s) ext_vec(gsym_t,rhs,s);	while (last_lex()->nom==Sep) {	    tok = safe_lex();	    s = ld_condition(tok);	    if (s) ext_vec(gsym_t,rhs,s);	}    }    return rhs;}static gsym_t *ld_condition(tok)atom_t *tok;{    static gsym_t sym;    atom_t atm;    symbol_t *n;    sym.nonterm = NULL;    sym.attr_index = NULLINDEX;    sym.op = NULLOP;    atm.nom = sym.value.nom = NULL;    atm.num = sym.value.num = 0.0;    if (!tok->nom) {	lex_error("illegal grammar symbol %g ignored",tok->num);	tok = safe_lex();	return NULL;    } else if (tok->nom && tok->nom->kind!=ATTRIBUTE) {	sym.nonterm = tok->nom;	tok = safe_lex();	return &sym;    } else /* tok->nom && tok->nom is an attribute */ {	sym.attr_index = tok->nom->index;	tok = safe_lex();	if (n=operator(tok)) {	    sym.op = (operator_t) n->index;	    tok = safe_lex();	    copy(atom_t,&sym.value,tok);	    safe_lex();	} else {	    lex_error("expected an operator -- supplying '='");	    sym.op = OPEQ;	    tok = safe_lex();	    copy(atom_t,&sym.value,tok);	    safe_lex();	}	return &sym;    }}static int mark_priority(mark) /* return n for token "!^n" else 0 */symbol_t *mark;{    char *cp;    int p=0;        for (cp=mark->name; *cp; cp++)       if (*cp=='!') p++;      else return 0;    return p;}static symbol_t *operator(tok)  /* return NULL if not operator, else op name */atom_t *tok;{    if (tok->nom->kind==OPERATOR) return tok->nom;    else return NULL;}/*****************************************************************************/void fprint_gsym(FILE *fp, gsym_t *sym){    if (!sym) {	fprintf(fp,"(null)");    } else if (sym->nonterm) {	fprint_symbol(fp,sym->nonterm);    } else {	fprintf(fp,"%s",field_name(sym->attr_index));	fprintf(fp,Op_name[sym->op]);	fprint_atom(fp,&(sym->value));    }}void fshow_gsym(fp,sym)FILE *fp;gsym_t *sym;{    if (!sym) {	fprintf(fp,"(null)");    } else if (sym->nonterm) {	fprint_symbol(fp,sym->nonterm);    } else {	fprintf(fp,"%s %s ",field_name(sym->attr_index),Op_name[sym->op]);	if (sym->value.nom==NULL) fprintf(fp,"%g",sym->value.num);	else fprintf(fp,"%s",sym->value.nom->name);    }}gsym_t *ld_gsym(fp)FILE *fp;{    gsym_t *gsym;    symbol_t *sym,*op;    char word_buf[BUFSIZ];    char *ptr;    double d,strtod(const char *,char **);    if (!Initialized) {	Initialized=TRUE;	op = intern("=");	op->kind = OPERATOR; op->index = OPEQ;	op = intern("!=");	op->kind = OPERATOR; op->index = OPNEQ;	op = intern("<=");	op->kind = OPERATOR; op->index = OPLE;	op = intern(">=");	op->kind = OPERATOR; op->index = OPGE;	op = intern("~");	op->kind = OPERATOR; op->index = OPIN;	op = intern("!~");	op->kind = OPERATOR; op->index = OPOUT;    }    fscanf(fp,"%s",word_buf);     if (strcmp(word_buf,"(null)")==0) {	return NULL;    } else if (strcmp(word_buf,".")==0) {	return NULL;    } else {	gsym = newmem(1,gsym_t);	/* attribute op value */	sym = intern(word_buf);	if (sym->kind!=ATTRIBUTE) {	    error("bad attribute %s in rule condition",word_buf);	    gsym->attr_index = 0;	} else {	    gsym->attr_index = sym->index;	}	fscanf(fp,"%s",word_buf); 	sym = intern(word_buf);	if (sym->kind!=OPERATOR) {	    error("bad operator %s in rule condition",word_buf);	    gsym->op = OPEQ;	} else {	    gsym->op = sym->index;	}	fscanf(fp,"%s",word_buf); 	if (continuous_field(gsym->attr_index)) {	    d = strtod(word_buf,&ptr);	    gsym->value.nom = NULL;	    if (ptr!=word_buf) {		gsym->value.num = d;	    }	    else {		lex_error("attribute '%s' should have a continuous value",			  field_name(gsym->attr_index));		gsym->value.num = 0;	    }	} else {	    gsym->value.nom = intern(word_buf);	}    }    /* printf("   condition: "); print_gsym(gsym); printf("\n"); */    return gsym;}void print_grammar(){    int i,j;    grule_t *rule;    for (i=0; i<vmax(Grammar); i++) {	rule = vref(grule_t,Grammar,i);	for (j=0; j<rule->priority; j++) printf("!");	print_symbol(rule->lhs); 	printf(" --> "); 	for (j=0; j<vmax(rule->rhs); j++) {	    if (j>0) printf(",");	    print_gsym(vref(gsym_t,rule->rhs,j));	}	printf(".\n");    }}BOOL contains_wildcard(gsym)gsym_t *gsym;{    return         gsym->nonterm==NULL 	&& gsym->value.nom!=NULL 	&& gsym->value.nom->kind==WILDCARD;}/*****************************************************************************/#ifdef TEST/* main: test driver*/int main(int,char**);main(argc,argv)int argc;char *argv[];{    if (argc<=3) {	fatal("syntax: test-grammar namesfile datafile grammarfile");    }    (void)ld_names(argv[1]);    (void)ld_data(argv[2]);    ld_grammar(argv[3],NULL);    printf("\n\n**** names information ****\n\n");    print_names();    printf("\n\n**** grammar after completion ****\n\n");    print_grammar();    print_grammar_indices();/*  printf("\n\n**** symbol table ***\n\n");    show_hashtab();*/    return 0;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -