12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- const TokenStream = require('./tokenStream')
- const tokenTypes = require('./tokenTypes')
-
- module.exports = class Lexer {
- scan(source) {
- let pos = 0
- let line = 1
- let tokenStream = new TokenStream()
- let allowSpecialCharactersInLiterals = false
-
- while (pos < source.length) {
- if (source[pos].match(/\(/) && !allowSpecialCharactersInLiterals) {
- tokenStream.tokens.push({
- type: tokenTypes.OPAREN,
- line: line,
- })
- pos++
- } else if (source[pos].match(/\)/)) {
- tokenStream.tokens.push({
- type: tokenTypes.CPAREN,
- line: line,
- })
- pos++
- } else if (source[pos].match(/["]/)) {
- allowSpecialCharactersInLiterals = !allowSpecialCharactersInLiterals
- tokenStream.tokens.push({
- type: tokenTypes.QUOTE,
- line: line,
- })
- pos++
- } else if (source[pos].match(/:/)) {
- let value = /:([^()'"\s]+)/.exec(source.slice(pos))[1].trim()
- tokenStream.tokens.push({
- type: tokenTypes.ATTRIBUTE,
- line: line,
- value: value,
- })
- pos += value.length + 1 // the +1 is to account for the colon
- } else if (source[pos].match(/\'/)) {
- let value = /'([^()"\s]+)/.exec(source.slice(pos))[1].trim()
- tokenStream.tokens.push({
- type: tokenTypes.SYMBOL,
- line: line,
- value: value,
- })
- pos += value.length + 1 // the +1 is to account for the apostrophe
- } else if (source[pos].match(/\n/)) {
- line++
- pos++
- } else if (source[pos].match(/\s/)) {
- pos++
- } else {
- let endPattern = /[^()"':\s]+/
-
- if (allowSpecialCharactersInLiterals) {
- endPattern = /[^"']+/
- }
-
- let value = endPattern.exec(source.slice(pos))[0].trim()
-
- if (['if', 'each'].includes(value)) {
- tokenStream.tokens.push({
- type: tokenTypes.KEYWORD,
- line: line,
- value: value,
- })
- } else {
- tokenStream.tokens.push({
- type: tokenTypes.LITERAL,
- line: line,
- value: value.trim(),
- })
- }
-
- pos += value.length
- }
- }
-
- tokenStream.tokens.push({
- type: tokenTypes.EOF,
- line: line,
- })
- return tokenStream
- }
- }
|