* yylex - finds the next token from the input stream,
* and returns its token type and value to the parser.
register struct toktab
*t
;
static struct toktab
*lasttok
= NULL
;
extern struct toktab
*getident(), *getnum(), *getstring(), *getop();
c
= cc
; /* skip spaces and comments */
while (c
!= EOF
&& (comflag
|| c
== COMMENT
|| isspace(c
))) {
if (c
== EOF
) { /* end of file */
if (isalpha(c
)) { /* gather ident or reserved word */
if ((t
= getident(c
, &cc
)) == NULL
)
else if (isdigit(c
)) { /* gather numeric literal */
if ((t
= getnum(c
, &cc
)) == NULL
)
else if (c
== '"' || c
== '\'') { /* gather string or cset literal */
if ((t
= getstring(c
, &cc
)) == NULL
)
else { /* gather longest legal operator */
if ((t
= getop(c
, &cc
)) == NULL
)
yylval
= OPNODE(t
->t_type
);
if (nlflag
&& lastend
&& (t
->t_flags
& BEGINNER
)) { /* insert a semicolon */
yylval
= OPNODE(SEMICOL
);
lastend
= t
->t_flags
& ENDER
;
* getident - gather an identifier beginning with ac.
* Character following identifier goes in cc.
struct toktab
*getident(ac
, cc
)
register struct toktab
*t
;
extern struct toktab
*findres();
syserr("out of string space");
syserr("out of string space");
if ((t
= findres()) != NULL
) {
yylval
= RESNODE(t
->t_type
);
yylval
= IDNODE(putident(p
-sfree
));
* findres - find a reserved word and return a pointer to
* its entry in the token table, or NULL if not reserved
register struct toktab
*t
;
if ((t
= restab
[c
- '_']) == NULL
)
while (t
->t_word
[0] == c
) {
if (strcmp(t
->t_word
, p
) == 0)
* getnum - gather a numeric literal
struct toktab
*getnum(ac
, cc
)
syserr("out of string space");
case 0: /* integer part */
if (isdigit(c
)) { r
= r
* 10 + tonum(c
); continue; }
if (c
== '.') { state
= 1; realflag
++; continue; }
if (tolower(c
) == 'e') { state
= 2; realflag
++; continue; }
err("invalid radix for integer literal", 0);
case 1: /* fractional part */
if (isdigit(c
)) continue;
if (tolower(c
) == 'e') { state
= 2; continue; }
case 2: /* optional exponent sign */
if (c
== '+' || c
== '-') { state
= 3; continue; }
case 3: /* first digit after e, e+, or e- */
if (isdigit(c
)) { state
= 4; continue; }
err("invalid real literal", 0);
case 4: /* remaining digits after e */
if (isdigit(c
)) continue;
case 5: /* first digit after r */
if ((isdigit(c
) || isletter(c
)) && tonum(c
) < r
)
err("invalid integer literal", 0);
case 6: /* remaining digits after r */
if (isdigit(c
) || isletter(c
)) {
if (tonum(c
) >= r
) { /* illegal digit for radix r */
err("invalid digit in integer literal", 0);
r
= tonum('z'); /* prevent more messages */
syserr("out of string space");
yylval
= REALNODE(putident(p
-sfree
));
yylval
= INTNODE(putident(p
-sfree
));
* getstring - gather a string literal, follow continuation
struct toktab
*getstring(ac
, cc
)
while ((c
= NEXTCHAR
) != sc
&& c
!= '\n' && c
!= EOF
) {
if (ctran
[c
] == ESCAPE
) {
else if (ctran
[c
] == 'x')
else if (ctran
[c
] == '^')
syserr("out of string space");
syserr("out of string space");
while ((c
= NEXTCHAR
) != EOF
&& isspace(c
)) ;
err("unclosed quote", 0);
if (ac
== '"') { /* have string */
yylval
= STRNODE(putident(p
-sfree
), p
-sfree
);
yylval
= CSETNODE(putident(p
-sfree
), p
-sfree
);
* ctlesc - translate a control escape -- backslash followed by
* caret and one character.
* octesc - translate an octal escape -- backslash followed by
* one, two, or three octal digits
c
= (c
<< 3) | (nc
- '0');
} while (isoctal(nc
) && i
++ < 3);
* hexesc - translate a hexadecimal escape -- backslash-x
* followed by one or two hexadecimal digits
if (nc
>= 'a' && nc
<= 'f')
else if (nc
>= 'A' && nc
<= 'F')
* getop - find the longest legal operator and return a pointer
* to its entry in the token table
struct toktab
*getop(ac
, cc
)
register struct optab
*state
;
while ((i
= state
->o_input
) && c
!= i
)
switch (state
->o_action
) {
err("invalid character", 0);