-
Notifications
You must be signed in to change notification settings - Fork 0
/
lexer.cpp
187 lines (174 loc) · 5.45 KB
/
lexer.cpp
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
#include "calcLex.h"
token curToken;
//this function opens the "filestream" var and returns true or false for success
ifstream filestream;
bool calcLexOpen(const char filename[])
{
filestream.open(filename, ios_base::in);
//returning true or false if the filestream is open
return filestream.is_open();
}
//this function finds the next token and outputs it
token calcLex()
{
curToken.clearData();
char currentChar;
while(1) //infinite loop, breaks through a return statement
{
//get the next char!
currentChar = filestream.get();
//used to ignore whitespace as a token
while( currentChar == ' ' || currentChar == '\t' || currentChar == '\n')
{
currentChar = filestream.get();
};
//if the current char is the end of a file, it returns the end of file symbol
if(currentChar == EOF)
{
curToken.type(endOfFileSym);
return curToken;
}
//this is the comment logic: if the next chars are /*...
if(followingChars("/*", currentChar, curToken))
{
//then while it isn't ending the line, or finding the end of comment sentinel...
while(currentChar != '\n' && !followingChars("*/", currentChar, curToken))
{
//move onto the next character
currentChar = filestream.get();
}
//move to the next character after the comment or line has ended
//hop back up to the top of the while loop
continue;
}
//if the chars ":=" are found, return the assignment symbol
if(followingChars(":=", currentChar, curToken))
{
curToken.type(assignSym);
curToken.data(":=");
return curToken;
}
//if the chars "read" are found, return the read symbol
if(followingChars("read", currentChar, curToken))
{
curToken.type(readSym);
curToken.data("read");
return curToken;
}
//if the chars "write" are found, return the write symbol
if(followingChars("write", currentChar, curToken))
{
curToken.type(writeSym);
curToken.data("write");
return curToken;
}
//if this is put above the followingChars, it adds a duplicate letter.
curToken.appendChar(currentChar);
//checks for identifier strings only starting with letters and underscores
if( isalpha(currentChar) || (currentChar == '_') )
{
while( isalnum(currentChar = filestream.get()) || (currentChar == '_'))
{
curToken.appendChar(currentChar);
}
//once the currentChar falls off the end of the identifier string, it must hop back to read the next one
filestream.unget();
//returns the identifier int
curToken.type(identifier);
return curToken;
}
//if the current char is a number
if(isdigit(currentChar))
{
while ( isdigit(currentChar = filestream.get()) || currentChar == '.')
{
if (currentChar == '.')
{
curToken.appendChar(currentChar);
currentChar = filestream.get();
if (!isdigit(currentChar))
{
curToken.type(numConstError);
return curToken;
}
while (isdigit(currentChar))
{
curToken.appendChar(currentChar);
currentChar = filestream.get();
}
filestream.unget();
curToken.type(numConst);
return curToken;
}
curToken.appendChar(currentChar);
}
filestream.unget();
curToken.type(numConst);
return curToken;
}
if(currentChar == '+')
{
curToken.type(addOp);
curToken.data("+");
return curToken;
}
if(currentChar == '-')
{
curToken.type(subOp);
curToken.data("-");
return curToken;
}
if(currentChar == '*')
{
curToken.type(multOp);
curToken.data("*");
return curToken;
}
if(currentChar == '/')
{
curToken.type(divOp);
curToken.data("/");
return curToken;
}
if(currentChar == '(')
{
curToken.type(leftParen);
curToken.data("(");
return curToken;
}
if(currentChar == ')')
{
curToken.type(rightParen);
curToken.data(")");
return curToken;
}
curToken.type(unknownError);
return curToken;
}
curToken.type(unknownError); //this should never get here
return curToken;
}
//function that finds if the chars following match a target symbol
bool followingChars(string target, char currentChar, token curToken)
{
for(int x = 0; x < target.length(); x++)
{
if(currentChar == target[x])
{
curToken.appendChar(currentChar);
currentChar = filestream.get();
}
else
{
curToken.clearData();
while(x != 0)
{
filestream.unget();
x--;
}
return false;
}
}
filestream.unget();
return true;
}