lex.go 21 KB

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