parse.go 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  1. // Copyright 2016 José Santos <henrique_1609@me.com>
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package jet
  15. import (
  16. "bytes"
  17. "fmt"
  18. "runtime"
  19. "strconv"
  20. "strings"
  21. )
  22. func unquote(text string) (string, error) {
  23. return strconv.Unquote(text)
  24. }
  25. // Template is the representation of a single parsed template.
  26. type Template struct {
  27. Name string // name of the template represented by the tree.
  28. ParseName string // name of the top-level template during parsing, for error messages.
  29. set *Set
  30. extends *Template
  31. imports []*Template
  32. processedBlocks map[string]*BlockNode
  33. passedBlocks map[string]*BlockNode
  34. Root *ListNode // top-level root of the tree.
  35. text string // text parsed to create the template (or its parent)
  36. // Parsing only; cleared after parse.
  37. lex *lexer
  38. token [3]item // three-token lookahead for parser.
  39. peekCount int
  40. }
  41. // next returns the next token.
  42. func (t *Template) next() item {
  43. if t.peekCount > 0 {
  44. t.peekCount--
  45. } else {
  46. t.token[0] = t.lex.nextItem()
  47. }
  48. return t.token[t.peekCount]
  49. }
  50. // backup backs the input stream up one token.
  51. func (t *Template) backup() {
  52. t.peekCount++
  53. }
  54. // backup2 backs the input stream up two tokens.
  55. // The zeroth token is already there.
  56. func (t *Template) backup2(t1 item) {
  57. t.token[1] = t1
  58. t.peekCount = 2
  59. }
  60. // backup3 backs the input stream up three tokens
  61. // The zeroth token is already there.
  62. func (t *Template) backup3(t2, t1 item) {
  63. // Reverse order: we're pushing back.
  64. t.token[1] = t1
  65. t.token[2] = t2
  66. t.peekCount = 3
  67. }
  68. // peek returns but does not consume the next token.
  69. func (t *Template) peek() item {
  70. if t.peekCount > 0 {
  71. return t.token[t.peekCount-1]
  72. }
  73. t.peekCount = 1
  74. t.token[0] = t.lex.nextItem()
  75. return t.token[0]
  76. }
  77. // nextNonSpace returns the next non-space token.
  78. func (t *Template) nextNonSpace() (token item) {
  79. for {
  80. token = t.next()
  81. if token.typ != itemSpace {
  82. break
  83. }
  84. }
  85. return token
  86. }
  87. // peekNonSpace returns but does not consume the next non-space token.
  88. func (t *Template) peekNonSpace() (token item) {
  89. for {
  90. token = t.next()
  91. if token.typ != itemSpace {
  92. break
  93. }
  94. }
  95. t.backup()
  96. return token
  97. }
  98. // errorf formats the error and terminates processing.
  99. func (t *Template) errorf(format string, args ...interface{}) {
  100. t.Root = nil
  101. format = fmt.Sprintf("template: %s:%d: %s", t.ParseName, t.lex.lineNumber(), format)
  102. panic(fmt.Errorf(format, args...))
  103. }
  104. // error terminates processing.
  105. func (t *Template) error(err error) {
  106. t.errorf("%s", err)
  107. }
  108. // expect consumes the next token and guarantees it has the required type.
  109. func (t *Template) expect(expectedType itemType, context, expected string) item {
  110. token := t.nextNonSpace()
  111. if token.typ != expectedType {
  112. t.unexpected(token, context, expected)
  113. }
  114. return token
  115. }
  116. func (t *Template) expectRightDelim(context string) item {
  117. return t.expect(itemRightDelim, context, "closing delimiter")
  118. }
  119. // expectOneOf consumes the next token and guarantees it has one of the required types.
  120. func (t *Template) expectOneOf(expected1, expected2 itemType, context, expectedAs string) item {
  121. token := t.nextNonSpace()
  122. if token.typ != expected1 && token.typ != expected2 {
  123. t.unexpected(token, context, expectedAs)
  124. }
  125. return token
  126. }
  127. // unexpected complains about the token and terminates processing.
  128. func (t *Template) unexpected(token item, context, expected string) {
  129. switch {
  130. case token.typ == itemImport,
  131. token.typ == itemExtends:
  132. t.errorf("parsing %s: unexpected keyword '%s' ('%s' statements must be at the beginning of the template)", context, token.val, token.val)
  133. case token.typ > itemKeyword:
  134. t.errorf("parsing %s: unexpected keyword '%s' (expected %s)", context, token.val, expected)
  135. default:
  136. t.errorf("parsing %s: unexpected token '%s' (expected %s)", context, token.val, expected)
  137. }
  138. }
  139. // recover is the handler that turns panics into returns from the top level of Parse.
  140. func (t *Template) recover(errp *error) {
  141. e := recover()
  142. if e != nil {
  143. if _, ok := e.(runtime.Error); ok {
  144. panic(e)
  145. }
  146. if t != nil {
  147. t.lex.drain()
  148. t.stopParse()
  149. }
  150. *errp = e.(error)
  151. }
  152. return
  153. }
  154. func (s *Set) parse(name, text string) (t *Template, err error) {
  155. t = &Template{
  156. Name: name,
  157. ParseName: name,
  158. text: text,
  159. set: s,
  160. passedBlocks: make(map[string]*BlockNode),
  161. }
  162. defer t.recover(&err)
  163. lexer := lex(name, text, false)
  164. lexer.setDelimiters(s.leftDelim, s.rightDelim)
  165. lexer.run()
  166. t.startParse(lexer)
  167. t.parseTemplate()
  168. t.stopParse()
  169. if t.extends != nil {
  170. t.addBlocks(t.extends.processedBlocks)
  171. }
  172. for _, _import := range t.imports {
  173. t.addBlocks(_import.processedBlocks)
  174. }
  175. t.addBlocks(t.passedBlocks)
  176. return t, err
  177. }
  178. func (t *Template) expectString(context string) string {
  179. token := t.expectOneOf(itemString, itemRawString, context, "string literal")
  180. s, err := unquote(token.val)
  181. if err != nil {
  182. t.error(err)
  183. }
  184. return s
  185. }
  186. // parse is the top-level parser for a template, essentially the same
  187. // It runs to EOF.
  188. func (t *Template) parseTemplate() (next Node) {
  189. t.Root = t.newList(t.peek().pos)
  190. // {{ extends|import stringLiteral }}
  191. for t.peek().typ != itemEOF {
  192. delim := t.next()
  193. if delim.typ == itemText && strings.TrimSpace(delim.val) == "" {
  194. continue //skips empty text nodes
  195. }
  196. if delim.typ == itemLeftDelim {
  197. token := t.nextNonSpace()
  198. if token.typ == itemExtends || token.typ == itemImport {
  199. s := t.expectString("extends|import")
  200. if token.typ == itemExtends {
  201. if t.extends != nil {
  202. t.errorf("Unexpected extends clause: each template can only extend one template")
  203. } else if len(t.imports) > 0 {
  204. t.errorf("Unexpected extends clause: the 'extends' clause should come before all import clauses")
  205. }
  206. var err error
  207. t.extends, err = t.set.getSiblingTemplate(s, t.Name)
  208. if err != nil {
  209. t.error(err)
  210. }
  211. } else {
  212. tt, err := t.set.getSiblingTemplate(s, t.Name)
  213. if err != nil {
  214. t.error(err)
  215. }
  216. t.imports = append(t.imports, tt)
  217. }
  218. t.expect(itemRightDelim, "extends|import", "closing delimiter")
  219. } else {
  220. t.backup2(delim)
  221. break
  222. }
  223. } else {
  224. t.backup()
  225. break
  226. }
  227. }
  228. for t.peek().typ != itemEOF {
  229. switch n := t.textOrAction(); n.Type() {
  230. case nodeEnd, nodeElse, nodeContent:
  231. t.errorf("unexpected %s", n)
  232. default:
  233. t.Root.append(n)
  234. }
  235. }
  236. return nil
  237. }
  238. // startParse initializes the parser, using the lexer.
  239. func (t *Template) startParse(lex *lexer) {
  240. t.Root = nil
  241. t.lex = lex
  242. }
  243. // stopParse terminates parsing.
  244. func (t *Template) stopParse() {
  245. t.lex = nil
  246. }
  247. // IsEmptyTree reports whether this tree (node) is empty of everything but space.
  248. func IsEmptyTree(n Node) bool {
  249. switch n := n.(type) {
  250. case nil:
  251. return true
  252. case *ActionNode:
  253. case *IfNode:
  254. case *ListNode:
  255. for _, node := range n.Nodes {
  256. if !IsEmptyTree(node) {
  257. return false
  258. }
  259. }
  260. return true
  261. case *RangeNode:
  262. case *IncludeNode:
  263. case *TextNode:
  264. return len(bytes.TrimSpace(n.Text)) == 0
  265. case *BlockNode:
  266. case *YieldNode:
  267. default:
  268. panic("unknown node: " + n.String())
  269. }
  270. return false
  271. }
  272. func (t *Template) blockParametersList(isDeclaring bool, context string) *BlockParameterList {
  273. block := &BlockParameterList{}
  274. t.expect(itemLeftParen, context, "opening parenthesis")
  275. for {
  276. var expression Expression
  277. next := t.nextNonSpace()
  278. if next.typ == itemIdentifier {
  279. identifier := next.val
  280. next2 := t.nextNonSpace()
  281. switch next2.typ {
  282. case itemComma, itemRightParen:
  283. block.List = append(block.List, BlockParameter{Identifier: identifier})
  284. next = next2
  285. case itemAssign:
  286. expression, next = t.parseExpression(context)
  287. block.List = append(block.List, BlockParameter{Identifier: identifier, Expression: expression})
  288. default:
  289. if !isDeclaring {
  290. switch next2.typ {
  291. case itemComma, itemRightParen:
  292. default:
  293. t.backup2(next)
  294. expression, next = t.parseExpression(context)
  295. block.List = append(block.List, BlockParameter{Expression: expression})
  296. }
  297. } else {
  298. t.unexpected(next2, context, "comma, assignment, or closing parenthesis")
  299. }
  300. }
  301. } else if !isDeclaring {
  302. switch next.typ {
  303. case itemComma, itemRightParen:
  304. default:
  305. t.backup()
  306. expression, next = t.parseExpression(context)
  307. block.List = append(block.List, BlockParameter{Expression: expression})
  308. }
  309. }
  310. if next.typ != itemComma {
  311. t.backup()
  312. break
  313. }
  314. }
  315. t.expect(itemRightParen, context, "closing parenthesis")
  316. return block
  317. }
  318. func (t *Template) parseBlock() Node {
  319. const context = "block clause"
  320. var pipe Expression
  321. name := t.expect(itemIdentifier, context, "name")
  322. bplist := t.blockParametersList(true, context)
  323. if t.peekNonSpace().typ != itemRightDelim {
  324. pipe = t.expression(context, "context")
  325. }
  326. t.expectRightDelim(context)
  327. list, end := t.itemList(nodeContent, nodeEnd)
  328. var contentList *ListNode
  329. if end.Type() == nodeContent {
  330. contentList, end = t.itemList(nodeEnd)
  331. }
  332. block := t.newBlock(name.pos, t.lex.lineNumber(), name.val, bplist, pipe, list, contentList)
  333. t.passedBlocks[block.Name] = block
  334. return block
  335. }
  336. func (t *Template) parseYield() Node {
  337. const context = "yield clause"
  338. var (
  339. pipe Expression
  340. name item
  341. bplist *BlockParameterList
  342. content *ListNode
  343. )
  344. // parse block name
  345. name = t.nextNonSpace()
  346. if name.typ == itemContent {
  347. // content yield {{yield content}}
  348. if t.peekNonSpace().typ != itemRightDelim {
  349. pipe = t.expression(context, "content context")
  350. }
  351. t.expectRightDelim(context)
  352. return t.newYield(name.pos, t.lex.lineNumber(), "", nil, pipe, nil, true)
  353. } else if name.typ != itemIdentifier {
  354. t.unexpected(name, context, "block name")
  355. }
  356. // parse block parameters
  357. bplist = t.blockParametersList(false, context)
  358. // parse optional context & content
  359. typ := t.peekNonSpace().typ
  360. if typ == itemRightDelim {
  361. t.expectRightDelim(context)
  362. } else {
  363. if typ != itemContent {
  364. // parse context expression
  365. pipe = t.expression("yield", "context")
  366. typ = t.peekNonSpace().typ
  367. }
  368. if typ == itemRightDelim {
  369. t.expectRightDelim(context)
  370. } else if typ == itemContent {
  371. // parse content from following nodes (until {{end}})
  372. t.nextNonSpace()
  373. t.expectRightDelim(context)
  374. content, _ = t.itemList(nodeEnd)
  375. } else {
  376. t.unexpected(t.nextNonSpace(), context, "content keyword or closing delimiter")
  377. }
  378. }
  379. return t.newYield(name.pos, t.lex.lineNumber(), name.val, bplist, pipe, content, false)
  380. }
  381. func (t *Template) parseInclude() Node {
  382. var context Expression
  383. name := t.expression("include", "template name")
  384. if t.peekNonSpace().typ != itemRightDelim {
  385. context = t.expression("include", "context")
  386. }
  387. t.expectRightDelim("include invocation")
  388. return t.newInclude(name.Position(), t.lex.lineNumber(), name, context)
  389. }
  390. func (t *Template) parseReturn() Node {
  391. value := t.expression("return", "value")
  392. t.expectRightDelim("return")
  393. return t.newReturn(value.Position(), t.lex.lineNumber(), value)
  394. }
  395. // itemList:
  396. // textOrAction*
  397. // Terminates at any of the given nodes, returned separately.
  398. func (t *Template) itemList(terminatedBy ...NodeType) (list *ListNode, next Node) {
  399. list = t.newList(t.peekNonSpace().pos)
  400. for t.peekNonSpace().typ != itemEOF {
  401. n := t.textOrAction()
  402. for _, terminatorType := range terminatedBy {
  403. if n.Type() == terminatorType {
  404. return list, n
  405. }
  406. }
  407. list.append(n)
  408. }
  409. t.errorf("unexpected EOF")
  410. return
  411. }
  412. // textOrAction:
  413. // text | action
  414. func (t *Template) textOrAction() Node {
  415. switch token := t.nextNonSpace(); token.typ {
  416. case itemText:
  417. return t.newText(token.pos, token.val)
  418. case itemLeftDelim:
  419. return t.action()
  420. default:
  421. t.unexpected(token, "input", "text or action")
  422. }
  423. return nil
  424. }
  425. func (t *Template) action() (n Node) {
  426. switch token := t.nextNonSpace(); token.typ {
  427. case itemInclude:
  428. return t.parseInclude()
  429. case itemBlock:
  430. return t.parseBlock()
  431. case itemEnd:
  432. return t.endControl()
  433. case itemYield:
  434. return t.parseYield()
  435. case itemContent:
  436. return t.contentControl()
  437. case itemIf:
  438. return t.ifControl()
  439. case itemElse:
  440. return t.elseControl()
  441. case itemRange:
  442. return t.rangeControl()
  443. case itemTry:
  444. return t.parseTry()
  445. case itemCatch:
  446. return t.parseCatch()
  447. case itemReturn:
  448. return t.parseReturn()
  449. }
  450. t.backup()
  451. action := t.newAction(t.peek().pos, t.lex.lineNumber())
  452. expr := t.assignmentOrExpression("command")
  453. if expr.Type() == NodeSet {
  454. action.Set = expr.(*SetNode)
  455. expr = nil
  456. if t.expectOneOf(itemSemicolon, itemRightDelim, "command", "semicolon or right delimiter").typ == itemSemicolon {
  457. expr = t.expression("command", "pipeline base expression")
  458. }
  459. }
  460. if expr != nil {
  461. action.Pipe = t.pipeline("command", expr)
  462. }
  463. return action
  464. }
  465. func (t *Template) logicalExpression(context string) (Expression, item) {
  466. left, endtoken := t.comparativeExpression(context)
  467. for endtoken.typ == itemAnd || endtoken.typ == itemOr {
  468. right, rightendtoken := t.comparativeExpression(context)
  469. left, endtoken = t.newLogicalExpr(left.Position(), t.lex.lineNumber(), left, right, endtoken), rightendtoken
  470. }
  471. return left, endtoken
  472. }
  473. func (t *Template) parseExpression(context string) (Expression, item) {
  474. expression, endtoken := t.logicalExpression(context)
  475. if endtoken.typ == itemTernary {
  476. var left, right Expression
  477. left, endtoken = t.parseExpression(context)
  478. if endtoken.typ != itemColon {
  479. t.unexpected(endtoken, "ternary expression", "colon in ternary expression")
  480. }
  481. right, endtoken = t.parseExpression(context)
  482. expression = t.newTernaryExpr(expression.Position(), t.lex.lineNumber(), expression, left, right)
  483. }
  484. return expression, endtoken
  485. }
  486. func (t *Template) comparativeExpression(context string) (Expression, item) {
  487. left, endtoken := t.numericComparativeExpression(context)
  488. for endtoken.typ == itemEquals || endtoken.typ == itemNotEquals {
  489. right, rightendtoken := t.numericComparativeExpression(context)
  490. left, endtoken = t.newComparativeExpr(left.Position(), t.lex.lineNumber(), left, right, endtoken), rightendtoken
  491. }
  492. return left, endtoken
  493. }
  494. func (t *Template) numericComparativeExpression(context string) (Expression, item) {
  495. left, endtoken := t.additiveExpression(context)
  496. for endtoken.typ >= itemGreat && endtoken.typ <= itemLessEquals {
  497. right, rightendtoken := t.additiveExpression(context)
  498. left, endtoken = t.newNumericComparativeExpr(left.Position(), t.lex.lineNumber(), left, right, endtoken), rightendtoken
  499. }
  500. return left, endtoken
  501. }
  502. func (t *Template) additiveExpression(context string) (Expression, item) {
  503. left, endtoken := t.multiplicativeExpression(context)
  504. for endtoken.typ == itemAdd || endtoken.typ == itemMinus {
  505. right, rightendtoken := t.multiplicativeExpression(context)
  506. left, endtoken = t.newAdditiveExpr(left.Position(), t.lex.lineNumber(), left, right, endtoken), rightendtoken
  507. }
  508. return left, endtoken
  509. }
  510. func (t *Template) multiplicativeExpression(context string) (left Expression, endtoken item) {
  511. left, endtoken = t.unaryExpression(context)
  512. for endtoken.typ >= itemMul && endtoken.typ <= itemMod {
  513. right, rightendtoken := t.unaryExpression(context)
  514. left, endtoken = t.newMultiplicativeExpr(left.Position(), t.lex.lineNumber(), left, right, endtoken), rightendtoken
  515. }
  516. return left, endtoken
  517. }
  518. func (t *Template) unaryExpression(context string) (Expression, item) {
  519. next := t.nextNonSpace()
  520. switch next.typ {
  521. case itemNot:
  522. expr, endToken := t.comparativeExpression(context)
  523. return t.newNotExpr(expr.Position(), t.lex.lineNumber(), expr), endToken
  524. case itemMinus, itemAdd:
  525. return t.newAdditiveExpr(next.pos, t.lex.lineNumber(), nil, t.operand("additive expression"), next), t.nextNonSpace()
  526. default:
  527. t.backup()
  528. }
  529. operand := t.operand(context)
  530. return operand, t.nextNonSpace()
  531. }
  532. func (t *Template) assignmentOrExpression(context string) (operand Expression) {
  533. t.peekNonSpace()
  534. line := t.lex.lineNumber()
  535. var right, left []Expression
  536. var isSet bool
  537. var isLet bool
  538. var returned item
  539. operand, returned = t.parseExpression(context)
  540. pos := operand.Position()
  541. if returned.typ == itemComma || returned.typ == itemAssign {
  542. isSet = true
  543. } else {
  544. if operand == nil {
  545. t.unexpected(returned, context, "operand")
  546. }
  547. t.backup()
  548. return operand
  549. }
  550. if isSet {
  551. leftloop:
  552. for {
  553. switch operand.Type() {
  554. case NodeField, NodeChain, NodeIdentifier:
  555. left = append(left, operand)
  556. default:
  557. t.errorf("unexpected node in assign")
  558. }
  559. switch returned.typ {
  560. case itemComma:
  561. operand, returned = t.parseExpression(context)
  562. case itemAssign:
  563. isLet = returned.val == ":="
  564. break leftloop
  565. default:
  566. t.unexpected(returned, "assignment", "comma or assignment")
  567. }
  568. }
  569. if isLet {
  570. for _, operand := range left {
  571. if operand.Type() != NodeIdentifier {
  572. t.errorf("unexpected node type %s in variable declaration", operand)
  573. }
  574. }
  575. }
  576. for {
  577. operand, returned = t.parseExpression("assignment")
  578. right = append(right, operand)
  579. if returned.typ != itemComma {
  580. t.backup()
  581. break
  582. }
  583. }
  584. var isIndexExprGetLookup bool
  585. if context == "range" {
  586. if len(left) > 2 || len(right) > 1 {
  587. t.errorf("unexpected number of operands in assign on range")
  588. }
  589. } else {
  590. if len(left) != len(right) {
  591. if len(left) == 2 && len(right) == 1 && right[0].Type() == NodeIndexExpr {
  592. isIndexExprGetLookup = true
  593. } else {
  594. t.errorf("unexpected number of operands in assign on range")
  595. }
  596. }
  597. }
  598. operand = t.newSet(pos, line, isLet, isIndexExprGetLookup, left, right)
  599. return
  600. }
  601. return
  602. }
  603. func (t *Template) expression(context, as string) Expression {
  604. expr, tk := t.parseExpression(context)
  605. if expr == nil {
  606. t.unexpected(tk, context, as)
  607. }
  608. t.backup()
  609. return expr
  610. }
  611. func (t *Template) pipeline(context string, baseExprMutate Expression) (pipe *PipeNode) {
  612. pos := t.peekNonSpace().pos
  613. pipe = t.newPipeline(pos, t.lex.lineNumber())
  614. if baseExprMutate == nil {
  615. pipe.errorf("parsing pipeline: first expression cannot be nil")
  616. }
  617. pipe.append(t.command(baseExprMutate))
  618. for {
  619. token := t.expectOneOf(itemPipe, itemRightDelim, "pipeline", "pipe or right delimiter")
  620. if token.typ == itemRightDelim {
  621. break
  622. }
  623. token = t.nextNonSpace()
  624. switch token.typ {
  625. case itemField, itemIdentifier:
  626. t.backup()
  627. pipe.append(t.command(nil))
  628. default:
  629. t.unexpected(token, "pipeline", "field or identifier")
  630. }
  631. }
  632. return
  633. }
  634. func (t *Template) command(baseExpr Expression) *CommandNode {
  635. cmd := t.newCommand(t.peekNonSpace().pos)
  636. if baseExpr == nil {
  637. baseExpr = t.expression("command", "name")
  638. }
  639. if baseExpr.Type() == NodeCallExpr {
  640. call := baseExpr.(*CallExprNode)
  641. cmd.BaseExpr = call.BaseExpr
  642. cmd.Args = call.Args
  643. return cmd
  644. }
  645. cmd.BaseExpr = baseExpr
  646. next := t.nextNonSpace()
  647. switch next.typ {
  648. case itemColon:
  649. cmd.Args = t.parseArguments()
  650. default:
  651. t.backup()
  652. }
  653. if cmd.BaseExpr == nil {
  654. t.errorf("empty command")
  655. }
  656. return cmd
  657. }
  658. // operand:
  659. // term .Field*
  660. // An operand is a space-separated component of a command,
  661. // a term possibly followed by field accesses.
  662. // A nil return means the next item is not an operand.
  663. func (t *Template) operand(context string) Expression {
  664. node := t.term()
  665. if node == nil {
  666. t.unexpected(t.next(), context, "term")
  667. }
  668. RESET:
  669. if t.peek().typ == itemField {
  670. chain := t.newChain(t.peek().pos, node)
  671. for t.peekNonSpace().typ == itemField {
  672. chain.Add(t.next().val)
  673. }
  674. // Compatibility with original API: If the term is of type NodeField
  675. // or NodeVariable, just put more fields on the original.
  676. // Otherwise, keep the Chain node.
  677. // Obvious parsing errors involving literal values are detected here.
  678. // More complex error cases will have to be handled at execution time.
  679. switch node.Type() {
  680. case NodeField:
  681. node = t.newField(chain.Position(), chain.String())
  682. case NodeBool, NodeString, NodeNumber, NodeNil:
  683. t.errorf("unexpected . after term %q", node.String())
  684. default:
  685. node = chain
  686. }
  687. }
  688. nodeTYPE := node.Type()
  689. if nodeTYPE == NodeIdentifier ||
  690. nodeTYPE == NodeCallExpr ||
  691. nodeTYPE == NodeField ||
  692. nodeTYPE == NodeChain ||
  693. nodeTYPE == NodeIndexExpr {
  694. switch t.nextNonSpace().typ {
  695. case itemLeftParen:
  696. callExpr := t.newCallExpr(node.Position(), t.lex.lineNumber(), node)
  697. callExpr.Args = t.parseArguments()
  698. t.expect(itemRightParen, "call expression", "closing parenthesis")
  699. node = callExpr
  700. goto RESET
  701. case itemLeftBrackets:
  702. base := node
  703. var index Expression
  704. var next item
  705. //found colon is slice expression
  706. if t.peekNonSpace().typ != itemColon {
  707. index, next = t.parseExpression("index|slice expression")
  708. } else {
  709. next = t.nextNonSpace()
  710. }
  711. switch next.typ {
  712. case itemColon:
  713. var endIndex Expression
  714. if t.peekNonSpace().typ != itemRightBrackets {
  715. endIndex = t.expression("slice expression", "end indexß")
  716. }
  717. node = t.newSliceExpr(node.Position(), node.line(), base, index, endIndex)
  718. case itemRightBrackets:
  719. node = t.newIndexExpr(node.Position(), node.line(), base, index)
  720. fallthrough
  721. default:
  722. t.backup()
  723. }
  724. t.expect(itemRightBrackets, "index expression", "closing bracket")
  725. goto RESET
  726. default:
  727. t.backup()
  728. }
  729. }
  730. return node
  731. }
  732. func (t *Template) parseArguments() []Expression {
  733. args := []Expression{}
  734. context := "call expression argument list"
  735. loop:
  736. for t.peekNonSpace().typ != itemRightParen {
  737. expr, endtoken := t.parseExpression(context)
  738. args = append(args, expr)
  739. switch endtoken.typ {
  740. case itemComma:
  741. // continue with closing parens (allowed because of multiline syntax) or next arg
  742. default:
  743. t.backup()
  744. break loop
  745. }
  746. }
  747. return args
  748. }
  749. func (t *Template) parseControl(allowElseIf bool, context string) (pos Pos, line int, set *SetNode, expression Expression, list, elseList *ListNode) {
  750. line = t.lex.lineNumber()
  751. expression = t.assignmentOrExpression(context)
  752. pos = expression.Position()
  753. if expression.Type() == NodeSet {
  754. set = expression.(*SetNode)
  755. if context != "range" {
  756. t.expect(itemSemicolon, context, "semicolon between assignment and expression")
  757. expression = t.expression(context, "expression after assignment")
  758. } else {
  759. expression = nil
  760. }
  761. }
  762. t.expectRightDelim(context)
  763. var next Node
  764. list, next = t.itemList(nodeElse, nodeEnd)
  765. if next.Type() == nodeElse {
  766. if allowElseIf && t.peek().typ == itemIf {
  767. // Special case for "else if". If the "else" is followed immediately by an "if",
  768. // the elseControl will have left the "if" token pending. Treat
  769. // {{if a}}_{{else if b}}_{{end}}
  770. // as
  771. // {{if a}}_{{else}}{{if b}}_{{end}}{{end}}.
  772. // To do this, parse the if as usual and stop at it {{end}}; the subsequent{{end}}
  773. // is assumed. This technique works even for long if-else-if chains.
  774. t.next() // Consume the "if" token.
  775. elseList = t.newList(next.Position())
  776. elseList.append(t.ifControl())
  777. // Do not consume the next item - only one {{end}} required.
  778. } else {
  779. elseList, next = t.itemList(nodeEnd)
  780. }
  781. }
  782. return pos, line, set, expression, list, elseList
  783. }
  784. // If:
  785. // {{if expression}} itemList {{end}}
  786. // {{if expression}} itemList {{else}} itemList {{end}}
  787. // If keyword is past.
  788. func (t *Template) ifControl() Node {
  789. return t.newIf(t.parseControl(true, "if"))
  790. }
  791. // Range:
  792. // {{range expression}} itemList {{end}}
  793. // {{range expression}} itemList {{else}} itemList {{end}}
  794. // Range keyword is past.
  795. func (t *Template) rangeControl() Node {
  796. return t.newRange(t.parseControl(false, "range"))
  797. }
  798. // End:
  799. // {{end}}
  800. // End keyword is past.
  801. func (t *Template) endControl() Node {
  802. return t.newEnd(t.expectRightDelim("end").pos)
  803. }
  804. // Content:
  805. // {{content}}
  806. // Content keyword is past.
  807. func (t *Template) contentControl() Node {
  808. return t.newContent(t.expectRightDelim("content").pos)
  809. }
  810. // Else:
  811. // {{else}}
  812. // Else keyword is past.
  813. func (t *Template) elseControl() Node {
  814. // Special case for "else if".
  815. peek := t.peekNonSpace()
  816. if peek.typ == itemIf {
  817. // We see "{{else if ... " but in effect rewrite it to {{else}}{{if ... ".
  818. return t.newElse(peek.pos, t.lex.lineNumber())
  819. }
  820. return t.newElse(t.expectRightDelim("else").pos, t.lex.lineNumber())
  821. }
  822. // Try-catch:
  823. // {{try}}
  824. // itemList
  825. // {{catch <ident>}}
  826. // itemList
  827. // {{end}}
  828. // try keyword is past.
  829. func (t *Template) parseTry() *TryNode {
  830. var recov *catchNode
  831. line := t.lex.lineNumber()
  832. pos := t.expectRightDelim("try").pos
  833. list, next := t.itemList(nodeCatch, nodeEnd)
  834. if next.Type() == nodeCatch {
  835. recov = next.(*catchNode)
  836. }
  837. return t.newTry(pos, line, list, recov)
  838. }
  839. // catch:
  840. // {{catch <ident>}}
  841. // itemList
  842. // {{end}}
  843. // catch keyword is past.
  844. func (t *Template) parseCatch() *catchNode {
  845. line := t.lex.lineNumber()
  846. var errVar *IdentifierNode
  847. peek := t.peekNonSpace()
  848. if peek.typ != itemRightDelim {
  849. _errVar := t.term()
  850. if typ := _errVar.Type(); typ != NodeIdentifier {
  851. t.errorf("unexpected node type '%s' in catch", typ)
  852. }
  853. errVar = _errVar.(*IdentifierNode)
  854. }
  855. t.expectRightDelim("catch")
  856. list, _ := t.itemList(nodeEnd)
  857. return t.newCatch(peek.pos, line, errVar, list)
  858. }
  859. // term:
  860. // literal (number, string, nil, boolean)
  861. // function (identifier)
  862. // .
  863. // .Field
  864. // variable
  865. // '(' expression ')'
  866. // A term is a simple "expression".
  867. // A nil return means the next item is not a term.
  868. func (t *Template) term() Node {
  869. switch token := t.nextNonSpace(); token.typ {
  870. case itemError:
  871. t.errorf("%s", token.val)
  872. case itemIdentifier:
  873. return t.newIdentifier(token.val, token.pos, t.lex.lineNumber())
  874. case itemNil:
  875. return t.newNil(token.pos)
  876. case itemField:
  877. return t.newField(token.pos, token.val)
  878. case itemBool:
  879. return t.newBool(token.pos, token.val == "true")
  880. case itemCharConstant, itemComplex, itemNumber:
  881. number, err := t.newNumber(token.pos, token.val, token.typ)
  882. if err != nil {
  883. t.error(err)
  884. }
  885. return number
  886. case itemLeftParen:
  887. pipe := t.expression("parenthesized expression", "expression")
  888. if token := t.next(); token.typ != itemRightParen {
  889. t.unexpected(token, "parenthesized expression", "closing parenthesis")
  890. }
  891. return pipe
  892. case itemString, itemRawString:
  893. s, err := unquote(token.val)
  894. if err != nil {
  895. t.error(err)
  896. }
  897. return t.newString(token.pos, token.val, s)
  898. }
  899. t.backup()
  900. return nil
  901. }