parser.go 23 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  1. package parser
  2. import (
  3. "fmt"
  4. "io"
  5. "sort"
  6. "strconv"
  7. "github.com/d5/tengo/v2/token"
  8. )
  9. type bailout struct{}
  10. var stmtStart = map[token.Token]bool{
  11. token.Break: true,
  12. token.Continue: true,
  13. token.For: true,
  14. token.If: true,
  15. token.Return: true,
  16. token.Export: true,
  17. }
  18. // Error represents a parser error.
  19. type Error struct {
  20. Pos SourceFilePos
  21. Msg string
  22. }
  23. func (e Error) Error() string {
  24. if e.Pos.Filename != "" || e.Pos.IsValid() {
  25. return fmt.Sprintf("Parse Error: %s\n\tat %s", e.Msg, e.Pos)
  26. }
  27. return fmt.Sprintf("Parse Error: %s", e.Msg)
  28. }
  29. // ErrorList is a collection of parser errors.
  30. type ErrorList []*Error
  31. // Add adds a new parser error to the collection.
  32. func (p *ErrorList) Add(pos SourceFilePos, msg string) {
  33. *p = append(*p, &Error{pos, msg})
  34. }
  35. // Len returns the number of elements in the collection.
  36. func (p ErrorList) Len() int {
  37. return len(p)
  38. }
  39. func (p ErrorList) Swap(i, j int) {
  40. p[i], p[j] = p[j], p[i]
  41. }
  42. func (p ErrorList) Less(i, j int) bool {
  43. e := &p[i].Pos
  44. f := &p[j].Pos
  45. if e.Filename != f.Filename {
  46. return e.Filename < f.Filename
  47. }
  48. if e.Line != f.Line {
  49. return e.Line < f.Line
  50. }
  51. if e.Column != f.Column {
  52. return e.Column < f.Column
  53. }
  54. return p[i].Msg < p[j].Msg
  55. }
  56. // Sort sorts the collection.
  57. func (p ErrorList) Sort() {
  58. sort.Sort(p)
  59. }
  60. func (p ErrorList) Error() string {
  61. switch len(p) {
  62. case 0:
  63. return "no errors"
  64. case 1:
  65. return p[0].Error()
  66. }
  67. return fmt.Sprintf("%s (and %d more errors)", p[0], len(p)-1)
  68. }
  69. // Err returns an error.
  70. func (p ErrorList) Err() error {
  71. if len(p) == 0 {
  72. return nil
  73. }
  74. return p
  75. }
  76. // Parser parses the Tengo source files. It's based on Go's parser
  77. // implementation.
  78. type Parser struct {
  79. file *SourceFile
  80. errors ErrorList
  81. scanner *Scanner
  82. pos Pos
  83. token token.Token
  84. tokenLit string
  85. exprLevel int // < 0: in control clause, >= 0: in expression
  86. syncPos Pos // last sync position
  87. syncCount int // number of advance calls without progress
  88. trace bool
  89. indent int
  90. traceOut io.Writer
  91. }
  92. // NewParser creates a Parser.
  93. func NewParser(file *SourceFile, src []byte, trace io.Writer) *Parser {
  94. p := &Parser{
  95. file: file,
  96. trace: trace != nil,
  97. traceOut: trace,
  98. }
  99. p.scanner = NewScanner(p.file, src,
  100. func(pos SourceFilePos, msg string) {
  101. p.errors.Add(pos, msg)
  102. }, 0)
  103. p.next()
  104. return p
  105. }
  106. // ParseFile parses the source and returns an AST file unit.
  107. func (p *Parser) ParseFile() (file *File, err error) {
  108. defer func() {
  109. if e := recover(); e != nil {
  110. if _, ok := e.(bailout); !ok {
  111. panic(e)
  112. }
  113. }
  114. p.errors.Sort()
  115. err = p.errors.Err()
  116. }()
  117. if p.trace {
  118. defer untracep(tracep(p, "File"))
  119. }
  120. if p.errors.Len() > 0 {
  121. return nil, p.errors.Err()
  122. }
  123. stmts := p.parseStmtList()
  124. p.expect(token.EOF)
  125. if p.errors.Len() > 0 {
  126. return nil, p.errors.Err()
  127. }
  128. file = &File{
  129. InputFile: p.file,
  130. Stmts: stmts,
  131. }
  132. return
  133. }
  134. func (p *Parser) parseExpr() Expr {
  135. if p.trace {
  136. defer untracep(tracep(p, "Expression"))
  137. }
  138. expr := p.parseBinaryExpr(token.LowestPrec + 1)
  139. // ternary conditional expression
  140. if p.token == token.Question {
  141. return p.parseCondExpr(expr)
  142. }
  143. return expr
  144. }
  145. func (p *Parser) parseBinaryExpr(prec1 int) Expr {
  146. if p.trace {
  147. defer untracep(tracep(p, "BinaryExpression"))
  148. }
  149. x := p.parseUnaryExpr()
  150. for {
  151. op, prec := p.token, p.token.Precedence()
  152. if prec < prec1 {
  153. return x
  154. }
  155. pos := p.expect(op)
  156. y := p.parseBinaryExpr(prec + 1)
  157. x = &BinaryExpr{
  158. LHS: x,
  159. RHS: y,
  160. Token: op,
  161. TokenPos: pos,
  162. }
  163. }
  164. }
  165. func (p *Parser) parseCondExpr(cond Expr) Expr {
  166. questionPos := p.expect(token.Question)
  167. trueExpr := p.parseExpr()
  168. colonPos := p.expect(token.Colon)
  169. falseExpr := p.parseExpr()
  170. return &CondExpr{
  171. Cond: cond,
  172. True: trueExpr,
  173. False: falseExpr,
  174. QuestionPos: questionPos,
  175. ColonPos: colonPos,
  176. }
  177. }
  178. func (p *Parser) parseUnaryExpr() Expr {
  179. if p.trace {
  180. defer untracep(tracep(p, "UnaryExpression"))
  181. }
  182. switch p.token {
  183. case token.Add, token.Sub, token.Not, token.Xor:
  184. pos, op := p.pos, p.token
  185. p.next()
  186. x := p.parseUnaryExpr()
  187. return &UnaryExpr{
  188. Token: op,
  189. TokenPos: pos,
  190. Expr: x,
  191. }
  192. }
  193. return p.parsePrimaryExpr()
  194. }
  195. func (p *Parser) parsePrimaryExpr() Expr {
  196. if p.trace {
  197. defer untracep(tracep(p, "PrimaryExpression"))
  198. }
  199. x := p.parseOperand()
  200. L:
  201. for {
  202. switch p.token {
  203. case token.Period:
  204. p.next()
  205. switch p.token {
  206. case token.Ident:
  207. x = p.parseSelector(x)
  208. default:
  209. pos := p.pos
  210. p.errorExpected(pos, "selector")
  211. p.advance(stmtStart)
  212. return &BadExpr{From: pos, To: p.pos}
  213. }
  214. case token.LBrack:
  215. x = p.parseIndexOrSlice(x)
  216. case token.LParen:
  217. x = p.parseCall(x)
  218. default:
  219. break L
  220. }
  221. }
  222. return x
  223. }
  224. func (p *Parser) parseCall(x Expr) *CallExpr {
  225. if p.trace {
  226. defer untracep(tracep(p, "Call"))
  227. }
  228. lparen := p.expect(token.LParen)
  229. p.exprLevel++
  230. var list []Expr
  231. var ellipsis Pos
  232. for p.token != token.RParen && p.token != token.EOF && !ellipsis.IsValid() {
  233. list = append(list, p.parseExpr())
  234. if p.token == token.Ellipsis {
  235. ellipsis = p.pos
  236. p.next()
  237. }
  238. if !p.expectComma(token.RParen, "call argument") {
  239. break
  240. }
  241. }
  242. p.exprLevel--
  243. rparen := p.expect(token.RParen)
  244. return &CallExpr{
  245. Func: x,
  246. LParen: lparen,
  247. RParen: rparen,
  248. Ellipsis: ellipsis,
  249. Args: list,
  250. }
  251. }
  252. func (p *Parser) expectComma(closing token.Token, want string) bool {
  253. if p.token == token.Comma {
  254. p.next()
  255. if p.token == closing {
  256. p.errorExpected(p.pos, want)
  257. return false
  258. }
  259. return true
  260. }
  261. if p.token == token.Semicolon && p.tokenLit == "\n" {
  262. p.next()
  263. }
  264. return false
  265. }
  266. func (p *Parser) parseIndexOrSlice(x Expr) Expr {
  267. if p.trace {
  268. defer untracep(tracep(p, "IndexOrSlice"))
  269. }
  270. lbrack := p.expect(token.LBrack)
  271. p.exprLevel++
  272. var index [2]Expr
  273. if p.token != token.Colon {
  274. index[0] = p.parseExpr()
  275. }
  276. numColons := 0
  277. if p.token == token.Colon {
  278. numColons++
  279. p.next()
  280. if p.token != token.RBrack && p.token != token.EOF {
  281. index[1] = p.parseExpr()
  282. }
  283. }
  284. p.exprLevel--
  285. rbrack := p.expect(token.RBrack)
  286. if numColons > 0 {
  287. // slice expression
  288. return &SliceExpr{
  289. Expr: x,
  290. LBrack: lbrack,
  291. RBrack: rbrack,
  292. Low: index[0],
  293. High: index[1],
  294. }
  295. }
  296. return &IndexExpr{
  297. Expr: x,
  298. LBrack: lbrack,
  299. RBrack: rbrack,
  300. Index: index[0],
  301. }
  302. }
  303. func (p *Parser) parseSelector(x Expr) Expr {
  304. if p.trace {
  305. defer untracep(tracep(p, "Selector"))
  306. }
  307. sel := p.parseIdent()
  308. return &SelectorExpr{Expr: x, Sel: &StringLit{
  309. Value: sel.Name,
  310. ValuePos: sel.NamePos,
  311. Literal: sel.Name,
  312. }}
  313. }
  314. func (p *Parser) parseOperand() Expr {
  315. if p.trace {
  316. defer untracep(tracep(p, "Operand"))
  317. }
  318. switch p.token {
  319. case token.Ident:
  320. return p.parseIdent()
  321. case token.Int:
  322. v, err := strconv.ParseInt(p.tokenLit, 0, 64)
  323. if err == strconv.ErrRange {
  324. p.error(p.pos, "number out of range")
  325. } else if err != nil {
  326. p.error(p.pos, "invalid integer")
  327. }
  328. x := &IntLit{
  329. Value: v,
  330. ValuePos: p.pos,
  331. Literal: p.tokenLit,
  332. }
  333. p.next()
  334. return x
  335. case token.Float:
  336. v, err := strconv.ParseFloat(p.tokenLit, 64)
  337. if err == strconv.ErrRange {
  338. p.error(p.pos, "number out of range")
  339. } else if err != nil {
  340. p.error(p.pos, "invalid float")
  341. }
  342. x := &FloatLit{
  343. Value: v,
  344. ValuePos: p.pos,
  345. Literal: p.tokenLit,
  346. }
  347. p.next()
  348. return x
  349. case token.Char:
  350. return p.parseCharLit()
  351. case token.String:
  352. v, _ := strconv.Unquote(p.tokenLit)
  353. x := &StringLit{
  354. Value: v,
  355. ValuePos: p.pos,
  356. Literal: p.tokenLit,
  357. }
  358. p.next()
  359. return x
  360. case token.True:
  361. x := &BoolLit{
  362. Value: true,
  363. ValuePos: p.pos,
  364. Literal: p.tokenLit,
  365. }
  366. p.next()
  367. return x
  368. case token.False:
  369. x := &BoolLit{
  370. Value: false,
  371. ValuePos: p.pos,
  372. Literal: p.tokenLit,
  373. }
  374. p.next()
  375. return x
  376. case token.Undefined:
  377. x := &UndefinedLit{TokenPos: p.pos}
  378. p.next()
  379. return x
  380. case token.Import:
  381. return p.parseImportExpr()
  382. case token.LParen:
  383. lparen := p.pos
  384. p.next()
  385. p.exprLevel++
  386. x := p.parseExpr()
  387. p.exprLevel--
  388. rparen := p.expect(token.RParen)
  389. return &ParenExpr{
  390. LParen: lparen,
  391. Expr: x,
  392. RParen: rparen,
  393. }
  394. case token.LBrack: // array literal
  395. return p.parseArrayLit()
  396. case token.LBrace: // map literal
  397. return p.parseMapLit()
  398. case token.Func: // function literal
  399. return p.parseFuncLit()
  400. case token.Error: // error expression
  401. return p.parseErrorExpr()
  402. case token.Immutable: // immutable expression
  403. return p.parseImmutableExpr()
  404. default:
  405. p.errorExpected(p.pos, "operand")
  406. }
  407. pos := p.pos
  408. p.advance(stmtStart)
  409. return &BadExpr{From: pos, To: p.pos}
  410. }
  411. func (p *Parser) parseImportExpr() Expr {
  412. pos := p.pos
  413. p.next()
  414. p.expect(token.LParen)
  415. if p.token != token.String {
  416. p.errorExpected(p.pos, "module name")
  417. p.advance(stmtStart)
  418. return &BadExpr{From: pos, To: p.pos}
  419. }
  420. // module name
  421. moduleName, _ := strconv.Unquote(p.tokenLit)
  422. expr := &ImportExpr{
  423. ModuleName: moduleName,
  424. Token: token.Import,
  425. TokenPos: pos,
  426. }
  427. p.next()
  428. p.expect(token.RParen)
  429. return expr
  430. }
  431. func (p *Parser) parseCharLit() Expr {
  432. if n := len(p.tokenLit); n >= 3 {
  433. code, _, _, err := strconv.UnquoteChar(p.tokenLit[1:n-1], '\'')
  434. if err == nil {
  435. x := &CharLit{
  436. Value: code,
  437. ValuePos: p.pos,
  438. Literal: p.tokenLit,
  439. }
  440. p.next()
  441. return x
  442. }
  443. }
  444. pos := p.pos
  445. p.error(pos, "illegal char literal")
  446. p.next()
  447. return &BadExpr{
  448. From: pos,
  449. To: p.pos,
  450. }
  451. }
  452. func (p *Parser) parseFuncLit() Expr {
  453. if p.trace {
  454. defer untracep(tracep(p, "FuncLit"))
  455. }
  456. typ := p.parseFuncType()
  457. p.exprLevel++
  458. body := p.parseBody()
  459. p.exprLevel--
  460. return &FuncLit{
  461. Type: typ,
  462. Body: body,
  463. }
  464. }
  465. func (p *Parser) parseArrayLit() Expr {
  466. if p.trace {
  467. defer untracep(tracep(p, "ArrayLit"))
  468. }
  469. lbrack := p.expect(token.LBrack)
  470. p.exprLevel++
  471. var elements []Expr
  472. for p.token != token.RBrack && p.token != token.EOF {
  473. elements = append(elements, p.parseExpr())
  474. if !p.expectComma(token.RBrack, "array element") {
  475. break
  476. }
  477. }
  478. p.exprLevel--
  479. rbrack := p.expect(token.RBrack)
  480. return &ArrayLit{
  481. Elements: elements,
  482. LBrack: lbrack,
  483. RBrack: rbrack,
  484. }
  485. }
  486. func (p *Parser) parseErrorExpr() Expr {
  487. pos := p.pos
  488. p.next()
  489. lparen := p.expect(token.LParen)
  490. value := p.parseExpr()
  491. rparen := p.expect(token.RParen)
  492. return &ErrorExpr{
  493. ErrorPos: pos,
  494. Expr: value,
  495. LParen: lparen,
  496. RParen: rparen,
  497. }
  498. }
  499. func (p *Parser) parseImmutableExpr() Expr {
  500. pos := p.pos
  501. p.next()
  502. lparen := p.expect(token.LParen)
  503. value := p.parseExpr()
  504. rparen := p.expect(token.RParen)
  505. return &ImmutableExpr{
  506. ErrorPos: pos,
  507. Expr: value,
  508. LParen: lparen,
  509. RParen: rparen,
  510. }
  511. }
  512. func (p *Parser) parseFuncType() *FuncType {
  513. if p.trace {
  514. defer untracep(tracep(p, "FuncType"))
  515. }
  516. pos := p.expect(token.Func)
  517. params := p.parseIdentList()
  518. return &FuncType{
  519. FuncPos: pos,
  520. Params: params,
  521. }
  522. }
  523. func (p *Parser) parseBody() *BlockStmt {
  524. if p.trace {
  525. defer untracep(tracep(p, "Body"))
  526. }
  527. lbrace := p.expect(token.LBrace)
  528. list := p.parseStmtList()
  529. rbrace := p.expect(token.RBrace)
  530. return &BlockStmt{
  531. LBrace: lbrace,
  532. RBrace: rbrace,
  533. Stmts: list,
  534. }
  535. }
  536. func (p *Parser) parseStmtList() (list []Stmt) {
  537. if p.trace {
  538. defer untracep(tracep(p, "StatementList"))
  539. }
  540. for p.token != token.RBrace && p.token != token.EOF {
  541. list = append(list, p.parseStmt())
  542. }
  543. return
  544. }
  545. func (p *Parser) parseIdent() *Ident {
  546. pos := p.pos
  547. name := "_"
  548. if p.token == token.Ident {
  549. name = p.tokenLit
  550. p.next()
  551. } else {
  552. p.expect(token.Ident)
  553. }
  554. return &Ident{
  555. NamePos: pos,
  556. Name: name,
  557. }
  558. }
  559. func (p *Parser) parseIdentList() *IdentList {
  560. if p.trace {
  561. defer untracep(tracep(p, "IdentList"))
  562. }
  563. var params []*Ident
  564. lparen := p.expect(token.LParen)
  565. isVarArgs := false
  566. if p.token != token.RParen {
  567. if p.token == token.Ellipsis {
  568. isVarArgs = true
  569. p.next()
  570. }
  571. params = append(params, p.parseIdent())
  572. for !isVarArgs && p.token == token.Comma {
  573. p.next()
  574. if p.token == token.Ellipsis {
  575. isVarArgs = true
  576. p.next()
  577. }
  578. params = append(params, p.parseIdent())
  579. }
  580. }
  581. rparen := p.expect(token.RParen)
  582. return &IdentList{
  583. LParen: lparen,
  584. RParen: rparen,
  585. VarArgs: isVarArgs,
  586. List: params,
  587. }
  588. }
  589. func (p *Parser) parseStmt() (stmt Stmt) {
  590. if p.trace {
  591. defer untracep(tracep(p, "Statement"))
  592. }
  593. switch p.token {
  594. case // simple statements
  595. token.Func, token.Error, token.Immutable, token.Ident, token.Int,
  596. token.Float, token.Char, token.String, token.True, token.False,
  597. token.Undefined, token.Import, token.LParen, token.LBrace,
  598. token.LBrack, token.Add, token.Sub, token.Mul, token.And, token.Xor,
  599. token.Not:
  600. s := p.parseSimpleStmt(false)
  601. p.expectSemi()
  602. return s
  603. case token.Return:
  604. return p.parseReturnStmt()
  605. case token.Export:
  606. return p.parseExportStmt()
  607. case token.If:
  608. return p.parseIfStmt()
  609. case token.For:
  610. return p.parseForStmt()
  611. case token.Break, token.Continue:
  612. return p.parseBranchStmt(p.token)
  613. case token.Semicolon:
  614. s := &EmptyStmt{Semicolon: p.pos, Implicit: p.tokenLit == "\n"}
  615. p.next()
  616. return s
  617. case token.RBrace:
  618. // semicolon may be omitted before a closing "}"
  619. return &EmptyStmt{Semicolon: p.pos, Implicit: true}
  620. default:
  621. pos := p.pos
  622. p.errorExpected(pos, "statement")
  623. p.advance(stmtStart)
  624. return &BadStmt{From: pos, To: p.pos}
  625. }
  626. }
  627. func (p *Parser) parseForStmt() Stmt {
  628. if p.trace {
  629. defer untracep(tracep(p, "ForStmt"))
  630. }
  631. pos := p.expect(token.For)
  632. // for {}
  633. if p.token == token.LBrace {
  634. body := p.parseBlockStmt()
  635. p.expectSemi()
  636. return &ForStmt{
  637. ForPos: pos,
  638. Body: body,
  639. }
  640. }
  641. prevLevel := p.exprLevel
  642. p.exprLevel = -1
  643. var s1 Stmt
  644. if p.token != token.Semicolon { // skipping init
  645. s1 = p.parseSimpleStmt(true)
  646. }
  647. // for _ in seq {} or
  648. // for value in seq {} or
  649. // for key, value in seq {}
  650. if forInStmt, isForIn := s1.(*ForInStmt); isForIn {
  651. forInStmt.ForPos = pos
  652. p.exprLevel = prevLevel
  653. forInStmt.Body = p.parseBlockStmt()
  654. p.expectSemi()
  655. return forInStmt
  656. }
  657. // for init; cond; post {}
  658. var s2, s3 Stmt
  659. if p.token == token.Semicolon {
  660. p.next()
  661. if p.token != token.Semicolon {
  662. s2 = p.parseSimpleStmt(false) // cond
  663. }
  664. p.expect(token.Semicolon)
  665. if p.token != token.LBrace {
  666. s3 = p.parseSimpleStmt(false) // post
  667. }
  668. } else {
  669. // for cond {}
  670. s2 = s1
  671. s1 = nil
  672. }
  673. // body
  674. p.exprLevel = prevLevel
  675. body := p.parseBlockStmt()
  676. p.expectSemi()
  677. cond := p.makeExpr(s2, "condition expression")
  678. return &ForStmt{
  679. ForPos: pos,
  680. Init: s1,
  681. Cond: cond,
  682. Post: s3,
  683. Body: body,
  684. }
  685. }
  686. func (p *Parser) parseBranchStmt(tok token.Token) Stmt {
  687. if p.trace {
  688. defer untracep(tracep(p, "BranchStmt"))
  689. }
  690. pos := p.expect(tok)
  691. var label *Ident
  692. if p.token == token.Ident {
  693. label = p.parseIdent()
  694. }
  695. p.expectSemi()
  696. return &BranchStmt{
  697. Token: tok,
  698. TokenPos: pos,
  699. Label: label,
  700. }
  701. }
  702. func (p *Parser) parseIfStmt() Stmt {
  703. if p.trace {
  704. defer untracep(tracep(p, "IfStmt"))
  705. }
  706. pos := p.expect(token.If)
  707. init, cond := p.parseIfHeader()
  708. body := p.parseBlockStmt()
  709. var elseStmt Stmt
  710. if p.token == token.Else {
  711. p.next()
  712. switch p.token {
  713. case token.If:
  714. elseStmt = p.parseIfStmt()
  715. case token.LBrace:
  716. elseStmt = p.parseBlockStmt()
  717. p.expectSemi()
  718. default:
  719. p.errorExpected(p.pos, "if or {")
  720. elseStmt = &BadStmt{From: p.pos, To: p.pos}
  721. }
  722. } else {
  723. p.expectSemi()
  724. }
  725. return &IfStmt{
  726. IfPos: pos,
  727. Init: init,
  728. Cond: cond,
  729. Body: body,
  730. Else: elseStmt,
  731. }
  732. }
  733. func (p *Parser) parseBlockStmt() *BlockStmt {
  734. if p.trace {
  735. defer untracep(tracep(p, "BlockStmt"))
  736. }
  737. lbrace := p.expect(token.LBrace)
  738. list := p.parseStmtList()
  739. rbrace := p.expect(token.RBrace)
  740. return &BlockStmt{
  741. LBrace: lbrace,
  742. RBrace: rbrace,
  743. Stmts: list,
  744. }
  745. }
  746. func (p *Parser) parseIfHeader() (init Stmt, cond Expr) {
  747. if p.token == token.LBrace {
  748. p.error(p.pos, "missing condition in if statement")
  749. cond = &BadExpr{From: p.pos, To: p.pos}
  750. return
  751. }
  752. outer := p.exprLevel
  753. p.exprLevel = -1
  754. if p.token == token.Semicolon {
  755. p.error(p.pos, "missing init in if statement")
  756. return
  757. }
  758. init = p.parseSimpleStmt(false)
  759. var condStmt Stmt
  760. if p.token == token.LBrace {
  761. condStmt = init
  762. init = nil
  763. } else if p.token == token.Semicolon {
  764. p.next()
  765. condStmt = p.parseSimpleStmt(false)
  766. } else {
  767. p.error(p.pos, "missing condition in if statement")
  768. }
  769. if condStmt != nil {
  770. cond = p.makeExpr(condStmt, "boolean expression")
  771. }
  772. if cond == nil {
  773. cond = &BadExpr{From: p.pos, To: p.pos}
  774. }
  775. p.exprLevel = outer
  776. return
  777. }
  778. func (p *Parser) makeExpr(s Stmt, want string) Expr {
  779. if s == nil {
  780. return nil
  781. }
  782. if es, isExpr := s.(*ExprStmt); isExpr {
  783. return es.Expr
  784. }
  785. found := "simple statement"
  786. if _, isAss := s.(*AssignStmt); isAss {
  787. found = "assignment"
  788. }
  789. p.error(s.Pos(), fmt.Sprintf("expected %s, found %s", want, found))
  790. return &BadExpr{From: s.Pos(), To: p.safePos(s.End())}
  791. }
  792. func (p *Parser) parseReturnStmt() Stmt {
  793. if p.trace {
  794. defer untracep(tracep(p, "ReturnStmt"))
  795. }
  796. pos := p.pos
  797. p.expect(token.Return)
  798. var x Expr
  799. if p.token != token.Semicolon && p.token != token.RBrace {
  800. x = p.parseExpr()
  801. }
  802. p.expectSemi()
  803. return &ReturnStmt{
  804. ReturnPos: pos,
  805. Result: x,
  806. }
  807. }
  808. func (p *Parser) parseExportStmt() Stmt {
  809. if p.trace {
  810. defer untracep(tracep(p, "ExportStmt"))
  811. }
  812. pos := p.pos
  813. p.expect(token.Export)
  814. x := p.parseExpr()
  815. p.expectSemi()
  816. return &ExportStmt{
  817. ExportPos: pos,
  818. Result: x,
  819. }
  820. }
  821. func (p *Parser) parseSimpleStmt(forIn bool) Stmt {
  822. if p.trace {
  823. defer untracep(tracep(p, "SimpleStmt"))
  824. }
  825. x := p.parseExprList()
  826. switch p.token {
  827. case token.Assign, token.Define: // assignment statement
  828. pos, tok := p.pos, p.token
  829. p.next()
  830. y := p.parseExprList()
  831. return &AssignStmt{
  832. LHS: x,
  833. RHS: y,
  834. Token: tok,
  835. TokenPos: pos,
  836. }
  837. case token.In:
  838. if forIn {
  839. p.next()
  840. y := p.parseExpr()
  841. var key, value *Ident
  842. var ok bool
  843. switch len(x) {
  844. case 1:
  845. key = &Ident{Name: "_", NamePos: x[0].Pos()}
  846. value, ok = x[0].(*Ident)
  847. if !ok {
  848. p.errorExpected(x[0].Pos(), "identifier")
  849. value = &Ident{Name: "_", NamePos: x[0].Pos()}
  850. }
  851. case 2:
  852. key, ok = x[0].(*Ident)
  853. if !ok {
  854. p.errorExpected(x[0].Pos(), "identifier")
  855. key = &Ident{Name: "_", NamePos: x[0].Pos()}
  856. }
  857. value, ok = x[1].(*Ident)
  858. if !ok {
  859. p.errorExpected(x[1].Pos(), "identifier")
  860. value = &Ident{Name: "_", NamePos: x[1].Pos()}
  861. }
  862. }
  863. return &ForInStmt{
  864. Key: key,
  865. Value: value,
  866. Iterable: y,
  867. }
  868. }
  869. }
  870. if len(x) > 1 {
  871. p.errorExpected(x[0].Pos(), "1 expression")
  872. // continue with first expression
  873. }
  874. switch p.token {
  875. case token.Define,
  876. token.AddAssign, token.SubAssign, token.MulAssign, token.QuoAssign,
  877. token.RemAssign, token.AndAssign, token.OrAssign, token.XorAssign,
  878. token.ShlAssign, token.ShrAssign, token.AndNotAssign:
  879. pos, tok := p.pos, p.token
  880. p.next()
  881. y := p.parseExpr()
  882. return &AssignStmt{
  883. LHS: []Expr{x[0]},
  884. RHS: []Expr{y},
  885. Token: tok,
  886. TokenPos: pos,
  887. }
  888. case token.Inc, token.Dec:
  889. // increment or decrement statement
  890. s := &IncDecStmt{Expr: x[0], Token: p.token, TokenPos: p.pos}
  891. p.next()
  892. return s
  893. }
  894. return &ExprStmt{Expr: x[0]}
  895. }
  896. func (p *Parser) parseExprList() (list []Expr) {
  897. if p.trace {
  898. defer untracep(tracep(p, "ExpressionList"))
  899. }
  900. list = append(list, p.parseExpr())
  901. for p.token == token.Comma {
  902. p.next()
  903. list = append(list, p.parseExpr())
  904. }
  905. return
  906. }
  907. func (p *Parser) parseMapElementLit() *MapElementLit {
  908. if p.trace {
  909. defer untracep(tracep(p, "MapElementLit"))
  910. }
  911. pos := p.pos
  912. name := "_"
  913. if p.token == token.Ident {
  914. name = p.tokenLit
  915. } else if p.token == token.String {
  916. v, _ := strconv.Unquote(p.tokenLit)
  917. name = v
  918. } else {
  919. p.errorExpected(pos, "map key")
  920. }
  921. p.next()
  922. colonPos := p.expect(token.Colon)
  923. valueExpr := p.parseExpr()
  924. return &MapElementLit{
  925. Key: name,
  926. KeyPos: pos,
  927. ColonPos: colonPos,
  928. Value: valueExpr,
  929. }
  930. }
  931. func (p *Parser) parseMapLit() *MapLit {
  932. if p.trace {
  933. defer untracep(tracep(p, "MapLit"))
  934. }
  935. lbrace := p.expect(token.LBrace)
  936. p.exprLevel++
  937. var elements []*MapElementLit
  938. for p.token != token.RBrace && p.token != token.EOF {
  939. elements = append(elements, p.parseMapElementLit())
  940. if !p.expectComma(token.RBrace, "map element") {
  941. break
  942. }
  943. }
  944. p.exprLevel--
  945. rbrace := p.expect(token.RBrace)
  946. return &MapLit{
  947. LBrace: lbrace,
  948. RBrace: rbrace,
  949. Elements: elements,
  950. }
  951. }
  952. func (p *Parser) expect(token token.Token) Pos {
  953. pos := p.pos
  954. if p.token != token {
  955. p.errorExpected(pos, "'"+token.String()+"'")
  956. }
  957. p.next()
  958. return pos
  959. }
  960. func (p *Parser) expectSemi() {
  961. switch p.token {
  962. case token.RParen, token.RBrace:
  963. // semicolon is optional before a closing ')' or '}'
  964. case token.Comma:
  965. // permit a ',' instead of a ';' but complain
  966. p.errorExpected(p.pos, "';'")
  967. fallthrough
  968. case token.Semicolon:
  969. p.next()
  970. default:
  971. p.errorExpected(p.pos, "';'")
  972. p.advance(stmtStart)
  973. }
  974. }
  975. func (p *Parser) advance(to map[token.Token]bool) {
  976. for ; p.token != token.EOF; p.next() {
  977. if to[p.token] {
  978. if p.pos == p.syncPos && p.syncCount < 10 {
  979. p.syncCount++
  980. return
  981. }
  982. if p.pos > p.syncPos {
  983. p.syncPos = p.pos
  984. p.syncCount = 0
  985. return
  986. }
  987. }
  988. }
  989. }
  990. func (p *Parser) error(pos Pos, msg string) {
  991. filePos := p.file.Position(pos)
  992. n := len(p.errors)
  993. if n > 0 && p.errors[n-1].Pos.Line == filePos.Line {
  994. // discard errors reported on the same line
  995. return
  996. }
  997. if n > 10 {
  998. // too many errors; terminate early
  999. panic(bailout{})
  1000. }
  1001. p.errors.Add(filePos, msg)
  1002. }
  1003. func (p *Parser) errorExpected(pos Pos, msg string) {
  1004. msg = "expected " + msg
  1005. if pos == p.pos {
  1006. // error happened at the current position: provide more specific
  1007. switch {
  1008. case p.token == token.Semicolon && p.tokenLit == "\n":
  1009. msg += ", found newline"
  1010. case p.token.IsLiteral():
  1011. msg += ", found " + p.tokenLit
  1012. default:
  1013. msg += ", found '" + p.token.String() + "'"
  1014. }
  1015. }
  1016. p.error(pos, msg)
  1017. }
  1018. func (p *Parser) next() {
  1019. if p.trace && p.pos.IsValid() {
  1020. s := p.token.String()
  1021. switch {
  1022. case p.token.IsLiteral():
  1023. p.printTrace(s, p.tokenLit)
  1024. case p.token.IsOperator(), p.token.IsKeyword():
  1025. p.printTrace(`"` + s + `"`)
  1026. default:
  1027. p.printTrace(s)
  1028. }
  1029. }
  1030. p.token, p.tokenLit, p.pos = p.scanner.Scan()
  1031. }
  1032. func (p *Parser) printTrace(a ...interface{}) {
  1033. const (
  1034. dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
  1035. n = len(dots)
  1036. )
  1037. filePos := p.file.Position(p.pos)
  1038. _, _ = fmt.Fprintf(p.traceOut, "%5d: %5d:%3d: ", p.pos, filePos.Line,
  1039. filePos.Column)
  1040. i := 2 * p.indent
  1041. for i > n {
  1042. _, _ = fmt.Fprint(p.traceOut, dots)
  1043. i -= n
  1044. }
  1045. _, _ = fmt.Fprint(p.traceOut, dots[0:i])
  1046. _, _ = fmt.Fprintln(p.traceOut, a...)
  1047. }
  1048. func (p *Parser) safePos(pos Pos) Pos {
  1049. fileBase := p.file.Base
  1050. fileSize := p.file.Size
  1051. if int(pos) < fileBase || int(pos) > fileBase+fileSize {
  1052. return Pos(fileBase + fileSize)
  1053. }
  1054. return pos
  1055. }
  1056. func tracep(p *Parser, msg string) *Parser {
  1057. p.printTrace(msg, "(")
  1058. p.indent++
  1059. return p
  1060. }
  1061. func untracep(p *Parser) {
  1062. p.indent--
  1063. p.printTrace(")")
  1064. }