Pristine Ack-5.5
[Ack-5.5.git] / util / topgen / LLlex.c
1 /* $Id: LLlex.c,v 1.6 1994/06/24 10:42:02 ceriel Exp $ */
2 /*
3  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4  * See the copyright notice in the ACK home directory, in the file "Copyright".
5  */
6 /* L L l e x . c
7  *
8  * Very simple lexical analyzer. 
9  * Also contains LLmessage().
10  */
11 # include <ctype.h>
12 # include <stdio.h>
13 # include "tunable.h"
14 # include "token.h"
15 # include "Lpars.h"
16
17 struct token dot;               /* current token */
18 static struct token aside;      /* to put currrent token aside, when a token
19                                  * is inserted
20                                  */
21 int     newline, lineno;        /* To keep track of linenumbers */
22 extern FILE *input;             /* file descriptor of machine table */
23
24 LLlex() {
25         register c;
26
27         if (aside.t_tokno) {    /* A token was pushed aside, return it now */
28                 dot = aside;
29                 aside.t_tokno = 0;
30                 return dot.t_tokno;
31         }
32         if (newline) {          /* delayed increment of lineno, needed to give
33                                  * correct line numbers in error messages
34                                  */
35                 lineno++;
36                 newline = 0;
37         }
38         c = getc(input);
39         while (c == '/') {      /* Could be a comment */
40                 if ((c = getc(input)) == '*') {
41                                 /* Yes, it is a comment */
42                         int l;
43
44                         l = lineno;
45                         do {
46                             do {
47                                 if (c == '\n') lineno++;
48                                 c = getc(input);
49                             } while (c != '*' && c != EOF);
50                             if (c != EOF) c = getc(input);
51                         } while (c != '/' && c != EOF);
52                         if (c == EOF) {
53                             c = lineno;
54                             lineno = l;
55                             error("Unterminated comment");
56                             lineno = c;
57                             c = EOF;
58                         }
59                         else c = getc(input);
60                 }
61                 else {
62                         ungetc(c, input);
63                         c = '/';
64                         break;
65                 }
66         }
67         dot.t_tokno = c;
68         dot.t_attrib = c;
69         if (isupper(c) || islower(c) || c == '_') {
70                 dot.t_tokno = LETTER;
71                 return LETTER;
72         }
73         if (isdigit(c)) {
74                 dot.t_tokno = DIGIT;
75                 return DIGIT;
76         }
77         switch(c) {
78           case line_term :
79                 dot.t_tokno = LINE_TERMINATOR;
80                 return LINE_TERMINATOR;
81           case operand_sep :
82                 dot.t_tokno = OPERAND_SEPARATOR;
83                 return OPERAND_SEPARATOR;
84           case instruction_sep :
85                 dot.t_tokno = INSTRUCTION_SEPARATOR;
86                 return INSTRUCTION_SEPARATOR;
87           case '-' :
88                 c = getc(input);
89                 if (c == '>') {
90                         dot.t_tokno = PATTERN_SEPARATOR;
91                         return PATTERN_SEPARATOR;
92                 }
93                 ungetc(c,input);
94                 dot.t_tokno = OTHER;
95                 return OTHER;
96           case open_bracket :
97                 dot.t_tokno = OPEN_BRACKET;
98                 return OPEN_BRACKET;
99           case close_bracket :
100                 dot.t_tokno = CLOSE_BRACKET;
101                 return CLOSE_BRACKET;
102           case '\n' :
103                 newline = 1;
104                 /* Fall through */
105           case ' ' :
106           case '\t' :
107                 dot.t_tokno = SPACE;
108                 return SPACE;
109           case '%' :
110           case EOF :
111                 return c;
112           default :
113                 /* Let the C-compiler find out what is illegal! */
114                 dot.t_tokno = OTHER;
115                 return OTHER;
116         }
117 }
118
119 LLmessage(d) {
120     static int savlineno;
121     
122     if (savlineno != lineno) {
123         /* Only an error message if on another line number */
124         savlineno = lineno;
125         error("Syntax error");
126     }
127     if (d > 0) {
128         /* "d" is the token to be inserted.
129          * This is the place to put the current token aside and
130          * give the inserted token an attribute ... but who cares
131          */
132         aside = dot;
133     }
134 }