parse.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987
  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(expected itemType, context string) item {
  110. token := t.nextNonSpace()
  111. if token.typ != expected {
  112. t.unexpected(token, context)
  113. }
  114. return token
  115. }
  116. // expectOneOf consumes the next token and guarantees it has one of the required types.
  117. func (t *Template) expectOneOf(expected1, expected2 itemType, context string) item {
  118. token := t.nextNonSpace()
  119. if token.typ != expected1 && token.typ != expected2 {
  120. t.unexpected(token, context)
  121. }
  122. return token
  123. }
  124. // unexpected complains about the token and terminates processing.
  125. func (t *Template) unexpected(token item, context string) {
  126. t.errorf("unexpected %s in %s", token, context)
  127. }
  128. // recover is the handler that turns panics into returns from the top level of Parse.
  129. func (t *Template) recover(errp *error) {
  130. e := recover()
  131. if e != nil {
  132. if _, ok := e.(runtime.Error); ok {
  133. panic(e)
  134. }
  135. if t != nil {
  136. t.lex.drain()
  137. t.stopParse()
  138. }
  139. *errp = e.(error)
  140. }
  141. return
  142. }
  143. func (s *Set) parse(name, text string) (t *Template, err error) {
  144. t = &Template{Name: name, text: text, set: s, passedBlocks: make(map[string]*BlockNode)}
  145. defer t.recover(&err)
  146. t.ParseName = t.Name
  147. t.startParse(lex(t.Name, text))
  148. t.parseTemplate()
  149. t.stopParse()
  150. if t.extends != nil {
  151. t.addBlocks(t.extends.processedBlocks)
  152. }
  153. for _, _import := range t.imports {
  154. t.addBlocks(_import.processedBlocks)
  155. }
  156. t.addBlocks(t.passedBlocks)
  157. return t, err
  158. }
  159. func (t *Template) expectString(context string) string {
  160. token := t.expectOneOf(itemString, itemRawString, context)
  161. s, err := unquote(token.val)
  162. if err != nil {
  163. t.error(err)
  164. }
  165. return s
  166. }
  167. // parse is the top-level parser for a template, essentially the same
  168. // It runs to EOF.
  169. func (t *Template) parseTemplate() (next Node) {
  170. t.Root = t.newList(t.peek().pos)
  171. // {{ extends|import stringLiteral }}
  172. for t.peek().typ != itemEOF {
  173. delim := t.next()
  174. if delim.typ == itemText && strings.TrimSpace(delim.val) == "" {
  175. continue //skips empty text nodes
  176. }
  177. if delim.typ == itemLeftDelim {
  178. token := t.nextNonSpace()
  179. if token.typ == itemExtends || token.typ == itemImport {
  180. s := t.expectString("extends|import")
  181. if token.typ == itemExtends {
  182. if t.extends != nil {
  183. t.errorf("Unexpected extends clause, only one extends clause is valid per template")
  184. } else if len(t.imports) > 0 {
  185. t.errorf("Unexpected extends clause, all import clause should come after extends clause")
  186. }
  187. var err error
  188. t.extends, err = t.set.getTemplateWhileParsing(t.Name, s)
  189. if err != nil {
  190. t.error(err)
  191. }
  192. } else {
  193. tt, err := t.set.getTemplateWhileParsing(t.Name, s)
  194. if err != nil {
  195. t.error(err)
  196. }
  197. t.imports = append(t.imports, tt)
  198. }
  199. t.expect(itemRightDelim, "extends|import")
  200. } else {
  201. t.backup2(delim)
  202. break
  203. }
  204. } else {
  205. t.backup()
  206. break
  207. }
  208. }
  209. for t.peek().typ != itemEOF {
  210. switch n := t.textOrAction(); n.Type() {
  211. case nodeEnd, nodeElse, nodeContent:
  212. t.errorf("unexpected %s", n)
  213. default:
  214. t.Root.append(n)
  215. }
  216. }
  217. return nil
  218. }
  219. // startParse initializes the parser, using the lexer.
  220. func (t *Template) startParse(lex *lexer) {
  221. t.Root = nil
  222. t.lex = lex
  223. }
  224. // stopParse terminates parsing.
  225. func (t *Template) stopParse() {
  226. t.lex = nil
  227. }
  228. // IsEmptyTree reports whether this tree (node) is empty of everything but space.
  229. func IsEmptyTree(n Node) bool {
  230. switch n := n.(type) {
  231. case nil:
  232. return true
  233. case *ActionNode:
  234. case *IfNode:
  235. case *ListNode:
  236. for _, node := range n.Nodes {
  237. if !IsEmptyTree(node) {
  238. return false
  239. }
  240. }
  241. return true
  242. case *RangeNode:
  243. case *IncludeNode:
  244. case *TextNode:
  245. return len(bytes.TrimSpace(n.Text)) == 0
  246. case *BlockNode:
  247. case *YieldNode:
  248. default:
  249. panic("unknown node: " + n.String())
  250. }
  251. return false
  252. }
  253. func (t *Template) blockParametersList(isDeclaring bool, context string) *BlockParameterList {
  254. block := &BlockParameterList{}
  255. t.expect(itemLeftParen, context)
  256. for {
  257. var expression Expression
  258. next := t.nextNonSpace()
  259. if next.typ == itemIdentifier {
  260. identifier := next.val
  261. next2 := t.nextNonSpace()
  262. switch next2.typ {
  263. case itemComma, itemRightParen:
  264. block.List = append(block.List, BlockParameter{Identifier: identifier})
  265. next = next2
  266. case itemAssign:
  267. expression, next = t.parseExpression(context)
  268. block.List = append(block.List, BlockParameter{Identifier: identifier, Expression: expression})
  269. default:
  270. if !isDeclaring {
  271. switch next2.typ {
  272. case itemComma, itemRightParen:
  273. default:
  274. t.backup2(next)
  275. expression, next = t.parseExpression(context)
  276. block.List = append(block.List, BlockParameter{Expression: expression})
  277. }
  278. } else {
  279. t.unexpected(next2, context)
  280. }
  281. }
  282. } else if !isDeclaring {
  283. switch next.typ {
  284. case itemComma, itemRightParen:
  285. default:
  286. t.backup()
  287. expression, next = t.parseExpression(context)
  288. block.List = append(block.List, BlockParameter{Expression: expression})
  289. }
  290. }
  291. if next.typ != itemComma {
  292. t.backup()
  293. break
  294. }
  295. }
  296. t.expect(itemRightParen, context)
  297. return block
  298. }
  299. func (t *Template) parseBlock() Node {
  300. const context = "block clause"
  301. var pipe Expression
  302. name := t.expect(itemIdentifier, context)
  303. bplist := t.blockParametersList(true, context)
  304. if t.peekNonSpace().typ != itemRightDelim {
  305. pipe = t.expression(context)
  306. }
  307. t.expect(itemRightDelim, context)
  308. list, end := t.itemList()
  309. var contentList *ListNode
  310. if end.Type() == nodeContent {
  311. contentList, end = t.itemList()
  312. if end.Type() != nodeEnd {
  313. t.errorf("unexpected %s in %s", end, context)
  314. }
  315. } else if end.Type() != nodeEnd {
  316. t.errorf("unexpected %s in %s", end, context)
  317. }
  318. block := t.newBlock(name.pos, t.lex.lineNumber(), name.val, bplist, pipe, list, contentList)
  319. t.passedBlocks[block.Name] = block
  320. return block
  321. }
  322. func (t *Template) parseYield() Node {
  323. const context = "yield clause"
  324. var (
  325. pipe Expression
  326. name item
  327. bplist *BlockParameterList
  328. content *ListNode
  329. end Node
  330. )
  331. // content yield {{yield content}}
  332. name = t.nextNonSpace()
  333. if name.typ == itemContent {
  334. if t.peekNonSpace().typ != itemRightDelim {
  335. pipe = t.expression(context)
  336. }
  337. t.expect(itemRightDelim, context)
  338. return t.newYield(name.pos, t.lex.lineNumber(), "", nil, pipe, nil, true)
  339. } else if name.typ != itemIdentifier {
  340. t.unexpected(name, context)
  341. }
  342. bplist = t.blockParametersList(false, context)
  343. typ := t.peekNonSpace().typ
  344. if typ != itemRightDelim {
  345. if typ == itemContent {
  346. t.nextNonSpace()
  347. t.expect(itemRightDelim, context)
  348. content, end = t.itemList()
  349. if end.Type() != nodeEnd {
  350. t.errorf("unexpected %s in %s", end, context)
  351. }
  352. } else {
  353. pipe = t.expression("yield")
  354. if t.peekNonSpace().typ == itemContent {
  355. t.nextNonSpace()
  356. t.expect(itemRightDelim, context)
  357. content, end = t.itemList()
  358. if end.Type() != nodeEnd {
  359. t.errorf("unexpected %s in %s", end, context)
  360. }
  361. } else {
  362. t.expect(itemRightDelim, context)
  363. }
  364. }
  365. } else {
  366. t.expect(itemRightDelim, context)
  367. }
  368. return t.newYield(name.pos, t.lex.lineNumber(), name.val, bplist, pipe, content, false)
  369. }
  370. func (t *Template) parseInclude() Node {
  371. var pipe Expression
  372. name := t.expression("include")
  373. if t.nextNonSpace().typ != itemRightDelim {
  374. t.backup()
  375. pipe = t.expression("include")
  376. t.expect(itemRightDelim, "include invocation")
  377. }
  378. return t.newInclude(name.Position(), t.lex.lineNumber(), name, pipe)
  379. }
  380. // itemListBlock:
  381. // textOrAction*
  382. // Terminates at {{end}} or {{else}}, returned separately.
  383. func (t *Template) itemListBlock() (list *ListNode, next Node) {
  384. list = t.newList(t.peekNonSpace().pos)
  385. for t.peekNonSpace().typ != itemEOF {
  386. n := t.textOrAction()
  387. switch n.Type() {
  388. case nodeEnd, nodeContent:
  389. return list, n
  390. }
  391. list.append(n)
  392. }
  393. t.errorf("unexpected EOF")
  394. return
  395. }
  396. // itemListControl:
  397. // textOrAction*
  398. // Terminates at {{end}}, returned separately.
  399. func (t *Template) itemList() (list *ListNode, next Node) {
  400. list = t.newList(t.peekNonSpace().pos)
  401. for t.peekNonSpace().typ != itemEOF {
  402. n := t.textOrAction()
  403. switch n.Type() {
  404. case nodeEnd, nodeElse, nodeContent:
  405. return list, n
  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")
  422. }
  423. return nil
  424. }
  425. func (t *Template) action() (n Node) {
  426. switch token := t.nextNonSpace(); token.typ {
  427. case itemElse:
  428. return t.elseControl()
  429. case itemEnd:
  430. return t.endControl()
  431. case itemContent:
  432. return t.contentControl()
  433. case itemIf:
  434. return t.ifControl()
  435. case itemRange:
  436. return t.rangeControl()
  437. case itemBlock:
  438. return t.parseBlock()
  439. case itemInclude:
  440. return t.parseInclude()
  441. case itemYield:
  442. return t.parseYield()
  443. }
  444. t.backup()
  445. action := t.newAction(t.peek().pos, t.lex.lineNumber())
  446. expr := t.assignmentOrExpression("command")
  447. if expr.Type() == NodeSet {
  448. action.Set = expr.(*SetNode)
  449. expr = nil
  450. }
  451. if action.Set == nil || t.expectOneOf(itemColonComma, itemRightDelim, "command").typ == itemColonComma {
  452. action.Pipe = t.pipeline("command", expr)
  453. }
  454. return action
  455. }
  456. func (t *Template) logicalExpression(context string) (Expression, item) {
  457. left, endtoken := t.comparativeExpression(context)
  458. for endtoken.typ == itemAnd || endtoken.typ == itemOr {
  459. right, rightendtoken := t.comparativeExpression(context)
  460. left, endtoken = t.newLogicalExpr(left.Position(), t.lex.lineNumber(), left, right, endtoken), rightendtoken
  461. }
  462. return left, endtoken
  463. }
  464. func (t *Template) parseExpression(context string) (Expression, item) {
  465. expression, endtoken := t.logicalExpression(context)
  466. if endtoken.typ == itemTernary {
  467. var left, right Expression
  468. left, endtoken = t.parseExpression(context)
  469. if endtoken.typ != itemColon {
  470. t.unexpected(endtoken, "ternary expression")
  471. }
  472. right, endtoken = t.parseExpression(context)
  473. expression = t.newTernaryExpr(expression.Position(), t.lex.lineNumber(), expression, left, right)
  474. }
  475. return expression, endtoken
  476. }
  477. func (t *Template) comparativeExpression(context string) (Expression, item) {
  478. left, endtoken := t.numericComparativeExpression(context)
  479. for endtoken.typ == itemEquals || endtoken.typ == itemNotEquals {
  480. right, rightendtoken := t.numericComparativeExpression(context)
  481. left, endtoken = t.newComparativeExpr(left.Position(), t.lex.lineNumber(), left, right, endtoken), rightendtoken
  482. }
  483. return left, endtoken
  484. }
  485. func (t *Template) numericComparativeExpression(context string) (Expression, item) {
  486. left, endtoken := t.additiveExpression(context)
  487. for endtoken.typ >= itemGreat && endtoken.typ <= itemLessEquals {
  488. right, rightendtoken := t.additiveExpression(context)
  489. left, endtoken = t.newNumericComparativeExpr(left.Position(), t.lex.lineNumber(), left, right, endtoken), rightendtoken
  490. }
  491. return left, endtoken
  492. }
  493. func (t *Template) additiveExpression(context string) (Expression, item) {
  494. left, endtoken := t.multiplicativeExpression(context)
  495. for endtoken.typ == itemAdd || endtoken.typ == itemMinus {
  496. right, rightendtoken := t.multiplicativeExpression(context)
  497. left, endtoken = t.newAdditiveExpr(left.Position(), t.lex.lineNumber(), left, right, endtoken), rightendtoken
  498. }
  499. return left, endtoken
  500. }
  501. func (t *Template) multiplicativeExpression(context string) (left Expression, endtoken item) {
  502. left, endtoken = t.unaryExpression(context)
  503. for endtoken.typ >= itemMul && endtoken.typ <= itemMod {
  504. right, rightendtoken := t.unaryExpression(context)
  505. left, endtoken = t.newMultiplicativeExpr(left.Position(), t.lex.lineNumber(), left, right, endtoken), rightendtoken
  506. }
  507. return left, endtoken
  508. }
  509. func (t *Template) unaryExpression(context string) (Expression, item) {
  510. next := t.nextNonSpace()
  511. switch next.typ {
  512. case itemNot:
  513. expr, endToken := t.comparativeExpression(context)
  514. return t.newNotExpr(expr.Position(), t.lex.lineNumber(), expr), endToken
  515. case itemMinus, itemAdd:
  516. return t.newAdditiveExpr(next.pos, t.lex.lineNumber(), nil, t.operand(), next), t.nextNonSpace()
  517. default:
  518. t.backup()
  519. }
  520. operand := t.operand()
  521. return operand, t.nextNonSpace()
  522. }
  523. func (t *Template) assignmentOrExpression(context string) (operand Expression) {
  524. t.peekNonSpace()
  525. line := t.lex.lineNumber()
  526. var right, left []Expression
  527. var isSet bool
  528. var isLet bool
  529. var returned item
  530. operand, returned = t.parseExpression(context)
  531. pos := operand.Position()
  532. if returned.typ == itemComma || returned.typ == itemAssign {
  533. isSet = true
  534. } else {
  535. if operand == nil {
  536. t.unexpected(returned, context)
  537. }
  538. t.backup()
  539. return operand
  540. }
  541. if isSet {
  542. leftloop:
  543. for {
  544. switch operand.Type() {
  545. case NodeField, NodeChain, NodeIdentifier:
  546. left = append(left, operand)
  547. default:
  548. t.errorf("unexpected node in assign")
  549. }
  550. switch returned.typ {
  551. case itemComma:
  552. operand, returned = t.parseExpression(context)
  553. case itemAssign:
  554. isLet = returned.val == ":="
  555. break leftloop
  556. default:
  557. t.unexpected(returned, "assignment")
  558. }
  559. }
  560. if isLet {
  561. for _, operand := range left {
  562. if operand.Type() != NodeIdentifier {
  563. t.errorf("unexpected node type %s in variable declaration", operand)
  564. }
  565. }
  566. }
  567. for {
  568. operand, returned = t.parseExpression("assignment")
  569. right = append(right, operand)
  570. if returned.typ != itemComma {
  571. t.backup()
  572. break
  573. }
  574. }
  575. var isIndexExprGetLookup bool
  576. if context == "range" {
  577. if len(left) > 2 || len(right) > 1 {
  578. t.errorf("unexpected number of operands in assign on range")
  579. }
  580. } else {
  581. if len(left) != len(right) {
  582. if len(left) == 2 && len(right) == 1 && right[0].Type() == NodeIndexExpr {
  583. isIndexExprGetLookup = true
  584. } else {
  585. t.errorf("unexpected number of operands in assign on range")
  586. }
  587. }
  588. }
  589. operand = t.newSet(pos, line, isLet, isIndexExprGetLookup, left, right)
  590. return
  591. }
  592. return
  593. }
  594. func (t *Template) expression(context string) Expression {
  595. expr, tk := t.parseExpression(context)
  596. if expr == nil {
  597. t.unexpected(tk, context)
  598. }
  599. t.backup()
  600. return expr
  601. }
  602. func (t *Template) pipeline(context string, baseExprMutate Expression) (pipe *PipeNode) {
  603. pos := t.peekNonSpace().pos
  604. pipe = t.newPipeline(pos, t.lex.lineNumber())
  605. var token item
  606. if baseExprMutate != nil {
  607. //special case
  608. pipe.append(t.command(baseExprMutate))
  609. token = t.nextNonSpace()
  610. if token.typ == itemPipe {
  611. token = t.nextNonSpace()
  612. } else {
  613. t.backup()
  614. t.expect(itemRightDelim, context)
  615. return
  616. }
  617. } else {
  618. token = t.nextNonSpace()
  619. }
  620. loop:
  621. for {
  622. switch token.typ {
  623. case itemBool, itemCharConstant, itemComplex, itemField, itemIdentifier,
  624. itemNumber, itemNil, itemRawString, itemString, itemLeftParen, itemNot:
  625. t.backup()
  626. pipe.append(t.command(nil))
  627. token = t.nextNonSpace()
  628. if token.typ == itemPipe {
  629. token = t.nextNonSpace()
  630. continue loop
  631. } else {
  632. t.backup()
  633. break loop
  634. }
  635. default:
  636. t.backup()
  637. break loop
  638. }
  639. }
  640. t.expect(itemRightDelim, context)
  641. return
  642. }
  643. func (t *Template) command(baseExpr Expression) *CommandNode {
  644. cmd := t.newCommand(t.peekNonSpace().pos)
  645. if baseExpr == nil {
  646. cmd.BaseExpr = t.expression("command")
  647. } else {
  648. cmd.BaseExpr = baseExpr
  649. }
  650. if t.nextNonSpace().typ == itemColon {
  651. cmd.Call = true
  652. cmd.Args = t.parseArguments()
  653. } else {
  654. t.backup()
  655. }
  656. if cmd.BaseExpr == nil {
  657. t.errorf("empty command")
  658. }
  659. return cmd
  660. }
  661. // operand:
  662. // term .Field*
  663. // An operand is a space-separated component of a command,
  664. // a term possibly followed by field accesses.
  665. // A nil return means the next item is not an operand.
  666. func (t *Template) operand() Expression {
  667. node := t.term()
  668. if node == nil {
  669. t.errorf("unexpected token %s on operand", t.next())
  670. }
  671. RESET:
  672. if t.peek().typ == itemField {
  673. chain := t.newChain(t.peek().pos, node)
  674. for t.peekNonSpace().typ == itemField {
  675. chain.Add(t.next().val)
  676. }
  677. // Compatibility with original API: If the term is of type NodeField
  678. // or NodeVariable, just put more fields on the original.
  679. // Otherwise, keep the Chain node.
  680. // Obvious parsing errors involving literal values are detected here.
  681. // More complex error cases will have to be handled at execution time.
  682. switch node.Type() {
  683. case NodeField:
  684. node = t.newField(chain.Position(), chain.String())
  685. case NodeBool, NodeString, NodeNumber, NodeNil:
  686. t.errorf("unexpected . after term %q", node.String())
  687. default:
  688. node = chain
  689. }
  690. }
  691. nodeTYPE := node.Type()
  692. if nodeTYPE == NodeIdentifier ||
  693. nodeTYPE == NodeCallExpr ||
  694. nodeTYPE == NodeField ||
  695. nodeTYPE == NodeChain ||
  696. nodeTYPE == NodeIndexExpr {
  697. switch t.nextNonSpace().typ {
  698. case itemLeftParen:
  699. callExpr := t.newCallExpr(node.Position(), t.lex.lineNumber(), node)
  700. callExpr.Args = t.parseArguments()
  701. t.expect(itemRightParen, "call expression")
  702. node = callExpr
  703. goto RESET
  704. case itemLeftBrackets:
  705. base := node
  706. var index Expression
  707. var next item
  708. //found colon is slice expression
  709. if t.peekNonSpace().typ != itemColon {
  710. index, next = t.parseExpression("index|slice expression")
  711. } else {
  712. next = t.nextNonSpace()
  713. }
  714. switch next.typ {
  715. case itemColon:
  716. var lenexpr Expression
  717. if t.peekNonSpace().typ != itemRightBrackets {
  718. lenexpr = t.expression("index expression")
  719. }
  720. node = t.newSliceExpr(node.Position(), node.line(), base, index, lenexpr)
  721. case itemRightBrackets:
  722. node = t.newIndexExpr(node.Position(), node.line(), base, index)
  723. fallthrough
  724. default:
  725. t.backup()
  726. }
  727. t.expect(itemRightBrackets, "index expression")
  728. goto RESET
  729. default:
  730. t.backup()
  731. }
  732. }
  733. return node
  734. }
  735. func (t *Template) parseArguments() (args []Expression) {
  736. if t.peekNonSpace().typ != itemRightParen {
  737. loop:
  738. for {
  739. expr, endtoken := t.parseExpression("call expression")
  740. args = append(args, expr)
  741. switch endtoken.typ {
  742. case itemComma:
  743. continue loop
  744. default:
  745. t.backup()
  746. break loop
  747. }
  748. }
  749. }
  750. return
  751. }
  752. func (t *Template) checkPipeline(pipe *PipeNode, context string) {
  753. // Reject empty pipelines
  754. if len(pipe.Cmds) == 0 {
  755. t.errorf("missing value for %s", context)
  756. }
  757. // Only the first command of a pipeline can start with a non executable operand
  758. for i, c := range pipe.Cmds[1:] {
  759. switch c.Args[0].Type() {
  760. case NodeBool, NodeNil, NodeNumber, NodeString:
  761. // With A|B|C, pipeline stage 2 is B
  762. t.errorf("non executable command in pipeline stage %d", i+2)
  763. }
  764. }
  765. }
  766. func (t *Template) parseControl(allowElseIf bool, context string) (pos Pos, line int, set *SetNode, expression Expression, list, elseList *ListNode) {
  767. line = t.lex.lineNumber()
  768. expression = t.assignmentOrExpression(context)
  769. pos = expression.Position()
  770. if expression.Type() == NodeSet {
  771. set = expression.(*SetNode)
  772. if context != "range" {
  773. t.expect(itemColonComma, context)
  774. expression = t.expression(context)
  775. } else {
  776. expression = nil
  777. }
  778. }
  779. t.expect(itemRightDelim, context)
  780. var next Node
  781. list, next = t.itemList()
  782. switch next.Type() {
  783. case nodeEnd: //done
  784. case nodeElse:
  785. if allowElseIf {
  786. // Special case for "else if". If the "else" is followed immediately by an "if",
  787. // the elseControl will have left the "if" token pending. Treat
  788. // {{if a}}_{{else if b}}_{{end}}
  789. // as
  790. // {{if a}}_{{else}}{{if b}}_{{end}}{{end}}.
  791. // To do this, parse the if as usual and stop at it {{end}}; the subsequent{{end}}
  792. // is assumed. This technique works even for long if-else-if chains.
  793. if t.peek().typ == itemIf {
  794. t.next() // Consume the "if" token.
  795. elseList = t.newList(next.Position())
  796. elseList.append(t.ifControl())
  797. // Do not consume the next item - only one {{end}} required.
  798. break
  799. }
  800. }
  801. elseList, next = t.itemList()
  802. if next.Type() != nodeEnd {
  803. t.errorf("expected end; found %s", next)
  804. }
  805. }
  806. return pos, line, set, expression, list, elseList
  807. }
  808. // If:
  809. // {{if expression}} itemList {{end}}
  810. // {{if expression}} itemList {{else}} itemList {{end}}
  811. // If keyword is past.
  812. func (t *Template) ifControl() Node {
  813. return t.newIf(t.parseControl(true, "if"))
  814. }
  815. // Range:
  816. // {{range expression}} itemList {{end}}
  817. // {{range expression}} itemList {{else}} itemList {{end}}
  818. // Range keyword is past.
  819. func (t *Template) rangeControl() Node {
  820. return t.newRange(t.parseControl(false, "range"))
  821. }
  822. // End:
  823. // {{end}}
  824. // End keyword is past.
  825. func (t *Template) endControl() Node {
  826. return t.newEnd(t.expect(itemRightDelim, "end").pos)
  827. }
  828. // Content:
  829. // {{content}}
  830. // Content keyword is past.
  831. func (t *Template) contentControl() Node {
  832. return t.newContent(t.expect(itemRightDelim, "content").pos)
  833. }
  834. // Else:
  835. // {{else}}
  836. // Else keyword is past.
  837. func (t *Template) elseControl() Node {
  838. // Special case for "else if".
  839. peek := t.peekNonSpace()
  840. if peek.typ == itemIf {
  841. // We see "{{else if ... " but in effect rewrite it to {{else}}{{if ... ".
  842. return t.newElse(peek.pos, t.lex.lineNumber())
  843. }
  844. return t.newElse(t.expect(itemRightDelim, "else").pos, t.lex.lineNumber())
  845. }
  846. // term:
  847. // literal (number, string, nil, boolean)
  848. // function (identifier)
  849. // .
  850. // .Field
  851. // variable
  852. // '(' expression ')'
  853. // A term is a simple "expression".
  854. // A nil return means the next item is not a term.
  855. func (t *Template) term() Node {
  856. switch token := t.nextNonSpace(); token.typ {
  857. case itemError:
  858. t.errorf("%s", token.val)
  859. case itemIdentifier:
  860. return t.newIdentifier(token.val, token.pos, t.lex.lineNumber())
  861. case itemNil:
  862. return t.newNil(token.pos)
  863. case itemField:
  864. return t.newField(token.pos, token.val)
  865. case itemBool:
  866. return t.newBool(token.pos, token.val == "true")
  867. case itemCharConstant, itemComplex, itemNumber:
  868. number, err := t.newNumber(token.pos, token.val, token.typ)
  869. if err != nil {
  870. t.error(err)
  871. }
  872. return number
  873. case itemLeftParen:
  874. pipe := t.expression("parenthesized expression")
  875. if token := t.next(); token.typ != itemRightParen {
  876. t.errorf("unclosed right paren: unexpected %s", token)
  877. }
  878. return pipe
  879. case itemString, itemRawString:
  880. s, err := unquote(token.val)
  881. if err != nil {
  882. t.error(err)
  883. }
  884. return t.newString(token.pos, token.val, s)
  885. }
  886. t.backup()
  887. return nil
  888. }