parser.go 23 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015
  1. /*
  2. * ECAL
  3. *
  4. * Copyright 2020 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the MIT
  7. * License, If a copy of the MIT License was not distributed with this
  8. * file, You can obtain one at https://opensource.org/licenses/MIT.
  9. */
  10. package parser
  11. import (
  12. "fmt"
  13. )
  14. /*
  15. Map of AST nodes corresponding to lexer tokens. The map determines how a given
  16. sequence of lexer tokens are organized into an AST.
  17. */
  18. var astNodeMap map[LexTokenID]*ASTNode
  19. func init() {
  20. astNodeMap = map[LexTokenID]*ASTNode{
  21. TokenEOF: {NodeEOF, nil, nil, nil, nil, 0, ndTerm, nil},
  22. // Value tokens
  23. TokenSTRING: {NodeSTRING, nil, nil, nil, nil, 0, ndTerm, nil},
  24. TokenNUMBER: {NodeNUMBER, nil, nil, nil, nil, 0, ndTerm, nil},
  25. TokenIDENTIFIER: {NodeIDENTIFIER, nil, nil, nil, nil, 0, ndIdentifier, nil},
  26. // Constructed tokens
  27. TokenSTATEMENTS: {NodeSTATEMENTS, nil, nil, nil, nil, 0, nil, nil},
  28. TokenFUNCCALL: {NodeFUNCCALL, nil, nil, nil, nil, 0, nil, nil},
  29. TokenCOMPACCESS: {NodeCOMPACCESS, nil, nil, nil, nil, 0, nil, nil},
  30. TokenLIST: {NodeLIST, nil, nil, nil, nil, 0, nil, nil},
  31. TokenMAP: {NodeMAP, nil, nil, nil, nil, 0, nil, nil},
  32. TokenPARAMS: {NodePARAMS, nil, nil, nil, nil, 0, nil, nil},
  33. TokenGUARD: {NodeGUARD, nil, nil, nil, nil, 0, nil, nil},
  34. // Condition operators
  35. TokenGEQ: {NodeGEQ, nil, nil, nil, nil, 60, nil, ldInfix},
  36. TokenLEQ: {NodeLEQ, nil, nil, nil, nil, 60, nil, ldInfix},
  37. TokenNEQ: {NodeNEQ, nil, nil, nil, nil, 60, nil, ldInfix},
  38. TokenEQ: {NodeEQ, nil, nil, nil, nil, 60, nil, ldInfix},
  39. TokenGT: {NodeGT, nil, nil, nil, nil, 60, nil, ldInfix},
  40. TokenLT: {NodeLT, nil, nil, nil, nil, 60, nil, ldInfix},
  41. // Grouping symbols
  42. TokenLPAREN: {"", nil, nil, nil, nil, 150, ndInner, nil},
  43. TokenRPAREN: {"", nil, nil, nil, nil, 0, nil, nil},
  44. TokenLBRACK: {"", nil, nil, nil, nil, 150, ndList, nil},
  45. TokenRBRACK: {"", nil, nil, nil, nil, 0, nil, nil},
  46. TokenLBRACE: {"", nil, nil, nil, nil, 150, ndMap, nil},
  47. TokenRBRACE: {"", nil, nil, nil, nil, 0, nil, nil},
  48. // Separators
  49. TokenDOT: {"", nil, nil, nil, nil, 0, nil, nil},
  50. TokenCOMMA: {"", nil, nil, nil, nil, 0, nil, nil},
  51. TokenSEMICOLON: {"", nil, nil, nil, nil, 0, nil, nil},
  52. // Grouping
  53. TokenCOLON: {NodeKVP, nil, nil, nil, nil, 60, nil, ldInfix},
  54. TokenEQUAL: {NodePRESET, nil, nil, nil, nil, 60, nil, ldInfix},
  55. // Arithmetic operators
  56. TokenPLUS: {NodePLUS, nil, nil, nil, nil, 110, ndPrefix, ldInfix},
  57. TokenMINUS: {NodeMINUS, nil, nil, nil, nil, 110, ndPrefix, ldInfix},
  58. TokenTIMES: {NodeTIMES, nil, nil, nil, nil, 120, nil, ldInfix},
  59. TokenDIV: {NodeDIV, nil, nil, nil, nil, 120, nil, ldInfix},
  60. TokenDIVINT: {NodeDIVINT, nil, nil, nil, nil, 120, nil, ldInfix},
  61. TokenMODINT: {NodeMODINT, nil, nil, nil, nil, 120, nil, ldInfix},
  62. // Assignment statement
  63. TokenASSIGN: {NodeASSIGN, nil, nil, nil, nil, 10, nil, ldInfix},
  64. TokenLET: {NodeLET, nil, nil, nil, nil, 0, ndPrefix, nil},
  65. // Import statement
  66. TokenIMPORT: {NodeIMPORT, nil, nil, nil, nil, 0, ndImport, nil},
  67. TokenAS: {NodeAS, nil, nil, nil, nil, 0, nil, nil},
  68. // Sink definition
  69. TokenSINK: {NodeSINK, nil, nil, nil, nil, 0, ndSkink, nil},
  70. TokenKINDMATCH: {NodeKINDMATCH, nil, nil, nil, nil, 150, ndPrefix, nil},
  71. TokenSCOPEMATCH: {NodeSCOPEMATCH, nil, nil, nil, nil, 150, ndPrefix, nil},
  72. TokenSTATEMATCH: {NodeSTATEMATCH, nil, nil, nil, nil, 150, ndPrefix, nil},
  73. TokenPRIORITY: {NodePRIORITY, nil, nil, nil, nil, 150, ndPrefix, nil},
  74. TokenSUPPRESSES: {NodeSUPPRESSES, nil, nil, nil, nil, 150, ndPrefix, nil},
  75. // Function definition
  76. TokenFUNC: {NodeFUNC, nil, nil, nil, nil, 0, ndFunc, nil},
  77. TokenRETURN: {NodeRETURN, nil, nil, nil, nil, 0, ndReturn, nil},
  78. // Boolean operators
  79. TokenAND: {NodeAND, nil, nil, nil, nil, 40, nil, ldInfix},
  80. TokenOR: {NodeOR, nil, nil, nil, nil, 30, nil, ldInfix},
  81. TokenNOT: {NodeNOT, nil, nil, nil, nil, 20, ndPrefix, nil},
  82. // Condition operators
  83. TokenLIKE: {NodeLIKE, nil, nil, nil, nil, 60, nil, ldInfix},
  84. TokenIN: {NodeIN, nil, nil, nil, nil, 60, nil, ldInfix},
  85. TokenHASPREFIX: {NodeHASPREFIX, nil, nil, nil, nil, 60, nil, ldInfix},
  86. TokenHASSUFFIX: {NodeHASSUFFIX, nil, nil, nil, nil, 60, nil, ldInfix},
  87. TokenNOTIN: {NodeNOTIN, nil, nil, nil, nil, 60, nil, ldInfix},
  88. // Constant terminals
  89. TokenFALSE: {NodeFALSE, nil, nil, nil, nil, 0, ndTerm, nil},
  90. TokenTRUE: {NodeTRUE, nil, nil, nil, nil, 0, ndTerm, nil},
  91. TokenNULL: {NodeNULL, nil, nil, nil, nil, 0, ndTerm, nil},
  92. // Conditional statements
  93. TokenIF: {NodeIF, nil, nil, nil, nil, 0, ndGuard, nil},
  94. TokenELIF: {"", nil, nil, nil, nil, 0, nil, nil},
  95. TokenELSE: {"", nil, nil, nil, nil, 0, nil, nil},
  96. // Loop statement
  97. TokenFOR: {NodeLOOP, nil, nil, nil, nil, 0, ndLoop, nil},
  98. TokenBREAK: {NodeBREAK, nil, nil, nil, nil, 0, ndTerm, nil},
  99. TokenCONTINUE: {NodeCONTINUE, nil, nil, nil, nil, 0, ndTerm, nil},
  100. // Try statement
  101. TokenTRY: {NodeTRY, nil, nil, nil, nil, 0, ndTry, nil},
  102. TokenEXCEPT: {NodeEXCEPT, nil, nil, nil, nil, 0, nil, nil},
  103. TokenOTHERWISE: {NodeOTHERWISE, nil, nil, nil, nil, 0, nil, nil},
  104. TokenFINALLY: {NodeFINALLY, nil, nil, nil, nil, 0, nil, nil},
  105. // Mutex statement
  106. TokenMUTEX: {NodeMUTEX, nil, nil, nil, nil, 0, ndMutex, nil},
  107. }
  108. }
  109. // Parser
  110. // ======
  111. /*
  112. Parser data structure
  113. */
  114. type parser struct {
  115. name string // Name to identify the input
  116. node *ASTNode // Current ast node
  117. tokens *LABuffer // Buffer which is connected to the channel which contains lex tokens
  118. rp RuntimeProvider // Runtime provider which creates runtime components
  119. }
  120. /*
  121. Parse parses a given input string and returns an AST.
  122. */
  123. func Parse(name string, input string) (*ASTNode, error) {
  124. return ParseWithRuntime(name, input, nil)
  125. }
  126. /*
  127. ParseWithRuntime parses a given input string and returns an AST decorated with
  128. runtime components.
  129. */
  130. func ParseWithRuntime(name string, input string, rp RuntimeProvider) (*ASTNode, error) {
  131. // Create a new parser with a look-ahead buffer of 3
  132. p := &parser{name, nil, NewLABuffer(Lex(name, input), 3), rp}
  133. // Read and set initial AST node
  134. node, err := p.next()
  135. if err != nil {
  136. return nil, err
  137. }
  138. p.node = node
  139. n, err := p.run(0)
  140. if err == nil && hasMoreStatements(p, n) {
  141. st := astNodeMap[TokenSTATEMENTS].instance(p, nil)
  142. st.Children = append(st.Children, n)
  143. for err == nil && hasMoreStatements(p, n) {
  144. // Skip semicolons
  145. if p.node.Token.ID == TokenSEMICOLON {
  146. skipToken(p, TokenSEMICOLON)
  147. }
  148. n, err = p.run(0)
  149. st.Children = append(st.Children, n)
  150. }
  151. n = st
  152. }
  153. if err == nil && p.node != nil && p.node.Token.ID != TokenEOF {
  154. token := *p.node.Token
  155. err = p.newParserError(ErrUnexpectedEnd, fmt.Sprintf("extra token id:%v (%v)",
  156. token.ID, token), token)
  157. }
  158. return n, err
  159. }
  160. /*
  161. run models the main parser function.
  162. */
  163. func (p *parser) run(rightBinding int) (*ASTNode, error) {
  164. var err error
  165. n := p.node
  166. p.node, err = p.next()
  167. if err != nil {
  168. return nil, err
  169. }
  170. // Start with the null denotation of this statement / expression
  171. if n.nullDenotation == nil {
  172. return nil, p.newParserError(ErrImpossibleNullDenotation,
  173. n.Token.String(), *n.Token)
  174. }
  175. left, err := n.nullDenotation(p, n)
  176. if err != nil {
  177. return nil, err
  178. }
  179. // Collect left denotations as long as the left binding power is greater
  180. // than the initial right one
  181. for rightBinding < p.node.binding {
  182. var nleft *ASTNode
  183. n = p.node
  184. if n.leftDenotation == nil {
  185. if left.Token.Lline < n.Token.Lline {
  186. // If the impossible left denotation is on a new line
  187. // we might be parsing a new statement
  188. return left, nil
  189. }
  190. return nil, p.newParserError(ErrImpossibleLeftDenotation,
  191. n.Token.String(), *n.Token)
  192. }
  193. p.node, err = p.next()
  194. if err != nil {
  195. return nil, err
  196. }
  197. // Get the next left denotation
  198. nleft, err = n.leftDenotation(p, n, left)
  199. left = nleft
  200. if err != nil {
  201. return nil, err
  202. }
  203. }
  204. return left, nil
  205. }
  206. /*
  207. next retrieves the next lexer token.
  208. */
  209. func (p *parser) next() (*ASTNode, error) {
  210. var preComments []MetaData
  211. var postComments []MetaData
  212. token, more := p.tokens.Next()
  213. for more && (token.ID == TokenPRECOMMENT || token.ID == TokenPOSTCOMMENT) {
  214. if token.ID == TokenPRECOMMENT {
  215. // Skip over pre comment token
  216. preComments = append(preComments, NewLexTokenInstance(token))
  217. token, more = p.tokens.Next()
  218. }
  219. if token.ID == TokenPOSTCOMMENT {
  220. // Skip over post comment token
  221. postComments = append(postComments, NewLexTokenInstance(token))
  222. token, more = p.tokens.Next()
  223. }
  224. }
  225. if !more {
  226. // Unexpected end of input - the associated token is an empty error token
  227. return nil, p.newParserError(ErrUnexpectedEnd, "", token)
  228. } else if token.ID == TokenError {
  229. // There was a lexer error wrap it in a parser error
  230. return nil, p.newParserError(ErrLexicalError, token.Val, token)
  231. } else if node, ok := astNodeMap[token.ID]; ok {
  232. // We got a normal AST component
  233. ret := node.instance(p, &token)
  234. ret.Meta = append(ret.Meta, preComments...) // Attach pre comments to the next AST node
  235. if len(postComments) > 0 && p.node != nil {
  236. p.node.Meta = append(p.node.Meta, postComments...) // Attach post comments to the previous AST node
  237. }
  238. return ret, nil
  239. }
  240. return nil, p.newParserError(ErrUnknownToken, fmt.Sprintf("id:%v (%v)", token.ID, token), token)
  241. }
  242. // Standard null denotation functions
  243. // ==================================
  244. /*
  245. ndTerm is used for terminals.
  246. */
  247. func ndTerm(p *parser, self *ASTNode) (*ASTNode, error) {
  248. return self, nil
  249. }
  250. /*
  251. ndInner returns the inner expression of an enclosed block and discard the
  252. block token. This method is used for brackets.
  253. */
  254. func ndInner(p *parser, self *ASTNode) (*ASTNode, error) {
  255. // Get the inner expression
  256. exp, err := p.run(0)
  257. if err != nil {
  258. return nil, err
  259. }
  260. // We return here the inner expression - discarding the bracket tokens
  261. return exp, skipToken(p, TokenRPAREN)
  262. }
  263. /*
  264. ndPrefix is used for prefix operators.
  265. */
  266. func ndPrefix(p *parser, self *ASTNode) (*ASTNode, error) {
  267. // Make sure a prefix will only prefix the next item
  268. val, err := p.run(self.binding + 20)
  269. if err != nil {
  270. return nil, err
  271. }
  272. self.Children = append(self.Children, val)
  273. return self, nil
  274. }
  275. // Null denotation functions for specific expressions
  276. // ==================================================
  277. /*
  278. ndImport is used to parse imports.
  279. */
  280. func ndImport(p *parser, self *ASTNode) (*ASTNode, error) {
  281. // Must specify a file path
  282. err := acceptChild(p, self, TokenSTRING)
  283. if err == nil {
  284. // Must specify AS
  285. if err = skipToken(p, TokenAS); err == nil {
  286. // Must specify an identifier
  287. err = acceptChild(p, self, TokenIDENTIFIER)
  288. }
  289. }
  290. return self, err
  291. }
  292. /*
  293. ndSink is used to parse sinks.
  294. */
  295. func ndSkink(p *parser, self *ASTNode) (*ASTNode, error) {
  296. var exp, ret *ASTNode
  297. // Must specify a name
  298. err := acceptChild(p, self, TokenIDENTIFIER)
  299. if err == nil {
  300. // Parse the rest of the parameters as children until we reach the body
  301. for err == nil && IsNotEndAndNotTokens(p, []LexTokenID{TokenLBRACE}) {
  302. if exp, err = p.run(150); err == nil {
  303. self.Children = append(self.Children, exp)
  304. // Skip commas
  305. if p.node.Token.ID == TokenCOMMA {
  306. err = skipToken(p, TokenCOMMA)
  307. }
  308. }
  309. }
  310. if err == nil {
  311. // Parse the body
  312. ret, err = parseInnerStatements(p, self)
  313. }
  314. }
  315. return ret, err
  316. }
  317. /*
  318. ndFunc is used to parse function definitions.
  319. */
  320. func ndFunc(p *parser, self *ASTNode) (*ASTNode, error) {
  321. var exp *ASTNode
  322. var err error
  323. // Might specify a function name
  324. if p.node.Token.ID == TokenIDENTIFIER {
  325. err = acceptChild(p, self, TokenIDENTIFIER)
  326. }
  327. // Read in parameters
  328. if err == nil {
  329. err = skipToken(p, TokenLPAREN)
  330. params := astNodeMap[TokenPARAMS].instance(p, nil)
  331. self.Children = append(self.Children, params)
  332. for err == nil && IsNotEndAndNotTokens(p, []LexTokenID{TokenRPAREN}) {
  333. // Parse all the expressions inside
  334. if exp, err = p.run(0); err == nil {
  335. params.Children = append(params.Children, exp)
  336. if p.node.Token.ID == TokenCOMMA {
  337. err = skipToken(p, TokenCOMMA)
  338. }
  339. }
  340. }
  341. if err == nil {
  342. err = skipToken(p, TokenRPAREN)
  343. }
  344. }
  345. if err == nil {
  346. // Parse the body
  347. self, err = parseInnerStatements(p, self)
  348. }
  349. return self, err
  350. }
  351. /*
  352. ndReturn is used to parse return statements.
  353. */
  354. func ndReturn(p *parser, self *ASTNode) (*ASTNode, error) {
  355. var err error
  356. if self.Token.Lline == p.node.Token.Lline {
  357. var val *ASTNode
  358. // Consume the next expression only if it is on the same line
  359. val, err = p.run(0)
  360. if err == nil {
  361. self.Children = append(self.Children, val)
  362. }
  363. }
  364. return self, err
  365. }
  366. /*
  367. ndIdentifier is to parse identifiers and function calls.
  368. */
  369. func ndIdentifier(p *parser, self *ASTNode) (*ASTNode, error) {
  370. var parseMore, parseSegment, parseFuncCall, parseCompositionAccess func(parent *ASTNode) error
  371. parseMore = func(current *ASTNode) error {
  372. var err error
  373. if p.node.Token.ID == TokenDOT {
  374. err = parseSegment(current)
  375. } else if p.node.Token.ID == TokenLPAREN {
  376. err = parseFuncCall(current)
  377. } else if p.node.Token.ID == TokenLBRACK && p.node.Token.Lline == self.Token.Lline {
  378. skipToken(p, TokenLBRACK)
  379. // Composition access needs to be on the same line as the identifier
  380. // as we might otherwise have a list
  381. err = parseCompositionAccess(current)
  382. }
  383. return err
  384. }
  385. parseSegment = func(current *ASTNode) error {
  386. var err error
  387. var next *ASTNode
  388. if err = skipToken(p, TokenDOT); err == nil {
  389. next = p.node
  390. if err = acceptChild(p, current, TokenIDENTIFIER); err == nil {
  391. err = parseMore(next)
  392. }
  393. }
  394. return err
  395. }
  396. parseFuncCall = func(current *ASTNode) error {
  397. var exp *ASTNode
  398. err := skipToken(p, TokenLPAREN)
  399. fc := astNodeMap[TokenFUNCCALL].instance(p, nil)
  400. current.Children = append(current.Children, fc)
  401. // Read in parameters
  402. for err == nil && IsNotEndAndNotTokens(p, []LexTokenID{TokenRPAREN}) {
  403. // Parse all the expressions inside the directives
  404. if exp, err = p.run(0); err == nil {
  405. fc.Children = append(fc.Children, exp)
  406. if p.node.Token.ID == TokenCOMMA {
  407. err = skipToken(p, TokenCOMMA)
  408. }
  409. }
  410. }
  411. if err == nil {
  412. if err = skipToken(p, TokenRPAREN); err == nil {
  413. err = parseMore(current)
  414. }
  415. }
  416. return err
  417. }
  418. parseCompositionAccess = func(current *ASTNode) error {
  419. var exp *ASTNode
  420. var err error
  421. ca := astNodeMap[TokenCOMPACCESS].instance(p, nil)
  422. current.Children = append(current.Children, ca)
  423. // Parse all the expressions inside the directives
  424. if exp, err = p.run(0); err == nil {
  425. ca.Children = append(ca.Children, exp)
  426. if err = skipToken(p, TokenRBRACK); err == nil {
  427. err = parseMore(current)
  428. }
  429. }
  430. return err
  431. }
  432. return self, parseMore(self)
  433. }
  434. /*
  435. ndList is used to collect elements of a list.
  436. */
  437. func ndList(p *parser, self *ASTNode) (*ASTNode, error) {
  438. var err error
  439. var exp *ASTNode
  440. // Create a list token
  441. st := astNodeMap[TokenLIST].instance(p, self.Token)
  442. // Get the inner expression
  443. for err == nil && IsNotEndAndNotTokens(p, []LexTokenID{TokenRBRACK}) {
  444. // Parse all the expressions inside
  445. if exp, err = p.run(0); err == nil {
  446. st.Children = append(st.Children, exp)
  447. if p.node.Token.ID == TokenCOMMA {
  448. err = skipToken(p, TokenCOMMA)
  449. }
  450. }
  451. }
  452. if err == nil {
  453. err = skipToken(p, TokenRBRACK)
  454. }
  455. // Must have a closing bracket
  456. return st, err
  457. }
  458. /*
  459. ndMap is used to collect elements of a map.
  460. */
  461. func ndMap(p *parser, self *ASTNode) (*ASTNode, error) {
  462. var err error
  463. var exp *ASTNode
  464. // Create a map token
  465. st := astNodeMap[TokenMAP].instance(p, self.Token)
  466. // Get the inner expression
  467. for err == nil && IsNotEndAndNotTokens(p, []LexTokenID{TokenRBRACE}) {
  468. // Parse all the expressions inside
  469. if exp, err = p.run(0); err == nil {
  470. st.Children = append(st.Children, exp)
  471. if p.node.Token.ID == TokenCOMMA {
  472. err = skipToken(p, TokenCOMMA)
  473. }
  474. }
  475. }
  476. if err == nil {
  477. err = skipToken(p, TokenRBRACE)
  478. }
  479. // Must have a closing brace
  480. return st, err
  481. }
  482. /*
  483. ndGuard is used to parse a conditional statement.
  484. */
  485. func ndGuard(p *parser, self *ASTNode) (*ASTNode, error) {
  486. var err error
  487. parseGuardAndStatements := func() error {
  488. // The brace starts statements while parsing the expression of an if statement
  489. nodeMapEntryBak := astNodeMap[TokenLBRACE]
  490. astNodeMap[TokenLBRACE] = &ASTNode{"", nil, nil, nil, nil, 0, parseInnerStatements, nil}
  491. exp, err := p.run(0)
  492. astNodeMap[TokenLBRACE] = nodeMapEntryBak
  493. if err == nil {
  494. g := astNodeMap[TokenGUARD].instance(p, nil)
  495. g.Children = append(g.Children, exp)
  496. self.Children = append(self.Children, g)
  497. _, err = parseInnerStatements(p, self)
  498. }
  499. return err
  500. }
  501. if err = parseGuardAndStatements(); err == nil {
  502. for err == nil && IsNotEndAndToken(p, TokenELIF) {
  503. // Parse an elif
  504. if err = skipToken(p, TokenELIF); err == nil {
  505. err = parseGuardAndStatements()
  506. }
  507. }
  508. if err == nil && p.node.Token.ID == TokenELSE {
  509. // Parse else
  510. if err = skipToken(p, TokenELSE); err == nil {
  511. g := astNodeMap[TokenGUARD].instance(p, nil)
  512. g.Children = append(g.Children, astNodeMap[TokenTRUE].instance(p, nil))
  513. self.Children = append(self.Children, g)
  514. _, err = parseInnerStatements(p, self)
  515. }
  516. }
  517. }
  518. return self, err
  519. }
  520. /*
  521. ndLoop is used to parse a loop statement.
  522. */
  523. func ndLoop(p *parser, self *ASTNode) (*ASTNode, error) {
  524. // The brace starts statements while parsing the expression of a for statement
  525. nodeMapEntryBak := astNodeMap[TokenLBRACE]
  526. astNodeMap[TokenLBRACE] = &ASTNode{"", nil, nil, nil, nil, 0, parseInnerStatements, nil}
  527. exp, err := p.run(0)
  528. astNodeMap[TokenLBRACE] = nodeMapEntryBak
  529. if err == nil {
  530. g := exp
  531. if exp.Token.ID != TokenIN {
  532. g = astNodeMap[TokenGUARD].instance(p, nil)
  533. g.Children = append(g.Children, exp)
  534. }
  535. self.Children = append(self.Children, g)
  536. _, err = parseInnerStatements(p, self)
  537. }
  538. return self, err
  539. }
  540. /*
  541. ndTry is used to parse a try block.
  542. */
  543. func ndTry(p *parser, self *ASTNode) (*ASTNode, error) {
  544. try, err := parseInnerStatements(p, self)
  545. for err == nil && IsNotEndAndToken(p, TokenEXCEPT) {
  546. except := p.node
  547. err = acceptChild(p, try, TokenEXCEPT)
  548. for err == nil &&
  549. IsNotEndAndNotTokens(p, []LexTokenID{TokenAS, TokenIDENTIFIER, TokenLBRACE}) {
  550. if err = acceptChild(p, except, TokenSTRING); err == nil {
  551. // Skip commas
  552. if p.node.Token.ID == TokenCOMMA {
  553. err = skipToken(p, TokenCOMMA)
  554. }
  555. }
  556. }
  557. if err == nil {
  558. if p.node.Token.ID == TokenAS {
  559. as := p.node
  560. if err = acceptChild(p, except, TokenAS); err == nil {
  561. err = acceptChild(p, as, TokenIDENTIFIER)
  562. }
  563. } else if p.node.Token.ID == TokenIDENTIFIER {
  564. err = acceptChild(p, except, TokenIDENTIFIER)
  565. }
  566. }
  567. if err == nil {
  568. _, err = parseInnerStatements(p, except)
  569. }
  570. }
  571. return ndOtherwiseFinally(p, try, err)
  572. }
  573. /*
  574. ndOtherwiseFinally is used to parse otherwise and finally blocks.
  575. */
  576. func ndOtherwiseFinally(p *parser, try *ASTNode, err error) (*ASTNode, error) {
  577. if err == nil && p.node.Token.ID == TokenOTHERWISE {
  578. otherwise := p.node
  579. if err = acceptChild(p, try, TokenOTHERWISE); err == nil {
  580. _, err = parseInnerStatements(p, otherwise)
  581. }
  582. }
  583. if err == nil && p.node.Token.ID == TokenFINALLY {
  584. finally := p.node
  585. if err = acceptChild(p, try, TokenFINALLY); err == nil {
  586. _, err = parseInnerStatements(p, finally)
  587. }
  588. }
  589. return try, err
  590. }
  591. /*
  592. ndMutex is used to parse a mutex block.
  593. */
  594. func ndMutex(p *parser, self *ASTNode) (*ASTNode, error) {
  595. var block *ASTNode
  596. err := acceptChild(p, self, TokenIDENTIFIER)
  597. if err == nil {
  598. block, err = parseInnerStatements(p, self)
  599. }
  600. return block, err
  601. }
  602. // Standard left denotation functions
  603. // ==================================
  604. /*
  605. ldInfix is used for infix operators.
  606. */
  607. func ldInfix(p *parser, self *ASTNode, left *ASTNode) (*ASTNode, error) {
  608. right, err := p.run(self.binding)
  609. if err != nil {
  610. return nil, err
  611. }
  612. self.Children = append(self.Children, left)
  613. self.Children = append(self.Children, right)
  614. return self, nil
  615. }
  616. // Helper functions
  617. // ================
  618. /*
  619. IsNotEndAndToken checks if the next token is of a specific type or the end has been reached.
  620. */
  621. func IsNotEndAndToken(p *parser, i LexTokenID) bool {
  622. return p.node != nil && p.node.Name != NodeEOF && p.node.Token.ID == i
  623. }
  624. /*
  625. IsNotEndAndNotTokens checks if the next token is not of a specific type or the end has been reached.
  626. */
  627. func IsNotEndAndNotTokens(p *parser, tokens []LexTokenID) bool {
  628. ret := p.node != nil && p.node.Name != NodeEOF
  629. for _, t := range tokens {
  630. ret = ret && p.node.Token.ID != t
  631. }
  632. return ret
  633. }
  634. /*
  635. hasMoreStatements returns true if there are more statements to parse.
  636. */
  637. func hasMoreStatements(p *parser, currentNode *ASTNode) bool {
  638. nextNode := p.node
  639. if nextNode == nil || nextNode.Token.ID == TokenEOF {
  640. return false
  641. } else if nextNode.Token.ID == TokenSEMICOLON {
  642. return true
  643. }
  644. return currentNode != nil && currentNode.Token.Lline < nextNode.Token.Lline
  645. }
  646. /*
  647. skipToken skips over a given token.
  648. */
  649. func skipToken(p *parser, ids ...LexTokenID) error {
  650. var err error
  651. canSkip := func(id LexTokenID) bool {
  652. for _, i := range ids {
  653. if i == id {
  654. return true
  655. }
  656. }
  657. return false
  658. }
  659. if !canSkip(p.node.Token.ID) {
  660. if p.node.Token.ID == TokenEOF {
  661. return p.newParserError(ErrUnexpectedEnd, "", *p.node.Token)
  662. }
  663. return p.newParserError(ErrUnexpectedToken, p.node.Token.Val, *p.node.Token)
  664. }
  665. // This should never return an error unless we skip over EOF or complex tokens
  666. // like values
  667. p.node, err = p.next()
  668. return err
  669. }
  670. /*
  671. acceptChild accepts the current token as a child.
  672. */
  673. func acceptChild(p *parser, self *ASTNode, id LexTokenID) error {
  674. var err error
  675. current := p.node
  676. if p.node, err = p.next(); err == nil {
  677. if current.Token.ID == id {
  678. self.Children = append(self.Children, current)
  679. } else {
  680. err = p.newParserError(ErrUnexpectedToken, current.Token.Val, *current.Token)
  681. }
  682. }
  683. return err
  684. }
  685. /*
  686. parseInnerStatements collects the inner statements of a block statement. It
  687. is assumed that a block statement starts with a left brace '{' and ends with
  688. a right brace '}'.
  689. */
  690. func parseInnerStatements(p *parser, self *ASTNode) (*ASTNode, error) {
  691. // Must start with an opening brace
  692. if err := skipToken(p, TokenLBRACE); err != nil {
  693. return nil, err
  694. }
  695. // Always create a statements node
  696. st := astNodeMap[TokenSTATEMENTS].instance(p, nil)
  697. self.Children = append(self.Children, st)
  698. // Check if there are actually children
  699. if p.node != nil && p.node.Token.ID != TokenRBRACE {
  700. n, err := p.run(0)
  701. if p.node != nil && p.node.Token.ID != TokenEOF {
  702. st.Children = append(st.Children, n)
  703. for hasMoreStatements(p, n) {
  704. if p.node.Token.ID == TokenSEMICOLON {
  705. skipToken(p, TokenSEMICOLON)
  706. } else if p.node.Token.ID == TokenRBRACE {
  707. break
  708. }
  709. n, err = p.run(0)
  710. st.Children = append(st.Children, n)
  711. }
  712. }
  713. if err != nil {
  714. return nil, err
  715. }
  716. }
  717. // Must end with a closing brace
  718. return self, skipToken(p, TokenRBRACE)
  719. }