aboutsummaryrefslogtreecommitdiffstats
path: root/utils/Burg/lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/Burg/lex.c')
-rw-r--r--utils/Burg/lex.c260
1 files changed, 260 insertions, 0 deletions
diff --git a/utils/Burg/lex.c b/utils/Burg/lex.c
new file mode 100644
index 0000000..3d6c5af
--- /dev/null
+++ b/utils/Burg/lex.c
@@ -0,0 +1,260 @@
+char rcsid_lex[] = "$Id$";
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include "b.h"
+#include "fe.h"
+#include "y.tab.h"
+
+static char buf[BUFSIZ];
+
+static int yyline = 1;
+
+typedef int (*ReadFn) ARGS((void));
+
+static char *StrCopy ARGS((char *));
+static int code_get ARGS((void));
+static int simple_get ARGS((void));
+static void ReadCharString ARGS((ReadFn, int));
+static void ReadCodeBlock ARGS((void));
+static void ReadOldComment ARGS((ReadFn));
+
+static char *
+StrCopy(s) char *s;
+{
+ char *t = (char *)zalloc(strlen(s) + 1);
+ strcpy(t,s);
+ return t;
+}
+
+static int
+simple_get()
+{
+ int ch;
+ if ((ch = getchar()) == '\n') {
+ yyline++;
+ }
+ return ch;
+}
+
+static int
+code_get()
+{
+ int ch;
+ if ((ch = getchar()) == '\n') {
+ yyline++;
+ }
+ if (ch != EOF) {
+ fputc(ch, outfile);
+ }
+ return ch;
+}
+
+void
+yypurge()
+{
+ while (code_get() != EOF) ;
+}
+
+
+static void
+ReadCharString(rdfn, which) ReadFn rdfn; int which;
+{
+ int ch;
+ int backslash = 0;
+ int firstline = yyline;
+
+ while ((ch = rdfn()) != EOF) {
+ if (ch == which && !backslash) {
+ return;
+ }
+ if (ch == '\\' && !backslash) {
+ backslash = 1;
+ } else {
+ backslash = 0;
+ }
+ }
+ yyerror1("Unexpected EOF in string on line ");
+ fprintf(stderr, "%d\n", firstline);
+ exit(1);
+}
+
+static void
+ReadOldComment(rdfn) ReadFn rdfn;
+{
+ /* will not work for comments delimiter in string */
+
+ int ch;
+ int starred = 0;
+ int firstline = yyline;
+
+ while ((ch = rdfn()) != EOF) {
+ if (ch == '*') {
+ starred = 1;
+ } else if (ch == '/' && starred) {
+ return;
+ } else {
+ starred = 0;
+ }
+ }
+ yyerror1("Unexpected EOF in comment on line ");
+ fprintf(stderr, "%d\n", firstline);
+ exit(1);
+}
+
+static void
+ReadCodeBlock()
+{
+ int ch;
+ int firstline = yyline;
+
+ while ((ch = getchar()) != EOF) {
+ if (ch == '%') {
+ ch = getchar();
+ if (ch != '}') {
+ yyerror("bad %%");
+ }
+ return;
+ }
+ fputc(ch, outfile);
+ if (ch == '\n') {
+ yyline++;
+ }
+ if (ch == '"' || ch == '\'') {
+ ReadCharString(code_get, ch);
+ } else if (ch == '/') {
+ ch = getchar();
+ if (ch == '*') {
+ fputc(ch, outfile);
+ ReadOldComment(code_get);
+ continue;
+ } else {
+ ungetc(ch, stdin);
+ }
+ }
+ }
+ yyerror1("Unclosed block of C code started on line ");
+ fprintf(stderr, "%d\n", firstline);
+ exit(1);
+}
+
+static int done;
+void
+yyfinished()
+{
+ done = 1;
+}
+
+int
+yylex()
+{
+ int ch;
+ char *ptr = buf;
+
+ if (done) return 0;
+ while ((ch = getchar()) != EOF) {
+ switch (ch) {
+ case ' ':
+ case '\f':
+ case '\t':
+ continue;
+ case '\n':
+ yyline++;
+ continue;
+ case '(':
+ case ')':
+ case ',':
+ case ':':
+ case ';':
+ case '=':
+ return(ch);
+ case '/':
+ ch = getchar();
+ if (ch == '*') {
+ ReadOldComment(simple_get);
+ continue;
+ } else {
+ ungetc(ch, stdin);
+ yyerror("illegal char /");
+ continue;
+ }
+ case '%':
+ ch = getchar();
+ switch (ch) {
+ case '%':
+ return (K_PPERCENT);
+ case '{':
+ ReadCodeBlock();
+ continue;
+ case 's':
+ case 'g':
+ case 't':
+ do {
+ if (ptr >= &buf[BUFSIZ]) {
+ yyerror("ID too long");
+ return(ERROR);
+ } else {
+ *ptr++ = ch;
+ }
+ ch = getchar();
+ } while (isalpha(ch) || isdigit(ch) || ch == '_');
+ ungetc(ch, stdin);
+ *ptr = '\0';
+ if (!strcmp(buf, "term")) return K_TERM;
+ if (!strcmp(buf, "start")) return K_START;
+ if (!strcmp(buf, "gram")) return K_GRAM;
+ yyerror("illegal character after %%");
+ continue;
+ default:
+ yyerror("illegal character after %%");
+ continue;
+ }
+ default:
+ if (isalpha(ch) ) {
+ do {
+ if (ptr >= &buf[BUFSIZ]) {
+ yyerror("ID too long");
+ return(ERROR);
+ } else {
+ *ptr++ = ch;
+ }
+ ch = getchar();
+ } while (isalpha(ch) || isdigit(ch) || ch == '_');
+ ungetc(ch, stdin);
+ *ptr = '\0';
+ yylval.y_string = StrCopy(buf);
+ return(ID);
+ }
+ if (isdigit(ch)) {
+ int val=0;
+ do {
+ val *= 10;
+ val += (ch - '0');
+ ch = getchar();
+ } while (isdigit(ch));
+ ungetc(ch, stdin);
+ yylval.y_int = val;
+ return(INT);
+ }
+ yyerror1("illegal char ");
+ fprintf(stderr, "(\\%03o)\n", ch);
+ exit(1);
+ }
+ }
+ return(0);
+}
+
+void
+yyerror1(str) char *str;
+{
+ fprintf(stderr, "line %d: %s", yyline, str);
+}
+
+void
+yyerror(str) char *str;
+{
+ yyerror1(str);
+ fprintf(stderr, "\n");
+ exit(1);
+}