+%{
+/* lang.l 1.1 81/02/24 */
+
+#include <ctype.h>
+#include "y.tab.h"
+#include "config.h"
+
+#define tprintf if (do_trace) printf
+/*
+ * Key word table
+ */
+
+struct kt {
+ char *kt_name;
+ int kt_val;
+} key_words[] = {
+ "cpu", CPU, "ident", IDENT, "config", CONFIG, "options", OPTIONS,
+ "device", DEVICE, "controller", CONTROLLER, "uba", UBA, "mba", MBA,
+ "csr", CSR, "nexus", NEXUS, "drive", DRIVE, "vector", VECTOR,
+ "pseudo-device", PSEUDO_DEVICE, "flags", FLAGS, "trace", TRACE,
+ "disk", DISK, "tape", CONTROLLER, "slave", SLAVE, "at", AT,
+ 0,0,
+};
+%}
+WORD [A-Za-z_]+
+%%
+{WORD} {
+ int i;
+
+ if ((i = kw_lookup(yytext)) == -1)
+ {
+ yylval = (int) yytext;
+ tprintf("id(%s) ", yytext);
+ return ID;
+ }
+ tprintf("(%s) ", yytext);
+ return i;
+ }
+0[0-7]* {
+ yylval = octal(yytext);
+ tprintf("#O:%o ", yylval);
+ return NUMBER;
+ }
+0x[0-9a-f]+ {
+ yylval = hex(yytext);
+ tprintf("#X:%x ", yylval);
+ return NUMBER;
+ }
+[1-9][0-9]* {
+ yylval = atoi(yytext);
+ tprintf("#D:%d ", yylval);
+ return NUMBER;
+ }
+"?" {
+ yylval = -1;
+ tprintf("? ");
+ return NUMBER;
+ }
+\n/[ \t] {
+ yyline++;
+ tprintf("\n... ");
+ }
+\n {
+ yyline++;
+ tprintf("\n");
+ return SEMICOLON;
+ }
+^#.* { /* Ignored (comment) */; }
+[ \t]* { /* Ignored (white space) */; }
+";" { return SEMICOLON; }
+%%
+/*
+ * kw_lookup
+ * Look up a string in the keyword table. Returns a -1 if the
+ * string is not a keyword otherwise it returns the keyword number
+ */
+
+kw_lookup(word)
+register char *word;
+{
+ register struct kt *kp;
+
+ for (kp = key_words; kp->kt_name != 0; kp++)
+ if (eq(word, kp->kt_name))
+ return kp->kt_val;
+ return -1;
+}
+
+/*
+ * Number conversion routines
+ */
+
+octal(str)
+char *str;
+{
+ int num;
+
+ sscanf(str, "%o", &num);
+ return num;
+}
+
+hex(str)
+char *str;
+{
+ int num;
+
+ sscanf(str, "%x", &num);
+ return num;
+}