File: lex.l

package info (click to toggle)
newsgate 1.6-22
  • links: PTS
  • area: non-free
  • in suites: etch, etch-m68k
  • size: 340 kB
  • ctags: 313
  • sloc: ansic: 2,686; yacc: 504; sh: 278; lex: 183; perl: 151; makefile: 111
file content (187 lines) | stat: -rw-r--r-- 3,890 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
**  Lexical analyzer for the gag language.  We have our own FSA
**  for comments because it's much smaller and quicker that way.
*/
%{
/* SUPPRESS 15 on yyt *//* Copying a bad pointer */
/* SUPPRESS 25 on yycrank *//* Creating a bad pointer during initialization */
/* SUPPRESS 26 on yyt *//* Storing a bad pointer */
/* SUPPRESS 592 on ncform_sccsid *//* Static variable was not used */
/* SUPPRESS 593 on yyfussy *//* Label was not used */
#include "gate.h"
#include "gag.h"

/* State of our automaton. */
typedef enum _STATE {
    S_STAR, S_NORMAL, S_END
} STATE;

/* Key-value pair. */
typedef struct _PAIR {
    STRING	name;
    int		value;
} PAIR;

char		yyfilename[SM_SIZE];
int		yylineno;
extern int	Errors;

/* List of GAG's keywords. */
STATIC PAIR	Keywords[] = {
    {	"default",		tDEFAULT	},
    {	"directory",		tDIRECTORY	},
    {	"distributions",	tDISTRIBUTIONS	},
    {	"dotify",		tDOTIFY		},
    {	"false",		tFALSE		},
    {	"flags",		tFLAGS		},
    {	"gateway",		tGATEWAY	},
    {	"inews",		tINEWS		},
    {	"mail2news",		tMAIL2NEWS	},
    {	"mailcontact",		tMAILCONTACT	},
    {	"mailhost",		tMAILHOST	},
    {	"mailinglist",		tMAILINGLIST	},
    {	"mailpost",		tMAILPOST	},
    {	"moderator",		tMODERATOR	},
    {	"news2mail",		tNEWS2MAIL	},
    {	"organization",		tORGANIZATION	},
    {	"owner",		tOWNER		},
    {	"request_address",	tREQUESTADDR	},
    {	"site",			tSITE		},
    {	"true",			tTRUE		},
    {	"user",			tUSER		},
    {	NULL,			0		}
};

%}

%%

[-+0-9A-Za-z_.]+	{
		    /* A simple tID or keyword. */
		    register PAIR	*p;

		    /* Keyword? */
		    for (p = Keywords; p->name; p++)
			if (EQ(p->name, yytext))
			    return p->value;
		    yylval.String = COPY(yytext);
		    return tID;
		    /* NOTREACHED */
		}

^#[ \t]+[0-9]+[ \t]+"[^\n]+"[^\n]*$	{
		    /* C pre-processor control line. */
		    register char	*p;
		    char		*namep;

		    /* Find the line number. */
		    for (p = yytext; *p && !isdigit(*p); p++)
			continue;
		    /* Parse the number, find the start of the filename. */
		    for (yylineno = atoi(p); *p && *p != '"'; p++)
			continue;
		    /* March down to the end of the filename. */
		    for (namep = p; *++p && *p != '"'; p++)
			continue;
		    *p = '\0';
		    (void)strncpy(yyfilename, namep, sizeof yyfilename - 1);
		    yyfilename[sizeof yyfilename - 1] = '\0';
		}

\"[^"]*		{
		    /* Quoted string. */
		    int		c;

		    /* See the Lex paper in Volume 2A or PS1:16
		     * for details on this code. */
		    if (yytext[yyleng - 1] == '\\')
			yymore();
		    else {
			if ((c = input()) == '"') {
			    yylval.String = COPY(&yytext[1]);
			    return tID;
			}
			unput(c);
			yyerror("Bad string");
		    }
		}

"/*"	        {
		    /* Comment. */
		    register STATE	S;

		    for (S = S_NORMAL; S != S_END; )
			switch (input()) {
			case '/':
			    if (S == S_STAR) {
				S = S_END;
				break;
			    }
			    /* FALLTHROUGH */
			default:
			    S = S_NORMAL;
			    break;
			case '\0':
			    S = S_END;
			    break;
			case '*':
			    S = S_STAR;
			    break;
			}
		}

[ \t\n]		{
		    /* Tasty whitespace. */
		}

.		{
		    /* Random special character. */
		    return *yytext;
		    /* NOTREACHED */
		}

%%


/*
**  Called by lex at end-of-stream.  Return one if no more input.
*/
int
yywrap()
{
    return 1;
}


void
yyopen(p)
    char	*p;
{
    if (p == NULL)
	(void)strcpy(yyfilename, "stdin");
    else {
	if ((yyin = fopen(p, "r")) == NULL) {
	    Fprintf(stderr, "%s: Can't open \"%s\" for input, %s.\n",
		    Pname, p, strerror(errno));
	    exit(1);
	}
	(void)strcpy(yyfilename, p);
    }
}


/*
**  Write an error message.
*/
void
yyerror(p)
    char	*p;
{
    char	buff[SM_SIZE];

    (void)strncpy(buff, yytext, sizeof buff);
    buff[sizeof buff - 1] = '\0';
    Fprintf(stderr, "\"%s\", line %d: %s (near \"%s\")\n",
	    yyfilename, yylineno, p, buff);
    Errors++;
}