1 | Parser
|
2 | ======
|
3 |
|
4 | The Parser class parse a source file into an AST. Firescript is compatible with the Esprima AST to make it compatible to other tools like linters or source formaters. Firescript AST, called FAST, is an extended AST. It has a few `fs` profixed properties and its own nodes like `FirescriptLogStatement` or `FirescriptTyping`.
|
5 |
|
6 | ## Usage
|
7 |
|
8 | ```js
|
9 | const parser = new Parser({
|
10 | // parser config
|
11 | })
|
12 |
|
13 | parser.parse('const banana = \'banana\'')
|
14 |
|
15 | // get next token
|
16 | const token = parser.nextToken()
|
17 |
|
18 | {
|
19 | "type": "identifier",
|
20 | "value": "const",
|
21 | "isKeyword": true,
|
22 | "index": 0,
|
23 | "length": 5,
|
24 | "lineLength": 1,
|
25 | "line": 1,
|
26 | "column": 1,
|
27 | "isKeyword": true,
|
28 | "indention": 0
|
29 | }
|
30 |
|
31 |
|
32 | // get next node
|
33 | const node = parser.nextNode()
|
34 |
|
35 | {
|
36 | "type": "VariableDeclaration",
|
37 | "declarations": [
|
38 | {
|
39 | "type": "VariableDeclarator",
|
40 | "id": {
|
41 | "type": "Identifier",
|
42 | "name": "banana"
|
43 | },
|
44 | "init": {
|
45 | "type": "Literal",
|
46 | "value": "banana",
|
47 | "raw": "'banana'"
|
48 | }
|
49 | }
|
50 | ],
|
51 | "kind": "const"
|
52 | }
|
53 | ```
|
54 |
|
55 | ### Parser setup
|
56 |
|
57 | ```cson
|
58 | 'keyword "const"':
|
59 | name: 'VariableDeclaration'
|
60 |
|
61 | 'identifier':
|
62 | name: 'Identifier'
|
63 |
|
64 | 'operator "="'
|
65 | name: 'AssignmentOperator'
|
66 |
|
67 | 'literal':
|
68 | name: 'Literal'
|
69 | ```
|
70 |
|
71 | `parser.nextToken()` returns the next token
|
72 |
|
73 | `parser.nextNode()` returns the next node
|
74 |
|
75 |
|
76 |
|
77 | #### Parser step by step
|
78 |
|
79 | ```js
|
80 | const banana = 'Banana'
|
81 | ```
|
82 |
|
83 | 1) Parser detects an identifier token with value `const`.
|
84 | 2) `const` is declared as a keyword. It returns an identifier token with `isKeyword` flag set to `true`.
|
85 | 3) Identifier `const` should be resolved with `VariableDeclaration` class located in `src/fs-parser/nodes/`.
|
86 | 4) Within the `VariableDeclaration` class, and identifier is required.
|
87 | 5) `VariableDeclaration` asks parser for an identifier by using `parser.getIdentifier()`
|
88 | 6) Parser returns an identifier with the value `banana`
|
89 | 7) `VariableDeclaration` requires an `punctuator` of type `=`
|
90 | 8) Parser returns an punctuator with the value `=`
|
91 | 9) `VariableDeclaration` requires any value from `parser.next()`
|
92 | 10) `VariableDeclaration` accepts value
|
93 |
|
94 | * Parser throws an `SyntaxError` if value doesn't match the required type.
|
95 |
|
96 | Parser Methods
|
97 | --------------
|
98 |
|
99 | ### nextNode()
|
100 |
|
101 | **Returns next node based on declarations conf**
|
102 |
|
103 | ### getIdentifier([*str* match | *arr[str]* match])
|
104 |
|
105 | **Returns a identifier**
|
106 |
|
107 |
|
108 | `match` defines an optional matching value. The value must match, otherwise a `SyntaxError` is thrown.
|
109 |
|
110 | ```js
|
111 | {
|
112 | type: 'identifier',
|
113 | value: 'banana',
|
114 | col: 1,
|
115 | line: 1,
|
116 | index: 0,
|
117 | length: 6
|
118 | }
|
119 | ```
|
120 |
|
121 | (i) Throws a `SyntaxError` if next type is not an `identifier`. It throws an `IndentionError` if next type is an `Indention`
|
122 |
|
123 | ### getKeyword([*str* match])
|
124 |
|
125 | **Returns a keyword**
|
126 |
|
127 | ```js
|
128 | {
|
129 | type: 'keyword',
|
130 | value: 'const',
|
131 | col: 1,
|
132 | line: 1,
|
133 | index: 0,
|
134 | length: 5
|
135 | }
|
136 | ```
|
137 |
|
138 | `match` See `getIdentifier()`
|
139 |
|
140 |
|
141 | ### getLiteral([*str* match])
|
142 |
|
143 | **Returns a literal**
|
144 |
|
145 | ```js
|
146 | {
|
147 | type: 'literal|regexp|number|template',
|
148 | value: '\'banana\'',
|
149 | col: 1,
|
150 | line: 1,
|
151 | index: 0,
|
152 | length: 5
|
153 | }
|
154 | ```
|
155 |
|
156 | `match` See `getIdentifier()`
|
157 |
|
158 |
|
159 | ### getPunctuator([*str* match])
|
160 |
|
161 | **Returns a punctuator**
|
162 |
|
163 | ```js
|
164 | {
|
165 | type: 'punctuator',
|
166 | value: '=',
|
167 | col: 14,
|
168 | line: 1,
|
169 | index: 13,
|
170 | length: 1
|
171 | }
|
172 | ```
|
173 |
|
174 | `match` See `getIdentifier()`
|
175 |
|
176 |
|
177 | ### getOperator([*str* match])
|
178 |
|
179 | **Returns a operator**
|
180 |
|
181 | ```js
|
182 | {
|
183 | type: 'operator',
|
184 | value: '+',
|
185 | col: 14,
|
186 | line: 1,
|
187 | index: 13,
|
188 | length: 1
|
189 | }
|
190 | ```
|
191 |
|
192 | `match` See `getIdentifier()`
|
193 |
|
194 | ### isIdentifier()
|
195 |
|
196 | Checks if next item is an `identifier`
|
197 |
|
198 | ### isKeyword()
|
199 |
|
200 | Checks if next item is a `keyword`
|
201 |
|
202 | ### isLiteral()
|
203 |
|
204 | Checks if next item is a `literal`
|
205 |
|
206 | ### isPunctuator()
|
207 |
|
208 | Checks if next item is a `punctuator`
|
209 |
|
210 | ### isOperator()
|
211 |
|
212 | Checks if next item is an `operator`
|
213 |
|
214 | ### isIndention()
|
215 |
|
216 | Checks if next item is an `indention`
|
217 |
|
218 | ## Scope features
|
219 |
|
220 | ### isScope()
|
221 |
|
222 | Checks if current scope is our scope
|
223 |
|
224 | Returns an `boolean`
|
225 |
|
226 | ### isChildScope([*bool* allowAnySize])
|
227 |
|
228 | Checks if current scope is a child scope
|
229 |
|
230 | `allowAnySize` Set this to `true` to allow a child indention more then one.
|
231 | Otherwise an `IndentionError` is thrown.
|
232 |
|
233 | Returns an `boolean`
|
234 |
|
235 | ### isParentScope()
|
236 |
|
237 | Checks if current scope is parent scope
|
238 |
|
239 | Returns an `boolean`
|
240 |
|
241 |
|
242 |
|
243 |
|
244 | ### syntaxError([*str* message], [token])
|
245 |
|
246 | **Throws a SyntaxError**
|
247 |
|
248 | ```js
|
249 | SyntaxError: Unexpected token at line 4 column 3
|
250 |
|
251 | 1 | if banana
|
252 | 2 | log 'Banana'
|
253 | 3 | else
|
254 | 4 | olg 'No Banana'
|
255 | x | ^
|
256 |
|
257 | ```
|