/* ------------------------------------------------------------------------ @NAME : start_parse @INPUT : infile input stream we'll read from (or NULL if reading from string) instring input string we'll read from (or NULL if reading from stream) line line number of the start of the string (just use 1 if the string is standalone and independent; if it comes from a file, you should supply the line number where it starts for better error messages) (ignored if infile != NULL) @OUTPUT : @RETURNS : @DESCRIPTION: Prepares things for parsing, in particular initializes the lexical state and lexical buffer, prepares DLG for reading (either from a stream or a string), and reads the first token. @GLOBALS : @CALLS : initialize_lexer_state() alloc_lex_buffer() zzrdstream() or zzrdstr() zzgettok() @CALLERS : @CREATED : 1997/06/21, GPW @MODIFIED : -------------------------------------------------------------------------- */ static void start_parse (FILE *infile, char *instring, int line) { if ( (infile == NULL) == (instring == NULL) ) { internal_error ("start_parse(): exactly one of infile and " "instring may be non-NULL"); } initialize_lexer_state (); alloc_lex_buffer (ZZLEXBUFSIZE); if (infile) { zzrdstream (infile); } else { zzrdstr (instring); zzline = line; } zzendcol = zzbegcol = 0; zzgettok (); }
void zzsyn(char * text, int tok, char * egroup, SetWordType * eset, int etok, int k, char * bad_text) { static char msg [MAX_ERROR]; int len; #ifndef ALLOW_WARNINGS text = NULL; /* avoid "unused parameter" warning */ #endif /* Initial message: give location of error */ msg[0] = (char) 0; /* make sure string is empty to start! */ if (tok == zzEOF_TOKEN) strcat (msg, "at end of input"); else sprintf (msg, "found \"%s\"", bad_text); len = strlen (msg); /* Caller supplied neither a single token nor set of tokens expected... */ if (!etok && !eset) { syntax_error (msg); return; } else { strcat (msg, ", "); len += 2; } /* I'm not quite sure what this is all about, or where k would be != 1... */ if (k != 1) { sprintf (msg+len, "; \"%s\" not", bad_text); if (zzset_deg (eset) > 1) strcat (msg, " in"); len = strlen (msg); } /* This is the code that usually gets run */ if (zzset_deg (eset) > 0) { if (zzset_deg (eset) == 1) strcat (msg, "expected "); else strcat (msg, "expected one of: "); append_token_set (msg, eset); } else { sprintf (msg+len, "expected %s", zztokens[etok]); if (etok == ENTRY_CLOSE) { strcat (msg, " (skipping to next \"@\")"); initialize_lexer_state (); } } len = strlen (msg); if (egroup && strlen (egroup) > 0) sprintf (msg+len, " in %s", egroup); syntax_error (msg); }
/* ------------------------------------------------------------------------ @NAME : bt_parse_file () @INPUT : filename - name of file to open. If NULL or "-", we read from stdin rather than opening a new file. options @OUTPUT : top @RETURNS : 0 if any entries in the file had serious errors 1 if all entries were OK @DESCRIPTION: Parses an entire BibTeX file, and returns a linked list of ASTs (or, if you like, a forest) for the entries in it. (Any entries with serious errors are omitted from the list.) @GLOBALS : @CALLS : bt_parse_entry() @CREATED : 1997/01/18, from process_file() in bibparse.c @MODIFIED : @COMMENTS : This function bears a *striking* resemblance to bibparse.c's process_file(). Eventually, I plan to replace this with a generalized process_file() that takes a function pointer to call for each entry. Until I decide on the right interface for that, though, I'm sticking with this simpler (but possibly memory-intensive) approach. -------------------------------------------------------------------------- */ AST * bt_parse_file (char * filename, ushort options, boolean * status) { FILE * infile; AST * entries, * cur_entry, * last; boolean entry_status, overall_status; if (options & BTO_STRINGMASK) /* any string options set? */ { usage_error ("bt_parse_file: illegal options " "(string options not allowed"); } /* * If a string was given, and it's *not* "-", then open that filename. * Otherwise just use stdin. */ if (filename != NULL && strcmp (filename, "-") != 0) { InputFilename = filename; infile = fopen (filename, "r"); if (infile == NULL) { perror (filename); return 0; } } else { InputFilename = "(stdin)"; infile = stdin; } entries = NULL; last = NULL; #if 1 /* explicit loop over entries, with junk cleaned out by read_entry () */ overall_status = TRUE; /* assume success */ while ((cur_entry = bt_parse_entry (infile, InputFilename, options, &entry_status))) { overall_status &= entry_status; if (!entry_status) continue; /* bad entry -- try next one */ if (!cur_entry) break; /* at eof -- we're done */ if (last == NULL) /* this is the first entry */ entries = cur_entry; else /* have already seen one */ last->right = cur_entry; last = cur_entry; } #else /* let the PCCTS lexer/parser handle everything */ initialize_lexer_state (); ANTLR (bibfile (top), infile); #endif fclose (infile); InputFilename = NULL; if (status) *status = overall_status; return entries; } /* bt_parse_file() */