lex.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. // Package js is an ECMAScript5.1 lexer following the specifications at http://www.ecma-international.org/ecma-262/5.1/.
  2. package js
  3. import (
  4. "unicode"
  5. "unicode/utf8"
  6. "github.com/tdewolff/parse/v2"
  7. )
  8. var identifierStart = []*unicode.RangeTable{unicode.Lu, unicode.Ll, unicode.Lt, unicode.Lm, unicode.Lo, unicode.Nl, unicode.Other_ID_Start}
  9. var identifierContinue = []*unicode.RangeTable{unicode.Lu, unicode.Ll, unicode.Lt, unicode.Lm, unicode.Lo, unicode.Nl, unicode.Mn, unicode.Mc, unicode.Nd, unicode.Pc, unicode.Other_ID_Continue}
  10. // IsIdentifierStart returns true if the byte-slice start is the start of an identifier
  11. func IsIdentifierStart(b []byte) bool {
  12. r, _ := utf8.DecodeRune(b)
  13. return r == '$' || r == '\\' || r == '_' || unicode.IsOneOf(identifierStart, r)
  14. }
  15. // IsIdentifierContinue returns true if the byte-slice start is a continuation of an identifier
  16. func IsIdentifierContinue(b []byte) bool {
  17. r, _ := utf8.DecodeRune(b)
  18. return r == '$' || r == '\\' || r == '\u200C' || r == '\u200D' || unicode.IsOneOf(identifierContinue, r)
  19. }
  20. // IsIdentifierEnd returns true if the byte-slice end is a start or continuation of an identifier
  21. func IsIdentifierEnd(b []byte) bool {
  22. r, _ := utf8.DecodeLastRune(b)
  23. return r == '$' || r == '\\' || r == '\u200C' || r == '\u200D' || unicode.IsOneOf(identifierContinue, r)
  24. }
  25. ////////////////////////////////////////////////////////////////
  26. // Lexer is the state for the lexer.
  27. type Lexer struct {
  28. r *parse.Input
  29. err error
  30. prevLineTerminator bool
  31. prevNumericLiteral bool
  32. level int
  33. templateLevels []int
  34. }
  35. // NewLexer returns a new Lexer for a given io.Reader.
  36. func NewLexer(r *parse.Input) *Lexer {
  37. return &Lexer{
  38. r: r,
  39. prevLineTerminator: true,
  40. level: 0,
  41. templateLevels: []int{},
  42. }
  43. }
  44. // Err returns the error encountered during lexing, this is often io.EOF but also other errors can be returned.
  45. func (l *Lexer) Err() error {
  46. if l.err != nil {
  47. return l.err
  48. }
  49. return l.r.Err()
  50. }
  51. // RegExp reparses the input stream for a regular expression. It is assumed that we just received DivToken or DivEqToken with Next(). This function will go back and read that as a regular expression.
  52. func (l *Lexer) RegExp() (TokenType, []byte) {
  53. if 0 < l.r.Offset() && l.r.Peek(-1) == '/' {
  54. l.r.Move(-1)
  55. } else if 1 < l.r.Offset() && l.r.Peek(-1) == '=' && l.r.Peek(-2) == '/' {
  56. l.r.Move(-2)
  57. } else {
  58. l.err = parse.NewErrorLexer(l.r, "expected / or /=")
  59. return ErrorToken, nil
  60. }
  61. l.r.Skip() // trick to set start = pos
  62. if l.consumeRegExpToken() {
  63. return RegExpToken, l.r.Shift()
  64. }
  65. l.err = parse.NewErrorLexer(l.r, "unexpected EOF or newline")
  66. return ErrorToken, nil
  67. }
  68. // Next returns the next Token. It returns ErrorToken when an error was encountered. Using Err() one can retrieve the error message.
  69. func (l *Lexer) Next() (TokenType, []byte) {
  70. prevLineTerminator := l.prevLineTerminator
  71. l.prevLineTerminator = false
  72. prevNumericLiteral := l.prevNumericLiteral
  73. l.prevNumericLiteral = false
  74. // study on 50x jQuery shows:
  75. // spaces: 20k
  76. // alpha: 16k
  77. // newlines: 14.4k
  78. // operators: 4k
  79. // numbers and dot: 3.6k
  80. // (): 3.4k
  81. // {}: 1.8k
  82. // []: 0.9k
  83. // "': 1k
  84. // semicolon: 2.4k
  85. // colon: 0.8k
  86. // comma: 2.4k
  87. // slash: 1.4k
  88. // `~: almost 0
  89. c := l.r.Peek(0)
  90. switch c {
  91. case ' ', '\t', '\v', '\f':
  92. l.r.Move(1)
  93. for l.consumeWhitespace() {
  94. }
  95. l.prevLineTerminator = prevLineTerminator
  96. return WhitespaceToken, l.r.Shift()
  97. case '\n', '\r':
  98. l.r.Move(1)
  99. for l.consumeLineTerminator() {
  100. }
  101. l.prevLineTerminator = true
  102. return LineTerminatorToken, l.r.Shift()
  103. case '>', '=', '!', '+', '*', '%', '&', '|', '^', '~', '?':
  104. if tt := l.consumeOperatorToken(); tt != ErrorToken {
  105. return tt, l.r.Shift()
  106. }
  107. case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.':
  108. if tt := l.consumeNumericToken(); tt != ErrorToken || l.r.Pos() != 0 {
  109. l.prevNumericLiteral = true
  110. return tt, l.r.Shift()
  111. } else if c == '.' {
  112. l.r.Move(1)
  113. if l.r.Peek(0) == '.' && l.r.Peek(1) == '.' {
  114. l.r.Move(2)
  115. return EllipsisToken, l.r.Shift()
  116. }
  117. return DotToken, l.r.Shift()
  118. }
  119. case ',':
  120. l.r.Move(1)
  121. return CommaToken, l.r.Shift()
  122. case ';':
  123. l.r.Move(1)
  124. return SemicolonToken, l.r.Shift()
  125. case '(':
  126. l.level++
  127. l.r.Move(1)
  128. return OpenParenToken, l.r.Shift()
  129. case ')':
  130. l.level--
  131. l.r.Move(1)
  132. return CloseParenToken, l.r.Shift()
  133. case '/':
  134. if tt := l.consumeCommentToken(); tt != ErrorToken || l.err != nil {
  135. if l.err != nil {
  136. return ErrorToken, nil
  137. }
  138. return tt, l.r.Shift()
  139. } else if tt := l.consumeOperatorToken(); tt != ErrorToken {
  140. return tt, l.r.Shift()
  141. }
  142. case '{':
  143. l.level++
  144. l.r.Move(1)
  145. return OpenBraceToken, l.r.Shift()
  146. case '}':
  147. l.level--
  148. if len(l.templateLevels) != 0 && l.level == l.templateLevels[len(l.templateLevels)-1] {
  149. return l.consumeTemplateToken(), l.r.Shift()
  150. }
  151. l.r.Move(1)
  152. return CloseBraceToken, l.r.Shift()
  153. case ':':
  154. l.r.Move(1)
  155. return ColonToken, l.r.Shift()
  156. case '\'', '"':
  157. return l.consumeStringToken(), l.r.Shift()
  158. case ']':
  159. l.r.Move(1)
  160. return CloseBracketToken, l.r.Shift()
  161. case '[':
  162. l.r.Move(1)
  163. return OpenBracketToken, l.r.Shift()
  164. case '<', '-':
  165. if l.consumeHTMLLikeCommentToken(prevLineTerminator) {
  166. return CommentToken, l.r.Shift()
  167. } else if tt := l.consumeOperatorToken(); tt != ErrorToken {
  168. return tt, l.r.Shift()
  169. }
  170. case '`':
  171. l.templateLevels = append(l.templateLevels, l.level)
  172. return l.consumeTemplateToken(), l.r.Shift()
  173. case '#':
  174. l.r.Move(1)
  175. if l.consumeIdentifierToken() {
  176. return PrivateIdentifierToken, l.r.Shift()
  177. }
  178. default:
  179. if l.consumeIdentifierToken() {
  180. if prevNumericLiteral {
  181. l.err = parse.NewErrorLexer(l.r, "unexpected identifier after number")
  182. return ErrorToken, nil
  183. } else if keyword, ok := Keywords[string(l.r.Lexeme())]; ok {
  184. return keyword, l.r.Shift()
  185. }
  186. return IdentifierToken, l.r.Shift()
  187. }
  188. if 0xC0 <= c {
  189. if l.consumeWhitespace() {
  190. for l.consumeWhitespace() {
  191. }
  192. l.prevLineTerminator = prevLineTerminator
  193. return WhitespaceToken, l.r.Shift()
  194. } else if l.consumeLineTerminator() {
  195. for l.consumeLineTerminator() {
  196. }
  197. l.prevLineTerminator = true
  198. return LineTerminatorToken, l.r.Shift()
  199. }
  200. } else if c == 0 && l.r.Err() != nil {
  201. return ErrorToken, nil
  202. }
  203. }
  204. r, _ := l.r.PeekRune(0)
  205. l.err = parse.NewErrorLexer(l.r, "unexpected %s", parse.Printable(r))
  206. return ErrorToken, l.r.Shift()
  207. }
  208. ////////////////////////////////////////////////////////////////
  209. /*
  210. The following functions follow the specifications at http://www.ecma-international.org/ecma-262/5.1/
  211. */
  212. func (l *Lexer) consumeWhitespace() bool {
  213. c := l.r.Peek(0)
  214. if c == ' ' || c == '\t' || c == '\v' || c == '\f' {
  215. l.r.Move(1)
  216. return true
  217. } else if 0xC0 <= c {
  218. if r, n := l.r.PeekRune(0); r == '\u00A0' || r == '\uFEFF' || unicode.Is(unicode.Zs, r) {
  219. l.r.Move(n)
  220. return true
  221. }
  222. }
  223. return false
  224. }
  225. func (l *Lexer) isLineTerminator() bool {
  226. c := l.r.Peek(0)
  227. if c == '\n' || c == '\r' {
  228. return true
  229. } else if c == 0xE2 && l.r.Peek(1) == 0x80 && (l.r.Peek(2) == 0xA8 || l.r.Peek(2) == 0xA9) {
  230. return true
  231. }
  232. return false
  233. }
  234. func (l *Lexer) consumeLineTerminator() bool {
  235. c := l.r.Peek(0)
  236. if c == '\n' {
  237. l.r.Move(1)
  238. return true
  239. } else if c == '\r' {
  240. if l.r.Peek(1) == '\n' {
  241. l.r.Move(2)
  242. } else {
  243. l.r.Move(1)
  244. }
  245. return true
  246. } else if c == 0xE2 && l.r.Peek(1) == 0x80 && (l.r.Peek(2) == 0xA8 || l.r.Peek(2) == 0xA9) {
  247. l.r.Move(3)
  248. return true
  249. }
  250. return false
  251. }
  252. func (l *Lexer) consumeDigit() bool {
  253. if c := l.r.Peek(0); c >= '0' && c <= '9' {
  254. l.r.Move(1)
  255. return true
  256. }
  257. return false
  258. }
  259. func (l *Lexer) consumeHexDigit() bool {
  260. if c := l.r.Peek(0); (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') {
  261. l.r.Move(1)
  262. return true
  263. }
  264. return false
  265. }
  266. func (l *Lexer) consumeBinaryDigit() bool {
  267. if c := l.r.Peek(0); c == '0' || c == '1' {
  268. l.r.Move(1)
  269. return true
  270. }
  271. return false
  272. }
  273. func (l *Lexer) consumeOctalDigit() bool {
  274. if c := l.r.Peek(0); c >= '0' && c <= '7' {
  275. l.r.Move(1)
  276. return true
  277. }
  278. return false
  279. }
  280. func (l *Lexer) consumeUnicodeEscape() bool {
  281. if l.r.Peek(0) != '\\' || l.r.Peek(1) != 'u' {
  282. return false
  283. }
  284. mark := l.r.Pos()
  285. l.r.Move(2)
  286. if c := l.r.Peek(0); c == '{' {
  287. l.r.Move(1)
  288. if l.consumeHexDigit() {
  289. for l.consumeHexDigit() {
  290. }
  291. if c := l.r.Peek(0); c == '}' {
  292. l.r.Move(1)
  293. return true
  294. }
  295. }
  296. l.r.Rewind(mark)
  297. return false
  298. } else if !l.consumeHexDigit() || !l.consumeHexDigit() || !l.consumeHexDigit() || !l.consumeHexDigit() {
  299. l.r.Rewind(mark)
  300. return false
  301. }
  302. return true
  303. }
  304. func (l *Lexer) consumeSingleLineComment() {
  305. for {
  306. c := l.r.Peek(0)
  307. if c == '\r' || c == '\n' || c == 0 && l.r.Err() != nil {
  308. break
  309. } else if 0xC0 <= c {
  310. if r, _ := l.r.PeekRune(0); r == '\u2028' || r == '\u2029' {
  311. break
  312. }
  313. }
  314. l.r.Move(1)
  315. }
  316. }
  317. ////////////////////////////////////////////////////////////////
  318. func (l *Lexer) consumeHTMLLikeCommentToken(prevLineTerminator bool) bool {
  319. c := l.r.Peek(0)
  320. if c == '<' && l.r.Peek(1) == '!' && l.r.Peek(2) == '-' && l.r.Peek(3) == '-' {
  321. // opening HTML-style single line comment
  322. l.r.Move(4)
  323. l.consumeSingleLineComment()
  324. return true
  325. } else if prevLineTerminator && c == '-' && l.r.Peek(1) == '-' && l.r.Peek(2) == '>' {
  326. // closing HTML-style single line comment
  327. // (only if current line didn't contain any meaningful tokens)
  328. l.r.Move(3)
  329. l.consumeSingleLineComment()
  330. return true
  331. }
  332. return false
  333. }
  334. func (l *Lexer) consumeCommentToken() TokenType {
  335. c := l.r.Peek(1)
  336. if c == '/' {
  337. // single line comment
  338. l.r.Move(2)
  339. l.consumeSingleLineComment()
  340. return CommentToken
  341. } else if c == '*' {
  342. l.r.Move(2)
  343. tt := CommentToken
  344. for {
  345. c := l.r.Peek(0)
  346. if c == '*' && l.r.Peek(1) == '/' {
  347. l.r.Move(2)
  348. break
  349. } else if c == 0 && l.r.Err() != nil {
  350. l.err = parse.NewErrorLexer(l.r, "unexpected EOF in comment")
  351. return ErrorToken
  352. } else if l.consumeLineTerminator() {
  353. l.prevLineTerminator = true
  354. tt = CommentLineTerminatorToken
  355. } else {
  356. l.r.Move(1)
  357. }
  358. }
  359. return tt
  360. }
  361. return ErrorToken
  362. }
  363. var opTokens = map[byte]TokenType{
  364. '=': EqToken,
  365. '!': NotToken,
  366. '<': LtToken,
  367. '>': GtToken,
  368. '+': AddToken,
  369. '-': SubToken,
  370. '*': MulToken,
  371. '/': DivToken,
  372. '%': ModToken,
  373. '&': BitAndToken,
  374. '|': BitOrToken,
  375. '^': BitXorToken,
  376. '~': BitNotToken,
  377. '?': QuestionToken,
  378. }
  379. var opEqTokens = map[byte]TokenType{
  380. '=': EqEqToken,
  381. '!': NotEqToken,
  382. '<': LtEqToken,
  383. '>': GtEqToken,
  384. '+': AddEqToken,
  385. '-': SubEqToken,
  386. '*': MulEqToken,
  387. '/': DivEqToken,
  388. '%': ModEqToken,
  389. '&': BitAndEqToken,
  390. '|': BitOrEqToken,
  391. '^': BitXorEqToken,
  392. }
  393. var opOpTokens = map[byte]TokenType{
  394. '<': LtLtToken,
  395. '+': IncrToken,
  396. '-': DecrToken,
  397. '*': ExpToken,
  398. '&': AndToken,
  399. '|': OrToken,
  400. '?': NullishToken,
  401. }
  402. var opOpEqTokens = map[byte]TokenType{
  403. '<': LtLtEqToken,
  404. '*': ExpEqToken,
  405. '&': AndEqToken,
  406. '|': OrEqToken,
  407. '?': NullishEqToken,
  408. }
  409. func (l *Lexer) consumeOperatorToken() TokenType {
  410. c := l.r.Peek(0)
  411. l.r.Move(1)
  412. if l.r.Peek(0) == '=' {
  413. l.r.Move(1)
  414. if l.r.Peek(0) == '=' && (c == '!' || c == '=') {
  415. l.r.Move(1)
  416. if c == '!' {
  417. return NotEqEqToken
  418. }
  419. return EqEqEqToken
  420. }
  421. return opEqTokens[c]
  422. } else if l.r.Peek(0) == c && (c == '+' || c == '-' || c == '*' || c == '&' || c == '|' || c == '?' || c == '<') {
  423. l.r.Move(1)
  424. if l.r.Peek(0) == '=' && c != '+' && c != '-' {
  425. l.r.Move(1)
  426. return opOpEqTokens[c]
  427. }
  428. return opOpTokens[c]
  429. } else if c == '?' && l.r.Peek(0) == '.' && (l.r.Peek(1) < '0' || l.r.Peek(1) > '9') {
  430. l.r.Move(1)
  431. return OptChainToken
  432. } else if c == '=' && l.r.Peek(0) == '>' {
  433. l.r.Move(1)
  434. return ArrowToken
  435. } else if c == '>' && l.r.Peek(0) == '>' {
  436. l.r.Move(1)
  437. if l.r.Peek(0) == '>' {
  438. l.r.Move(1)
  439. if l.r.Peek(0) == '=' {
  440. l.r.Move(1)
  441. return GtGtGtEqToken
  442. }
  443. return GtGtGtToken
  444. } else if l.r.Peek(0) == '=' {
  445. l.r.Move(1)
  446. return GtGtEqToken
  447. }
  448. return GtGtToken
  449. }
  450. return opTokens[c]
  451. }
  452. func (l *Lexer) consumeIdentifierToken() bool {
  453. c := l.r.Peek(0)
  454. if identifierStartTable[c] {
  455. l.r.Move(1)
  456. } else if 0xC0 <= c {
  457. if r, n := l.r.PeekRune(0); unicode.IsOneOf(identifierStart, r) {
  458. l.r.Move(n)
  459. } else {
  460. return false
  461. }
  462. } else if !l.consumeUnicodeEscape() {
  463. return false
  464. }
  465. for {
  466. c := l.r.Peek(0)
  467. if identifierTable[c] {
  468. l.r.Move(1)
  469. } else if 0xC0 <= c {
  470. if r, n := l.r.PeekRune(0); r == '\u200C' || r == '\u200D' || unicode.IsOneOf(identifierContinue, r) {
  471. l.r.Move(n)
  472. } else {
  473. break
  474. }
  475. } else if !l.consumeUnicodeEscape() {
  476. break
  477. }
  478. }
  479. return true
  480. }
  481. func (l *Lexer) consumeNumericSeparator(f func() bool) bool {
  482. if l.r.Peek(0) != '_' {
  483. return false
  484. }
  485. l.r.Move(1)
  486. if !f() {
  487. l.r.Move(-1)
  488. return false
  489. }
  490. return true
  491. }
  492. func (l *Lexer) consumeNumericToken() TokenType {
  493. // assume to be on 0 1 2 3 4 5 6 7 8 9 .
  494. first := l.r.Peek(0)
  495. if first == '0' {
  496. l.r.Move(1)
  497. if l.r.Peek(0) == 'x' || l.r.Peek(0) == 'X' {
  498. l.r.Move(1)
  499. if l.consumeHexDigit() {
  500. for l.consumeHexDigit() || l.consumeNumericSeparator(l.consumeHexDigit) {
  501. }
  502. return HexadecimalToken
  503. }
  504. l.err = parse.NewErrorLexer(l.r, "invalid hexadecimal number")
  505. return ErrorToken
  506. } else if l.r.Peek(0) == 'b' || l.r.Peek(0) == 'B' {
  507. l.r.Move(1)
  508. if l.consumeBinaryDigit() {
  509. for l.consumeBinaryDigit() || l.consumeNumericSeparator(l.consumeBinaryDigit) {
  510. }
  511. return BinaryToken
  512. }
  513. l.err = parse.NewErrorLexer(l.r, "invalid binary number")
  514. return ErrorToken
  515. } else if l.r.Peek(0) == 'o' || l.r.Peek(0) == 'O' {
  516. l.r.Move(1)
  517. if l.consumeOctalDigit() {
  518. for l.consumeOctalDigit() || l.consumeNumericSeparator(l.consumeOctalDigit) {
  519. }
  520. return OctalToken
  521. }
  522. l.err = parse.NewErrorLexer(l.r, "invalid octal number")
  523. return ErrorToken
  524. } else if l.r.Peek(0) == 'n' {
  525. l.r.Move(1)
  526. return BigIntToken
  527. } else if '0' <= l.r.Peek(0) && l.r.Peek(0) <= '9' {
  528. l.err = parse.NewErrorLexer(l.r, "legacy octal numbers are not supported")
  529. return ErrorToken
  530. }
  531. } else if first != '.' {
  532. for l.consumeDigit() || l.consumeNumericSeparator(l.consumeDigit) {
  533. }
  534. }
  535. // we have parsed a 0 or an integer number
  536. c := l.r.Peek(0)
  537. if c == '.' {
  538. l.r.Move(1)
  539. if l.consumeDigit() {
  540. for l.consumeDigit() || l.consumeNumericSeparator(l.consumeDigit) {
  541. }
  542. c = l.r.Peek(0)
  543. } else if first == '.' {
  544. // number starts with a dot and must be followed by digits
  545. l.r.Move(-1)
  546. return ErrorToken // may be dot or ellipsis
  547. } else {
  548. c = l.r.Peek(0)
  549. }
  550. } else if c == 'n' {
  551. l.r.Move(1)
  552. return BigIntToken
  553. }
  554. if c == 'e' || c == 'E' {
  555. l.r.Move(1)
  556. c = l.r.Peek(0)
  557. if c == '+' || c == '-' {
  558. l.r.Move(1)
  559. }
  560. if !l.consumeDigit() {
  561. l.err = parse.NewErrorLexer(l.r, "invalid number")
  562. return ErrorToken
  563. }
  564. for l.consumeDigit() || l.consumeNumericSeparator(l.consumeDigit) {
  565. }
  566. }
  567. return DecimalToken
  568. }
  569. func (l *Lexer) consumeStringToken() TokenType {
  570. // assume to be on ' or "
  571. delim := l.r.Peek(0)
  572. l.r.Move(1)
  573. for {
  574. c := l.r.Peek(0)
  575. if c == delim {
  576. l.r.Move(1)
  577. break
  578. } else if c == '\\' {
  579. l.r.Move(1)
  580. if !l.consumeLineTerminator() {
  581. if c := l.r.Peek(0); c == delim || c == '\\' {
  582. l.r.Move(1)
  583. }
  584. }
  585. continue
  586. } else if c == '\n' || c == '\r' || c == 0 && l.r.Err() != nil {
  587. l.err = parse.NewErrorLexer(l.r, "unterminated string literal")
  588. return ErrorToken
  589. }
  590. l.r.Move(1)
  591. }
  592. return StringToken
  593. }
  594. func (l *Lexer) consumeRegExpToken() bool {
  595. // assume to be on /
  596. l.r.Move(1)
  597. inClass := false
  598. for {
  599. c := l.r.Peek(0)
  600. if !inClass && c == '/' {
  601. l.r.Move(1)
  602. break
  603. } else if c == '[' {
  604. inClass = true
  605. } else if c == ']' {
  606. inClass = false
  607. } else if c == '\\' {
  608. l.r.Move(1)
  609. if l.isLineTerminator() || l.r.Peek(0) == 0 && l.r.Err() != nil {
  610. return false
  611. }
  612. } else if l.isLineTerminator() || c == 0 && l.r.Err() != nil {
  613. return false
  614. }
  615. l.r.Move(1)
  616. }
  617. // flags
  618. for {
  619. c := l.r.Peek(0)
  620. if identifierTable[c] {
  621. l.r.Move(1)
  622. } else if 0xC0 <= c {
  623. if r, n := l.r.PeekRune(0); r == '\u200C' || r == '\u200D' || unicode.IsOneOf(identifierContinue, r) {
  624. l.r.Move(n)
  625. } else {
  626. break
  627. }
  628. } else {
  629. break
  630. }
  631. }
  632. return true
  633. }
  634. func (l *Lexer) consumeTemplateToken() TokenType {
  635. // assume to be on ` or } when already within template
  636. continuation := l.r.Peek(0) == '}'
  637. l.r.Move(1)
  638. for {
  639. c := l.r.Peek(0)
  640. if c == '`' {
  641. l.templateLevels = l.templateLevels[:len(l.templateLevels)-1]
  642. l.r.Move(1)
  643. if continuation {
  644. return TemplateEndToken
  645. }
  646. return TemplateToken
  647. } else if c == '$' && l.r.Peek(1) == '{' {
  648. l.level++
  649. l.r.Move(2)
  650. if continuation {
  651. return TemplateMiddleToken
  652. }
  653. return TemplateStartToken
  654. } else if c == '\\' {
  655. l.r.Move(1)
  656. if c := l.r.Peek(0); c != 0 {
  657. l.r.Move(1)
  658. }
  659. continue
  660. } else if c == 0 && l.r.Err() != nil {
  661. l.err = parse.NewErrorLexer(l.r, "unterminated template literal")
  662. return ErrorToken
  663. }
  664. l.r.Move(1)
  665. }
  666. }
  667. var identifierStartTable = [256]bool{
  668. // ASCII
  669. false, false, false, false, false, false, false, false,
  670. false, false, false, false, false, false, false, false,
  671. false, false, false, false, false, false, false, false,
  672. false, false, false, false, false, false, false, false,
  673. false, false, false, false, true, false, false, false, // $
  674. false, false, false, false, false, false, false, false,
  675. false, false, false, false, false, false, false, false,
  676. false, false, false, false, false, false, false, false,
  677. false, true, true, true, true, true, true, true, // A, B, C, D, E, F, G
  678. true, true, true, true, true, true, true, true, // H, I, J, K, L, M, N, O
  679. true, true, true, true, true, true, true, true, // P, Q, R, S, T, U, V, W
  680. true, true, true, false, false, false, false, true, // X, Y, Z, _
  681. false, true, true, true, true, true, true, true, // a, b, c, d, e, f, g
  682. true, true, true, true, true, true, true, true, // h, i, j, k, l, m, n, o
  683. true, true, true, true, true, true, true, true, // p, q, r, s, t, u, v, w
  684. true, true, true, false, false, false, false, false, // x, y, z
  685. // non-ASCII
  686. false, false, false, false, false, false, false, false,
  687. false, false, false, false, false, false, false, false,
  688. false, false, false, false, false, false, false, false,
  689. false, false, false, false, false, false, false, false,
  690. false, false, false, false, false, false, false, false,
  691. false, false, false, false, false, false, false, false,
  692. false, false, false, false, false, false, false, false,
  693. false, false, false, false, false, false, false, false,
  694. false, false, false, false, false, false, false, false,
  695. false, false, false, false, false, false, false, false,
  696. false, false, false, false, false, false, false, false,
  697. false, false, false, false, false, false, false, false,
  698. false, false, false, false, false, false, false, false,
  699. false, false, false, false, false, false, false, false,
  700. false, false, false, false, false, false, false, false,
  701. false, false, false, false, false, false, false, false,
  702. }
  703. var identifierTable = [256]bool{
  704. // ASCII
  705. false, false, false, false, false, false, false, false,
  706. false, false, false, false, false, false, false, false,
  707. false, false, false, false, false, false, false, false,
  708. false, false, false, false, false, false, false, false,
  709. false, false, false, false, true, false, false, false, // $
  710. false, false, false, false, false, false, false, false,
  711. true, true, true, true, true, true, true, true, // 0, 1, 2, 3, 4, 5, 6, 7
  712. true, true, false, false, false, false, false, false, // 8, 9
  713. false, true, true, true, true, true, true, true, // A, B, C, D, E, F, G
  714. true, true, true, true, true, true, true, true, // H, I, J, K, L, M, N, O
  715. true, true, true, true, true, true, true, true, // P, Q, R, S, T, U, V, W
  716. true, true, true, false, false, false, false, true, // X, Y, Z, _
  717. false, true, true, true, true, true, true, true, // a, b, c, d, e, f, g
  718. true, true, true, true, true, true, true, true, // h, i, j, k, l, m, n, o
  719. true, true, true, true, true, true, true, true, // p, q, r, s, t, u, v, w
  720. true, true, true, false, false, false, false, false, // x, y, z
  721. // non-ASCII
  722. false, false, false, false, false, false, false, false,
  723. false, false, false, false, false, false, false, false,
  724. false, false, false, false, false, false, false, false,
  725. false, false, false, false, false, false, false, false,
  726. false, false, false, false, false, false, false, false,
  727. false, false, false, false, false, false, false, false,
  728. false, false, false, false, false, false, false, false,
  729. false, false, false, false, false, false, false, false,
  730. false, false, false, false, false, false, false, false,
  731. false, false, false, false, false, false, false, false,
  732. false, false, false, false, false, false, false, false,
  733. false, false, false, false, false, false, false, false,
  734. false, false, false, false, false, false, false, false,
  735. false, false, false, false, false, false, false, false,
  736. false, false, false, false, false, false, false, false,
  737. false, false, false, false, false, false, false, false,
  738. }