This repository was archived by the owner on Jul 22, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlexer.ts
More file actions
144 lines (132 loc) · 4.57 KB
/
lexer.ts
File metadata and controls
144 lines (132 loc) · 4.57 KB
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
import {LongException} from './exception/error';
import {LongNumber} from './tokens/number';
import {LongString} from './tokens/strings';
import {Token, operators, builtinFunctions} from './tokens/token';
/**
* The position or the index in the
* string data read from the specified
* filename
*
* Contains a position(which is the index),
* and a tail[boolean] (end of the file or not)
*/
export interface Position {
position: number;
tail: boolean;
}
export interface TokenAnalyse {
position: number;
data: string;
lineNumber: number;
}
/**
*
*
* @param {String} fileData The data in the file
* @param {Position} position The current position of the lexer
* in the whole string
* @param {String | null} character The current character
*
*/
export class LongLexicalAnalyser {
private readonly fileData: string;
private position: Position;
private character: string | null;
private tokens: Array<Token> = new Array();
private command: Array<Array<Token>> = new Array();
private lineNumber: number = 1;
/**
* @constructor
* @param fileData the data in the file
*/
constructor(fileData:string) {
this.fileData = fileData.toString();
this.position = {position: 0, tail: false};
this.character = this.setCurrentCharacter();
}
/**
* @private
*
* @returns {String | null} the current character or null
*/
public setCurrentCharacter = (): string | null => {
if (this.position.position == this.fileData.length) {
this.position.tail = true;
return null;
} else {
return this.fileData[this.position.position];
}
};
/**
* @public
*
* @returns the tokens and list of exceptions
*/
public createLexicalAnalyser = (): any => {
this.character = this.setCurrentCharacter();
while (this.character != null) {
if (this.character == ' ') {
// if we find a space character(end of a command)
// append the current list of tokens to the list
// of commands and clear the token(only if the token list
// is not empty)
if (this.tokens.length >= 0) {
this.command.push(this.tokens);
this.tokens = new Array();
}
} else if (Number.isInteger(parseInt(this.character))) {
// else, if the character converted to an integer
// is not **NaN**, we take it as a number a try
// to produce a new number
const number = new LongNumber({
position: this.position.position,
data: this.fileData,
lineNumber: this.lineNumber,
});
const numberInfo = number.createNumberToken();
// updating the position so that the lexer continues
// to tokenise after the number ends
this.position.position = numberInfo.position - 1;
this.tokens.push({
tokenType: 'number',
tokenData: numberInfo.number,
});
} else if (this.character == '"') {
// if the character is a quotation("")[The start of a string]
// keep track of the string till the string ends with
// another quotation mark and update the position
// and also add the new token to the token array
const string = new LongString(this.fileData, this.position.position);
const stringInfo = string.createLongString();
this.position.position = stringInfo.pos - 1;
this.tokens.push({
tokenType: stringInfo.data.length == 1 ? 'char' : 'string',
tokenData: stringInfo.data.toString(),
});
} else if (this.character == '\n') {
// update the line number count if the lexer
// encounter a newline character
this.lineNumber += 1;
} else if (operators.includes(this.character)) {
// if the current character is present in the array
// of operators(the character is an operator),
// append it to the token list
this.tokens.push({
tokenType: 'operator',
tokenData: this.character,
});
} else if (Object.keys(builtinFunctions).includes(this.character)) {
// if the character is present in the keys of
// the builtin character(#, !) push to
// token array with the type specified in the dict
this.tokens.push({
tokenType: builtinFunctions[this.character].type,
tokenData: this.character,
});
}
this.position.position += 1;
this.character = this.setCurrentCharacter();
}
return this.command;
};
}