jlex 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/examples/manual-lexer.js +87 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
|
|
2
|
+
# jlex [](https://www.npmjs.com/package/jlex)
|
|
3
|
+
|
|
1
4
|
## Install
|
|
2
5
|
|
|
3
6
|
`npm i jlex`
|
|
@@ -104,7 +107,7 @@ When you execute the former program, you get:
|
|
|
104
107
|
|
|
105
108
|
## Using the lexer from a Jison grammar
|
|
106
109
|
|
|
107
|
-
In file [examples/grammar.jison](examples/grammar.jison) you'll find an example
|
|
110
|
+
In file [examples/grammar.jison](examples/grammar.jison#L32-L33) you'll find an example
|
|
108
111
|
of setting the generated lexer to be used from a Jison grammar. The key is
|
|
109
112
|
to set the `lex` attribute of the `parser` object to the generated lexer:
|
|
110
113
|
|
|
@@ -183,4 +186,9 @@ Here is a description of the attributes of the lexer object:
|
|
|
183
186
|
rules: [ /^(?:\s+)/, /^(?:[0-9]+)/, /^(?:-)/, /^(?:$)/, /^(?:.)/ ],
|
|
184
187
|
conditions: { INITIAL: { rules: [Array], inclusive: true } }
|
|
185
188
|
}
|
|
186
|
-
```
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Writing a Jison compatible lexer by hand
|
|
192
|
+
|
|
193
|
+
See file [examples/manual-lexer.js](examples/manual-lexer.js) to see an example that
|
|
194
|
+
illustrates how to write a Jison compatible lexer by hand.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const lexer = {
|
|
2
|
+
input: "",
|
|
3
|
+
index: 0,
|
|
4
|
+
|
|
5
|
+
yytext: "",
|
|
6
|
+
yylineno: 0, // base 0 internamente
|
|
7
|
+
yylloc: {},
|
|
8
|
+
|
|
9
|
+
setInput(input) {
|
|
10
|
+
this.input = input;
|
|
11
|
+
this.index = 0;
|
|
12
|
+
this.yylineno = 0;
|
|
13
|
+
this.column = 0;
|
|
14
|
+
return this;
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
lex() {
|
|
18
|
+
if (this.index >= this.input.length) {
|
|
19
|
+
return this.EOF;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Saltar espacios
|
|
23
|
+
while (/\s+/.test(this.input[this.index])) {
|
|
24
|
+
this.advance(this.input[this.index]);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (this.index >= this.input.length) {
|
|
28
|
+
return this.EOF;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const startLine = this.yylineno + 1; // Jison usa base 1
|
|
32
|
+
const startColumn = this.column;
|
|
33
|
+
|
|
34
|
+
const char = this.input[this.index];
|
|
35
|
+
|
|
36
|
+
// PLUS
|
|
37
|
+
if (char === "+") {
|
|
38
|
+
this.yytext = "+";
|
|
39
|
+
this.advance(char);
|
|
40
|
+
|
|
41
|
+
this.yylloc = {
|
|
42
|
+
first_line: startLine,
|
|
43
|
+
last_line: this.yylineno + 1,
|
|
44
|
+
first_column: startColumn,
|
|
45
|
+
last_column: this.column
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
return "PLUS";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// NUMBER (soporta múltiples dígitos)
|
|
52
|
+
if (/\d/.test(char)) {
|
|
53
|
+
let num = "";
|
|
54
|
+
|
|
55
|
+
while (/\d/.test(this.input[this.index])) {
|
|
56
|
+
num += this.input[this.index];
|
|
57
|
+
this.advance(this.input[this.index]);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
this.yytext = num;
|
|
61
|
+
|
|
62
|
+
this.yylloc = {
|
|
63
|
+
first_line: startLine,
|
|
64
|
+
last_line: this.yylineno + 1,
|
|
65
|
+
first_column: startColumn,
|
|
66
|
+
last_column: this.column
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
return "NUMBER";
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
throw new Error("Carácter inesperado: " + char);
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
advance(char) {
|
|
76
|
+
this.index++;
|
|
77
|
+
|
|
78
|
+
if (char === "\n") {
|
|
79
|
+
this.yylineno++;
|
|
80
|
+
this.column = 0;
|
|
81
|
+
} else {
|
|
82
|
+
this.column++;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
module.exports = lexer;
|