Lexical Analyzer
Lexical Analyzer
cpp 1
1 #include <stdio.h>
2 #include <ctype.h>
3
4 #define LETTER 0
5 #define DIGIT 1
6 #define UNKNOWN 99
7
8 // Token codes
9 #define INT_LIT 10
10 #define IDENT 11
11 #define ASSIGN_OP 20
12 #define ADD_OP 21
13 #define SUB_OP 22
14 #define MULT_OP 23
15 #define DIV_OP 24
16 #define LEFT_PAREN 25
17 #define RIGHT_PAREN 26
18
19 // Global variables
20 int charClass;
21 char lexeme[100];
22 char nextChar;
23 int lexLen;
24 int token;
25 int nextToken;
26 FILE* in_fp, * fopen();
27
28 // Function declarations
29 void addChar();
30 void getChar();
31 void getNonBlank();
32 int lex();
33 int lookup(char ch);
34
35 // Main driver
36 int main() {
37 // Open the input data file and process its contents
38 if (fopen_s(&in_fp, "front.in", "r") != 0) {
39 printf("ERROR - cannot open front.in \n");
40 }
41 else {
42 getChar();
43 do
44 lex();
45 while (nextToken != EOF);
46 }
47 return 0;
48 }
49
...g\LexicalAnalyzer\LexicalAnalyzer\LexicalAnalyzer.cpp 2
50 // lookup - a function to lookup operators and parentheses and return the
token
51 int lookup(char ch) {
52 switch (ch) {
53 case '(':
54 addChar();
55 nextToken = LEFT_PAREN;
56 break;
57 case ')':
58 addChar();
59 nextToken = RIGHT_PAREN;
60 break;
61 case '+':
62 addChar();
63 nextToken = ADD_OP;
64 break;
65 case '-':
66 addChar();
67 nextToken = SUB_OP;
68 break;
69 case '*':
70 addChar();
71 nextToken = MULT_OP;
72 break;
73 case '/':
74 addChar();
75 nextToken = DIV_OP;
76 break;
77 default:
78 addChar();
79 nextToken = EOF;
80 break;
81 }
82 return nextToken;
83 }
84
85 // addChar - a function to add nextChar to lexeme
86 void addChar() {
87 if (lexLen <= 98) {
88 lexeme[lexLen++] = nextChar;
89 lexeme[lexLen] = 0;
90 }
91 else {
92 printf("Error - lexeme is too long \n");
93 }
94 }
95
96 // getChar - a function to get the next character of input and determine
its character class
...g\LexicalAnalyzer\LexicalAnalyzer\LexicalAnalyzer.cpp 3
97 void getChar() {
98 if ((nextChar = getc(in_fp)) != EOF) {
99 if (isalpha(nextChar))
100 charClass = LETTER;
101 else if (isdigit(nextChar))
102 charClass = DIGIT;
103 else
104 charClass = UNKNOWN;
105 }
106 else {
107 charClass = EOF;
108 }
109 }
110
111 // getNonBlank - a function to call getChar until it returns a non-
whitespace character
112 void getNonBlank() {
113 while (isspace(nextChar))
114 getChar();
115 }
116
117 // lex - a simple lexical analyzer for arithmetic expressions
118 int lex() {
119 lexLen = 0;
120 getNonBlank();
121 switch (charClass) {
122 // Parse identifiers
123 case LETTER:
124 addChar();
125 getChar();
126 while (charClass == LETTER || charClass == DIGIT) {
127 addChar();
128 getChar();
129 }
130 nextToken = IDENT;
131 break;
132 // Parse integer literals
133 case DIGIT:
134 addChar();
135 getChar();
136 while (charClass == DIGIT) {
137 addChar();
138 getChar();
139 }
140 nextToken = INT_LIT;
141 break;
142 // Parentheses and operators
143 case UNKNOWN:
144 lookup(nextChar);
...g\LexicalAnalyzer\LexicalAnalyzer\LexicalAnalyzer.cpp 4
145 getChar();
146 break;
147 // EOF
148 case EOF:
149 nextToken = EOF;
150 lexeme[0] = 'E';
151 lexeme[1] = '0';
152 lexeme[2] = 'F';
153 lexeme[3] = 0;
154 break;
155 } // End of switch
156 printf("Next token is: %d, Next lexeme is %s\n", nextToken, lexeme);
157 return nextToken;
158 }
159