lexer.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. package parse
  2. import (
  3. "bufio"
  4. "bytes"
  5. "fmt"
  6. "github.com/yuin/gopher-lua/ast"
  7. "io"
  8. "reflect"
  9. "strconv"
  10. "strings"
  11. )
  12. const EOF = -1
  13. const whitespace1 = 1<<'\t' | 1<<'\r' | 1<<' '
  14. const whitespace2 = 1<<'\t' | 1<<'\n' | 1<<'\r' | 1<<' '
  15. type Error struct {
  16. Pos ast.Position
  17. Message string
  18. Token string
  19. }
  20. func (e *Error) Error() string {
  21. pos := e.Pos
  22. if pos.Line == EOF {
  23. return fmt.Sprintf("%v at EOF: %s\n", pos.Source, e.Message)
  24. } else {
  25. return fmt.Sprintf("%v line:%d(column:%d) near '%v': %s\n", pos.Source, pos.Line, pos.Column, e.Token, e.Message)
  26. }
  27. }
  28. func writeChar(buf *bytes.Buffer, c int) { buf.WriteByte(byte(c)) }
  29. func isDecimal(ch int) bool { return '0' <= ch && ch <= '9' }
  30. func isIdent(ch int, pos int) bool {
  31. return ch == '_' || 'A' <= ch && ch <= 'Z' || 'a' <= ch && ch <= 'z' || isDecimal(ch) && pos > 0
  32. }
  33. func isDigit(ch int) bool {
  34. return '0' <= ch && ch <= '9' || 'a' <= ch && ch <= 'f' || 'A' <= ch && ch <= 'F'
  35. }
  36. type Scanner struct {
  37. Pos ast.Position
  38. reader *bufio.Reader
  39. }
  40. func NewScanner(reader io.Reader, source string) *Scanner {
  41. return &Scanner{
  42. Pos: ast.Position{source, 1, 0},
  43. reader: bufio.NewReaderSize(reader, 4096),
  44. }
  45. }
  46. func (sc *Scanner) Error(tok string, msg string) *Error { return &Error{sc.Pos, msg, tok} }
  47. func (sc *Scanner) TokenError(tok ast.Token, msg string) *Error { return &Error{tok.Pos, msg, tok.Str} }
  48. func (sc *Scanner) readNext() int {
  49. ch, err := sc.reader.ReadByte()
  50. if err == io.EOF {
  51. return EOF
  52. }
  53. return int(ch)
  54. }
  55. func (sc *Scanner) Newline(ch int) {
  56. if ch < 0 {
  57. return
  58. }
  59. sc.Pos.Line += 1
  60. sc.Pos.Column = 0
  61. next := sc.Peek()
  62. if ch == '\n' && next == '\r' || ch == '\r' && next == '\n' {
  63. sc.reader.ReadByte()
  64. }
  65. }
  66. func (sc *Scanner) Next() int {
  67. ch := sc.readNext()
  68. switch ch {
  69. case '\n', '\r':
  70. sc.Newline(ch)
  71. ch = int('\n')
  72. case EOF:
  73. sc.Pos.Line = EOF
  74. sc.Pos.Column = 0
  75. default:
  76. sc.Pos.Column++
  77. }
  78. return ch
  79. }
  80. func (sc *Scanner) Peek() int {
  81. ch := sc.readNext()
  82. if ch != EOF {
  83. sc.reader.UnreadByte()
  84. }
  85. return ch
  86. }
  87. func (sc *Scanner) skipWhiteSpace(whitespace int64) int {
  88. ch := sc.Next()
  89. for ; whitespace&(1<<uint(ch)) != 0; ch = sc.Next() {
  90. }
  91. return ch
  92. }
  93. func (sc *Scanner) skipComments(ch int) error {
  94. // multiline comment
  95. if sc.Peek() == '[' {
  96. ch = sc.Next()
  97. if sc.Peek() == '[' || sc.Peek() == '=' {
  98. var buf bytes.Buffer
  99. if err := sc.scanMultilineString(sc.Next(), &buf); err != nil {
  100. return sc.Error(buf.String(), "invalid multiline comment")
  101. }
  102. return nil
  103. }
  104. }
  105. for {
  106. if ch == '\n' || ch == '\r' || ch < 0 {
  107. break
  108. }
  109. ch = sc.Next()
  110. }
  111. return nil
  112. }
  113. func (sc *Scanner) scanIdent(ch int, buf *bytes.Buffer) error {
  114. writeChar(buf, ch)
  115. for isIdent(sc.Peek(), 1) {
  116. writeChar(buf, sc.Next())
  117. }
  118. return nil
  119. }
  120. func (sc *Scanner) scanDecimal(ch int, buf *bytes.Buffer) error {
  121. writeChar(buf, ch)
  122. for isDecimal(sc.Peek()) {
  123. writeChar(buf, sc.Next())
  124. }
  125. return nil
  126. }
  127. func (sc *Scanner) scanNumber(ch int, buf *bytes.Buffer) error {
  128. if ch == '0' { // octal
  129. if sc.Peek() == 'x' || sc.Peek() == 'X' {
  130. writeChar(buf, ch)
  131. writeChar(buf, sc.Next())
  132. hasvalue := false
  133. for isDigit(sc.Peek()) {
  134. writeChar(buf, sc.Next())
  135. hasvalue = true
  136. }
  137. if !hasvalue {
  138. return sc.Error(buf.String(), "illegal hexadecimal number")
  139. }
  140. return nil
  141. } else if sc.Peek() != '.' && isDecimal(sc.Peek()) {
  142. ch = sc.Next()
  143. }
  144. }
  145. sc.scanDecimal(ch, buf)
  146. if sc.Peek() == '.' {
  147. sc.scanDecimal(sc.Next(), buf)
  148. }
  149. if ch = sc.Peek(); ch == 'e' || ch == 'E' {
  150. writeChar(buf, sc.Next())
  151. if ch = sc.Peek(); ch == '-' || ch == '+' {
  152. writeChar(buf, sc.Next())
  153. }
  154. sc.scanDecimal(sc.Next(), buf)
  155. }
  156. return nil
  157. }
  158. func (sc *Scanner) scanString(quote int, buf *bytes.Buffer) error {
  159. ch := sc.Next()
  160. for ch != quote {
  161. if ch == '\n' || ch == '\r' || ch < 0 {
  162. return sc.Error(buf.String(), "unterminated string")
  163. }
  164. if ch == '\\' {
  165. if err := sc.scanEscape(ch, buf); err != nil {
  166. return err
  167. }
  168. } else {
  169. writeChar(buf, ch)
  170. }
  171. ch = sc.Next()
  172. }
  173. return nil
  174. }
  175. func (sc *Scanner) scanEscape(ch int, buf *bytes.Buffer) error {
  176. ch = sc.Next()
  177. switch ch {
  178. case 'a':
  179. buf.WriteByte('\a')
  180. case 'b':
  181. buf.WriteByte('\b')
  182. case 'f':
  183. buf.WriteByte('\f')
  184. case 'n':
  185. buf.WriteByte('\n')
  186. case 'r':
  187. buf.WriteByte('\r')
  188. case 't':
  189. buf.WriteByte('\t')
  190. case 'v':
  191. buf.WriteByte('\v')
  192. case '\\':
  193. buf.WriteByte('\\')
  194. case '"':
  195. buf.WriteByte('"')
  196. case '\'':
  197. buf.WriteByte('\'')
  198. case '\n':
  199. buf.WriteByte('\n')
  200. case '\r':
  201. buf.WriteByte('\n')
  202. sc.Newline('\r')
  203. default:
  204. if '0' <= ch && ch <= '9' {
  205. bytes := []byte{byte(ch)}
  206. for i := 0; i < 2 && isDecimal(sc.Peek()); i++ {
  207. bytes = append(bytes, byte(sc.Next()))
  208. }
  209. val, _ := strconv.ParseInt(string(bytes), 10, 32)
  210. writeChar(buf, int(val))
  211. } else {
  212. buf.WriteByte('\\')
  213. writeChar(buf, ch)
  214. return sc.Error(buf.String(), "Invalid escape sequence")
  215. }
  216. }
  217. return nil
  218. }
  219. func (sc *Scanner) countSep(ch int) (int, int) {
  220. count := 0
  221. for ; ch == '='; count = count + 1 {
  222. ch = sc.Next()
  223. }
  224. return count, ch
  225. }
  226. func (sc *Scanner) scanMultilineString(ch int, buf *bytes.Buffer) error {
  227. var count1, count2 int
  228. count1, ch = sc.countSep(ch)
  229. if ch != '[' {
  230. return sc.Error(string(ch), "invalid multiline string")
  231. }
  232. ch = sc.Next()
  233. if ch == '\n' || ch == '\r' {
  234. ch = sc.Next()
  235. }
  236. for {
  237. if ch < 0 {
  238. return sc.Error(buf.String(), "unterminated multiline string")
  239. } else if ch == ']' {
  240. count2, ch = sc.countSep(sc.Next())
  241. if count1 == count2 && ch == ']' {
  242. goto finally
  243. }
  244. buf.WriteByte(']')
  245. buf.WriteString(strings.Repeat("=", count2))
  246. continue
  247. }
  248. writeChar(buf, ch)
  249. ch = sc.Next()
  250. }
  251. finally:
  252. return nil
  253. }
  254. var reservedWords = map[string]int{
  255. "and": TAnd, "break": TBreak, "do": TDo, "else": TElse, "elseif": TElseIf,
  256. "end": TEnd, "false": TFalse, "for": TFor, "function": TFunction,
  257. "if": TIf, "in": TIn, "local": TLocal, "nil": TNil, "not": TNot, "or": TOr,
  258. "return": TReturn, "repeat": TRepeat, "then": TThen, "true": TTrue,
  259. "until": TUntil, "while": TWhile}
  260. func (sc *Scanner) Scan(lexer *Lexer) (ast.Token, error) {
  261. redo:
  262. var err error
  263. tok := ast.Token{}
  264. newline := false
  265. ch := sc.skipWhiteSpace(whitespace1)
  266. if ch == '\n' || ch == '\r' {
  267. newline = true
  268. ch = sc.skipWhiteSpace(whitespace2)
  269. }
  270. if ch == '(' {
  271. lexer.PNewLine = newline
  272. }
  273. var _buf bytes.Buffer
  274. buf := &_buf
  275. tok.Pos = sc.Pos
  276. switch {
  277. case isIdent(ch, 0):
  278. tok.Type = TIdent
  279. err = sc.scanIdent(ch, buf)
  280. tok.Str = buf.String()
  281. if err != nil {
  282. goto finally
  283. }
  284. if typ, ok := reservedWords[tok.Str]; ok {
  285. tok.Type = typ
  286. }
  287. case isDecimal(ch):
  288. tok.Type = TNumber
  289. err = sc.scanNumber(ch, buf)
  290. tok.Str = buf.String()
  291. default:
  292. switch ch {
  293. case EOF:
  294. tok.Type = EOF
  295. case '-':
  296. if sc.Peek() == '-' {
  297. err = sc.skipComments(sc.Next())
  298. if err != nil {
  299. goto finally
  300. }
  301. goto redo
  302. } else {
  303. tok.Type = ch
  304. tok.Str = string(ch)
  305. }
  306. case '"', '\'':
  307. tok.Type = TString
  308. err = sc.scanString(ch, buf)
  309. tok.Str = buf.String()
  310. case '[':
  311. if c := sc.Peek(); c == '[' || c == '=' {
  312. tok.Type = TString
  313. err = sc.scanMultilineString(sc.Next(), buf)
  314. tok.Str = buf.String()
  315. } else {
  316. tok.Type = ch
  317. tok.Str = string(ch)
  318. }
  319. case '=':
  320. if sc.Peek() == '=' {
  321. tok.Type = TEqeq
  322. tok.Str = "=="
  323. sc.Next()
  324. } else {
  325. tok.Type = ch
  326. tok.Str = string(ch)
  327. }
  328. case '~':
  329. if sc.Peek() == '=' {
  330. tok.Type = TNeq
  331. tok.Str = "~="
  332. sc.Next()
  333. } else {
  334. err = sc.Error("~", "Invalid '~' token")
  335. }
  336. case '<':
  337. if sc.Peek() == '=' {
  338. tok.Type = TLte
  339. tok.Str = "<="
  340. sc.Next()
  341. } else {
  342. tok.Type = ch
  343. tok.Str = string(ch)
  344. }
  345. case '>':
  346. if sc.Peek() == '=' {
  347. tok.Type = TGte
  348. tok.Str = ">="
  349. sc.Next()
  350. } else {
  351. tok.Type = ch
  352. tok.Str = string(ch)
  353. }
  354. case '.':
  355. ch2 := sc.Peek()
  356. switch {
  357. case isDecimal(ch2):
  358. tok.Type = TNumber
  359. err = sc.scanNumber(ch, buf)
  360. tok.Str = buf.String()
  361. case ch2 == '.':
  362. writeChar(buf, ch)
  363. writeChar(buf, sc.Next())
  364. if sc.Peek() == '.' {
  365. writeChar(buf, sc.Next())
  366. tok.Type = T3Comma
  367. } else {
  368. tok.Type = T2Comma
  369. }
  370. default:
  371. tok.Type = '.'
  372. }
  373. tok.Str = buf.String()
  374. case '+', '*', '/', '%', '^', '#', '(', ')', '{', '}', ']', ';', ':', ',':
  375. tok.Type = ch
  376. tok.Str = string(ch)
  377. default:
  378. writeChar(buf, ch)
  379. err = sc.Error(buf.String(), "Invalid token")
  380. goto finally
  381. }
  382. }
  383. finally:
  384. tok.Name = TokenName(int(tok.Type))
  385. return tok, err
  386. }
  387. // yacc interface {{{
  388. type Lexer struct {
  389. scanner *Scanner
  390. Stmts []ast.Stmt
  391. PNewLine bool
  392. Token ast.Token
  393. }
  394. func (lx *Lexer) Lex(lval *yySymType) int {
  395. tok, err := lx.scanner.Scan(lx)
  396. if err != nil {
  397. panic(err)
  398. }
  399. if tok.Type < 0 {
  400. return 0
  401. }
  402. lval.token = tok
  403. lx.Token = tok
  404. return int(tok.Type)
  405. }
  406. func (lx *Lexer) Error(message string) {
  407. panic(lx.scanner.Error(lx.Token.Str, message))
  408. }
  409. func (lx *Lexer) TokenError(tok ast.Token, message string) {
  410. panic(lx.scanner.TokenError(tok, message))
  411. }
  412. func Parse(reader io.Reader, name string) (chunk []ast.Stmt, err error) {
  413. lexer := &Lexer{NewScanner(reader, name), nil, false, ast.Token{Str: ""}}
  414. chunk = nil
  415. defer func() {
  416. if e := recover(); e != nil {
  417. err, _ = e.(error)
  418. }
  419. }()
  420. yyParse(lexer)
  421. chunk = lexer.Stmts
  422. return
  423. }
  424. // }}}
  425. // Dump {{{
  426. func isInlineDumpNode(rv reflect.Value) bool {
  427. switch rv.Kind() {
  428. case reflect.Struct, reflect.Slice, reflect.Interface, reflect.Ptr:
  429. return false
  430. default:
  431. return true
  432. }
  433. }
  434. func dump(node interface{}, level int, s string) string {
  435. rt := reflect.TypeOf(node)
  436. if fmt.Sprint(rt) == "<nil>" {
  437. return strings.Repeat(s, level) + "<nil>"
  438. }
  439. rv := reflect.ValueOf(node)
  440. buf := []string{}
  441. switch rt.Kind() {
  442. case reflect.Slice:
  443. if rv.Len() == 0 {
  444. return strings.Repeat(s, level) + "<empty>"
  445. }
  446. for i := 0; i < rv.Len(); i++ {
  447. buf = append(buf, dump(rv.Index(i).Interface(), level, s))
  448. }
  449. case reflect.Ptr:
  450. vt := rv.Elem()
  451. tt := rt.Elem()
  452. indicies := []int{}
  453. for i := 0; i < tt.NumField(); i++ {
  454. if strings.Index(tt.Field(i).Name, "Base") > -1 {
  455. continue
  456. }
  457. indicies = append(indicies, i)
  458. }
  459. switch {
  460. case len(indicies) == 0:
  461. return strings.Repeat(s, level) + "<empty>"
  462. case len(indicies) == 1 && isInlineDumpNode(vt.Field(indicies[0])):
  463. for _, i := range indicies {
  464. buf = append(buf, strings.Repeat(s, level)+"- Node$"+tt.Name()+": "+dump(vt.Field(i).Interface(), 0, s))
  465. }
  466. default:
  467. buf = append(buf, strings.Repeat(s, level)+"- Node$"+tt.Name())
  468. for _, i := range indicies {
  469. if isInlineDumpNode(vt.Field(i)) {
  470. inf := dump(vt.Field(i).Interface(), 0, s)
  471. buf = append(buf, strings.Repeat(s, level+1)+tt.Field(i).Name+": "+inf)
  472. } else {
  473. buf = append(buf, strings.Repeat(s, level+1)+tt.Field(i).Name+": ")
  474. buf = append(buf, dump(vt.Field(i).Interface(), level+2, s))
  475. }
  476. }
  477. }
  478. default:
  479. buf = append(buf, strings.Repeat(s, level)+fmt.Sprint(node))
  480. }
  481. return strings.Join(buf, "\n")
  482. }
  483. func Dump(chunk []ast.Stmt) string {
  484. return dump(chunk, 0, " ")
  485. }
  486. // }}