parser.go.y 23 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090
  1. %{
  2. package parser
  3. import (
  4. "github.com/mattn/anko/ast"
  5. )
  6. %}
  7. %type<compstmt> compstmt
  8. %type<stmts> stmts
  9. %type<stmt> stmt
  10. %type<stmt_var_or_lets> stmt_var_or_lets
  11. %type<stmt_var> stmt_var
  12. %type<stmt_lets> stmt_lets
  13. %type<stmt_if> stmt_if
  14. %type<stmt_for> stmt_for
  15. %type<stmt_switch> stmt_switch
  16. %type<stmt_switch_cases> stmt_switch_cases
  17. %type<stmt_switch_case> stmt_switch_case
  18. %type<stmt_switch_default> stmt_switch_default
  19. %type<exprs> exprs
  20. %type<expr> expr
  21. %type<expr_idents> expr_idents
  22. %type<type_data> type_data
  23. %type<type_data_struct> type_data_struct
  24. %type<slice_count> slice_count
  25. %type<expr_member_or_ident> expr_member_or_ident
  26. %type<expr_member> expr_member
  27. %type<expr_ident> expr_ident
  28. %type<expr_literals> expr_literals
  29. %type<expr_map> expr_map
  30. %type<expr_slice> expr_slice
  31. %type<expr_chan> expr_chan
  32. %type<expr> expr_unary
  33. %type<expr> expr_binary
  34. %type<expr> expr_lets
  35. %type<expr> op_binary
  36. %type<expr> op_comparison
  37. %type<expr> op_add
  38. %type<expr> op_multiply
  39. %union{
  40. tok ast.Token
  41. compstmt ast.Stmt
  42. stmts ast.Stmt
  43. stmt ast.Stmt
  44. stmt_var_or_lets ast.Stmt
  45. stmt_var ast.Stmt
  46. stmt_lets ast.Stmt
  47. stmt_if ast.Stmt
  48. stmt_for ast.Stmt
  49. stmt_switch ast.Stmt
  50. stmt_switch_cases ast.Stmt
  51. stmt_switch_case ast.Stmt
  52. stmt_switch_default ast.Stmt
  53. exprs []ast.Expr
  54. expr ast.Expr
  55. expr_idents []string
  56. type_data *ast.TypeStruct
  57. type_data_struct *ast.TypeStruct
  58. slice_count int
  59. expr_member_or_ident ast.Expr
  60. expr_member *ast.MemberExpr
  61. expr_ident *ast.IdentExpr
  62. expr_literals ast.Expr
  63. expr_map *ast.MapExpr
  64. expr_slice ast.Expr
  65. expr_chan ast.Expr
  66. expr_unary ast.Expr
  67. expr_binary ast.Expr
  68. expr_lets ast.Expr
  69. op_binary ast.Operator
  70. op_comparison ast.Operator
  71. op_add ast.Operator
  72. op_multiply ast.Operator
  73. }
  74. %token<tok> IDENT NUMBER STRING ARRAY VARARG FUNC RETURN VAR THROW IF ELSE FOR IN EQEQ NEQ GE LE OROR ANDAND NEW TRUE FALSE NIL NILCOALESCE MODULE TRY CATCH FINALLY PLUSEQ MINUSEQ MULEQ DIVEQ ANDEQ OREQ BREAK CONTINUE PLUSPLUS MINUSMINUS SHIFTLEFT SHIFTRIGHT SWITCH CASE DEFAULT GO CHAN STRUCT MAKE OPCHAN EQOPCHAN TYPE LEN DELETE CLOSE MAP IMPORT
  75. /* lowest precedence */
  76. %left ,
  77. %right '=' PLUSEQ MINUSEQ MULEQ DIVEQ ANDEQ OREQ EQOPCHAN
  78. %right ':'
  79. %right OPCHAN
  80. %right '?' NILCOALESCE
  81. %left OROR
  82. %left ANDAND
  83. %left EQEQ NEQ '<' LE '>' GE
  84. %left '+' '-' '|' '^'
  85. %left '*' '/' '%' SHIFTLEFT SHIFTRIGHT '&'
  86. %right IN
  87. %right PLUSPLUS MINUSMINUS
  88. %right UNARY
  89. /* highest precedence */
  90. /* https://golang.org/ref/spec#Expression */
  91. %%
  92. compstmt :
  93. opt_term
  94. {
  95. $$ = nil
  96. }
  97. | stmts opt_term
  98. {
  99. $$ = $1
  100. }
  101. stmts :
  102. opt_term stmt
  103. {
  104. if $2 != nil {
  105. $$ = &ast.StmtsStmt{Stmts: []ast.Stmt{$2}}
  106. }
  107. if l, ok := yylex.(*Lexer); ok {
  108. l.stmt = $$
  109. }
  110. }
  111. | stmts term stmt
  112. {
  113. if $3 != nil {
  114. if $1 == nil {
  115. $$ = &ast.StmtsStmt{Stmts: []ast.Stmt{$3}}
  116. } else {
  117. stmts := $1.(*ast.StmtsStmt)
  118. stmts.Stmts = append(stmts.Stmts, $3)
  119. }
  120. if l, ok := yylex.(*Lexer); ok {
  121. l.stmt = $$
  122. }
  123. }
  124. }
  125. stmt :
  126. /* nothing */
  127. {
  128. $$ = nil
  129. }
  130. | stmt_var_or_lets
  131. {
  132. $$ = $1
  133. }
  134. | BREAK
  135. {
  136. $$ = &ast.BreakStmt{}
  137. $$.SetPosition($1.Position())
  138. }
  139. | CONTINUE
  140. {
  141. $$ = &ast.ContinueStmt{}
  142. $$.SetPosition($1.Position())
  143. }
  144. | RETURN exprs
  145. {
  146. $$ = &ast.ReturnStmt{Exprs: $2}
  147. $$.SetPosition($1.Position())
  148. }
  149. | THROW expr
  150. {
  151. $$ = &ast.ThrowStmt{Expr: $2}
  152. $$.SetPosition($1.Position())
  153. }
  154. | MODULE IDENT '{' compstmt '}'
  155. {
  156. $$ = &ast.ModuleStmt{Name: $2.Lit, Stmt: $4}
  157. $$.SetPosition($1.Position())
  158. }
  159. | TRY '{' compstmt '}' CATCH IDENT '{' compstmt '}' FINALLY '{' compstmt '}'
  160. {
  161. $$ = &ast.TryStmt{Try: $3, Var: $6.Lit, Catch: $8, Finally: $12}
  162. $$.SetPosition($1.Position())
  163. }
  164. | TRY '{' compstmt '}' CATCH '{' compstmt '}' FINALLY '{' compstmt '}'
  165. {
  166. $$ = &ast.TryStmt{Try: $3, Catch: $7, Finally: $11}
  167. $$.SetPosition($1.Position())
  168. }
  169. | TRY '{' compstmt '}' CATCH IDENT '{' compstmt '}'
  170. {
  171. $$ = &ast.TryStmt{Try: $3, Var: $6.Lit, Catch: $8}
  172. $$.SetPosition($1.Position())
  173. }
  174. | TRY '{' compstmt '}' CATCH '{' compstmt '}'
  175. {
  176. $$ = &ast.TryStmt{Try: $3, Catch: $7}
  177. $$.SetPosition($1.Position())
  178. }
  179. | GO IDENT '(' exprs VARARG ')'
  180. {
  181. $$ = &ast.GoroutineStmt{Expr: &ast.CallExpr{Name: $2.Lit, SubExprs: $4, VarArg: true, Go: true}}
  182. $$.SetPosition($2.Position())
  183. }
  184. | GO IDENT '(' exprs ')'
  185. {
  186. $$ = &ast.GoroutineStmt{Expr: &ast.CallExpr{Name: $2.Lit, SubExprs: $4, Go: true}}
  187. $$.SetPosition($2.Position())
  188. }
  189. | GO expr '(' exprs VARARG ')'
  190. {
  191. $$ = &ast.GoroutineStmt{Expr: &ast.AnonCallExpr{Expr: $2, SubExprs: $4, VarArg: true, Go: true}}
  192. $$.SetPosition($2.Position())
  193. }
  194. | GO expr '(' exprs ')'
  195. {
  196. $$ = &ast.GoroutineStmt{Expr: &ast.AnonCallExpr{Expr: $2, SubExprs: $4, Go: true}}
  197. $$.SetPosition($1.Position())
  198. }
  199. | DELETE '(' expr ')'
  200. {
  201. $$ = &ast.DeleteStmt{Item: $3}
  202. $$.SetPosition($1.Position())
  203. }
  204. | DELETE '(' expr ',' expr ')'
  205. {
  206. $$ = &ast.DeleteStmt{Item: $3, Key: $5}
  207. $$.SetPosition($1.Position())
  208. }
  209. | CLOSE '(' expr ')'
  210. {
  211. $$ = &ast.CloseStmt{Expr: $3}
  212. $$.SetPosition($1.Position())
  213. }
  214. | stmt_if
  215. {
  216. $$ = $1
  217. }
  218. | stmt_for
  219. {
  220. $$ = $1
  221. }
  222. | stmt_switch
  223. {
  224. $$ = $1
  225. }
  226. | expr
  227. {
  228. $$ = &ast.ExprStmt{Expr: $1}
  229. $$.SetPosition($1.Position())
  230. }
  231. stmt_var_or_lets :
  232. stmt_var
  233. {
  234. $$ = $1
  235. }
  236. | stmt_lets
  237. {
  238. $$ = $1
  239. }
  240. stmt_var :
  241. VAR expr_idents '=' exprs
  242. {
  243. $$ = &ast.VarStmt{Names: $2, Exprs: $4}
  244. $$.SetPosition($1.Position())
  245. }
  246. stmt_lets :
  247. expr '=' expr
  248. {
  249. $$ = &ast.LetsStmt{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{$3}}
  250. $$.SetPosition($1.Position())
  251. }
  252. | exprs '=' exprs
  253. {
  254. if len($1) == 2 && len($3) == 1 {
  255. if _, ok := $3[0].(*ast.ItemExpr); ok {
  256. $$ = &ast.LetMapItemStmt{LHSS: $1, RHS: $3[0]}
  257. } else {
  258. $$ = &ast.LetsStmt{LHSS: $1, RHSS: $3}
  259. }
  260. } else {
  261. $$ = &ast.LetsStmt{LHSS: $1, RHSS: $3}
  262. }
  263. $$.SetPosition($1[0].Position())
  264. }
  265. | expr EQOPCHAN expr
  266. {
  267. $$ = &ast.ChanStmt{LHS: $1, RHS: $3}
  268. $$.SetPosition($1.Position())
  269. }
  270. | exprs EQOPCHAN expr
  271. {
  272. if len($1) == 2 {
  273. chanStmt := &ast.ChanStmt{LHS: $1[0].(ast.Expr), OkExpr: $1[1].(ast.Expr), RHS: $3}
  274. $$ = chanStmt
  275. $$.SetPosition(chanStmt.LHS.Position())
  276. } else if len($1) < 2 {
  277. yylex.Error("missing expressions on left side of channel operator")
  278. $$ = &ast.ChanStmt{RHS: $3}
  279. $$.SetPosition($2.Position())
  280. }
  281. }
  282. stmt_if :
  283. IF expr '{' compstmt '}'
  284. {
  285. $$ = &ast.IfStmt{If: $2, Then: $4, Else: nil}
  286. $$.SetPosition($1.Position())
  287. }
  288. | stmt_if ELSE IF expr '{' compstmt '}'
  289. {
  290. ifStmt := $1.(*ast.IfStmt)
  291. ifStmt.ElseIf = append(ifStmt.ElseIf, &ast.IfStmt{If: $4, Then: $6})
  292. }
  293. | stmt_if ELSE '{' compstmt '}'
  294. {
  295. ifStmt := $1.(*ast.IfStmt)
  296. if ifStmt.Else != nil {
  297. yylex.Error("multiple else statement")
  298. }
  299. ifStmt.Else = $4
  300. }
  301. stmt_for :
  302. FOR '{' compstmt '}'
  303. {
  304. $$ = &ast.LoopStmt{Stmt: $3}
  305. $$.SetPosition($1.Position())
  306. }
  307. | FOR expr_idents IN expr '{' compstmt '}'
  308. {
  309. if len($2) < 1 {
  310. yylex.Error("missing identifier")
  311. } else if len($2) > 2 {
  312. yylex.Error("too many identifiers")
  313. } else {
  314. $$ = &ast.ForStmt{Vars: $2, Value: $4, Stmt: $6}
  315. $$.SetPosition($1.Position())
  316. }
  317. }
  318. | FOR expr '{' compstmt '}'
  319. {
  320. $$ = &ast.LoopStmt{Expr: $2, Stmt: $4}
  321. $$.SetPosition($1.Position())
  322. }
  323. | FOR ';' ';' '{' compstmt '}'
  324. {
  325. $$ = &ast.CForStmt{Stmt: $5}
  326. $$.SetPosition($1.Position())
  327. }
  328. | FOR ';' ';' expr '{' compstmt '}'
  329. {
  330. $$ = &ast.CForStmt{Expr3: $4, Stmt: $6}
  331. $$.SetPosition($1.Position())
  332. }
  333. | FOR ';' expr ';' '{' compstmt '}'
  334. {
  335. $$ = &ast.CForStmt{Expr2: $3, Stmt: $6}
  336. $$.SetPosition($1.Position())
  337. }
  338. | FOR ';' expr ';' expr '{' compstmt '}'
  339. {
  340. $$ = &ast.CForStmt{Expr2: $3, Expr3: $5, Stmt: $7}
  341. $$.SetPosition($1.Position())
  342. }
  343. | FOR stmt_var_or_lets ';' ';' '{' compstmt '}'
  344. {
  345. $$ = &ast.CForStmt{Stmt1: $2, Stmt: $6}
  346. $$.SetPosition($1.Position())
  347. }
  348. | FOR stmt_var_or_lets ';' ';' expr '{' compstmt '}'
  349. {
  350. $$ = &ast.CForStmt{Stmt1: $2, Expr3: $5, Stmt: $7}
  351. $$.SetPosition($1.Position())
  352. }
  353. | FOR stmt_var_or_lets ';' expr ';' '{' compstmt '}'
  354. {
  355. $$ = &ast.CForStmt{Stmt1: $2, Expr2: $4, Stmt: $7}
  356. $$.SetPosition($1.Position())
  357. }
  358. | FOR stmt_var_or_lets ';' expr ';' expr '{' compstmt '}'
  359. {
  360. $$ = &ast.CForStmt{Stmt1: $2, Expr2: $4, Expr3: $6, Stmt: $8}
  361. $$.SetPosition($1.Position())
  362. }
  363. stmt_switch :
  364. SWITCH expr '{' opt_newlines stmt_switch_cases opt_newlines '}'
  365. {
  366. switchStmt := $5.(*ast.SwitchStmt)
  367. switchStmt.Expr = $2
  368. $$ = switchStmt
  369. $$.SetPosition($1.Position())
  370. }
  371. stmt_switch_cases :
  372. /* nothing */
  373. {
  374. $$ = &ast.SwitchStmt{}
  375. }
  376. | stmt_switch_default
  377. {
  378. $$ = &ast.SwitchStmt{Default: $1}
  379. }
  380. | stmt_switch_case
  381. {
  382. $$ = &ast.SwitchStmt{Cases: []ast.Stmt{$1}}
  383. }
  384. | stmt_switch_cases stmt_switch_case
  385. {
  386. switchStmt := $1.(*ast.SwitchStmt)
  387. switchStmt.Cases = append(switchStmt.Cases, $2)
  388. $$ = switchStmt
  389. }
  390. | stmt_switch_cases stmt_switch_default
  391. {
  392. switchStmt := $1.(*ast.SwitchStmt)
  393. if switchStmt.Default != nil {
  394. yylex.Error("multiple default statement")
  395. }
  396. switchStmt.Default = $2
  397. }
  398. stmt_switch_case :
  399. CASE expr ':' compstmt
  400. {
  401. $$ = &ast.SwitchCaseStmt{Exprs: []ast.Expr{$2}, Stmt: $4}
  402. $$.SetPosition($1.Position())
  403. }
  404. | CASE exprs ':' compstmt
  405. {
  406. $$ = &ast.SwitchCaseStmt{Exprs: $2, Stmt: $4}
  407. $$.SetPosition($1.Position())
  408. }
  409. stmt_switch_default :
  410. DEFAULT ':' compstmt
  411. {
  412. $$ = $3
  413. }
  414. exprs :
  415. /* nothing */
  416. {
  417. $$ = nil
  418. }
  419. | expr
  420. {
  421. $$ = []ast.Expr{$1}
  422. }
  423. | exprs ',' opt_newlines expr
  424. {
  425. if len($1) == 0 {
  426. yylex.Error("syntax error: unexpected ','")
  427. }
  428. $$ = append($1, $4)
  429. }
  430. | exprs ',' opt_newlines expr_ident
  431. {
  432. if len($1) == 0 {
  433. yylex.Error("syntax error: unexpected ','")
  434. }
  435. $$ = append($1, $4)
  436. }
  437. expr :
  438. expr_member_or_ident
  439. {
  440. $$ = $1
  441. }
  442. | expr_literals
  443. {
  444. $$ = $1
  445. }
  446. | expr '?' expr ':' expr
  447. {
  448. $$ = &ast.TernaryOpExpr{Expr: $1, LHS: $3, RHS: $5}
  449. $$.SetPosition($1.Position())
  450. }
  451. | expr NILCOALESCE expr
  452. {
  453. $$ = &ast.NilCoalescingOpExpr{LHS: $1, RHS: $3}
  454. $$.SetPosition($1.Position())
  455. }
  456. | FUNC '(' expr_idents ')' '{' compstmt '}'
  457. {
  458. $$ = &ast.FuncExpr{Params: $3, Stmt: $6}
  459. $$.SetPosition($1.Position())
  460. }
  461. | FUNC '(' expr_idents VARARG ')' '{' compstmt '}'
  462. {
  463. $$ = &ast.FuncExpr{Params: $3, Stmt: $7, VarArg: true}
  464. $$.SetPosition($1.Position())
  465. }
  466. | FUNC IDENT '(' expr_idents ')' '{' compstmt '}'
  467. {
  468. $$ = &ast.FuncExpr{Name: $2.Lit, Params: $4, Stmt: $7}
  469. $$.SetPosition($1.Position())
  470. }
  471. | FUNC IDENT '(' expr_idents VARARG ')' '{' compstmt '}'
  472. {
  473. $$ = &ast.FuncExpr{Name: $2.Lit, Params: $4, Stmt: $8, VarArg: true}
  474. $$.SetPosition($1.Position())
  475. }
  476. | '[' ']'
  477. {
  478. $$ = &ast.ArrayExpr{}
  479. if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) }
  480. }
  481. | '[' opt_newlines exprs opt_comma_newlines ']'
  482. {
  483. $$ = &ast.ArrayExpr{Exprs: $3}
  484. if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) }
  485. }
  486. | slice_count type_data '{' opt_newlines exprs opt_comma_newlines '}'
  487. {
  488. $$ = &ast.ArrayExpr{Exprs: $5, TypeData: &ast.TypeStruct{Kind: ast.TypeSlice, SubType: $2, Dimensions: $1}}
  489. if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) }
  490. }
  491. | '(' expr ')'
  492. {
  493. $$ = &ast.ParenExpr{SubExpr: $2}
  494. if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) }
  495. }
  496. | IDENT '(' exprs VARARG ')'
  497. {
  498. $$ = &ast.CallExpr{Name: $1.Lit, SubExprs: $3, VarArg: true}
  499. $$.SetPosition($1.Position())
  500. }
  501. | IDENT '(' exprs ')'
  502. {
  503. $$ = &ast.CallExpr{Name: $1.Lit, SubExprs: $3}
  504. $$.SetPosition($1.Position())
  505. }
  506. | expr '(' exprs VARARG ')'
  507. {
  508. $$ = &ast.AnonCallExpr{Expr: $1, SubExprs: $3, VarArg: true}
  509. $$.SetPosition($1.Position())
  510. }
  511. | expr '(' exprs ')'
  512. {
  513. $$ = &ast.AnonCallExpr{Expr: $1, SubExprs: $3}
  514. $$.SetPosition($1.Position())
  515. }
  516. | expr_ident '[' expr ']'
  517. {
  518. $$ = &ast.ItemExpr{Item: $1, Index: $3}
  519. $$.SetPosition($1.Position())
  520. }
  521. | expr '[' expr ']'
  522. {
  523. $$ = &ast.ItemExpr{Item: $1, Index: $3}
  524. $$.SetPosition($1.Position())
  525. }
  526. | LEN '(' expr ')'
  527. {
  528. $$ = &ast.LenExpr{Expr: $3}
  529. $$.SetPosition($1.Position())
  530. }
  531. | IMPORT '(' expr ')'
  532. {
  533. $$ = &ast.ImportExpr{Name: $3}
  534. $$.SetPosition($1.Position())
  535. }
  536. | NEW '(' type_data ')'
  537. {
  538. if $3.Kind == ast.TypeDefault {
  539. $3.Kind = ast.TypePtr
  540. $$ = &ast.MakeExpr{TypeData: $3}
  541. } else {
  542. $$ = &ast.MakeExpr{TypeData: &ast.TypeStruct{Kind: ast.TypePtr, SubType: $3}}
  543. }
  544. $$.SetPosition($1.Position())
  545. }
  546. | MAKE '(' type_data ')'
  547. {
  548. $$ = &ast.MakeExpr{TypeData: $3}
  549. $$.SetPosition($1.Position())
  550. }
  551. | MAKE '(' type_data ',' expr ')'
  552. {
  553. $$ = &ast.MakeExpr{TypeData: $3, LenExpr: $5}
  554. $$.SetPosition($1.Position())
  555. }
  556. | MAKE '(' type_data ',' expr ',' expr ')'
  557. {
  558. $$ = &ast.MakeExpr{TypeData: $3, LenExpr: $5, CapExpr: $7}
  559. $$.SetPosition($1.Position())
  560. }
  561. | MAKE '(' TYPE IDENT ',' expr ')'
  562. {
  563. $$ = &ast.MakeTypeExpr{Name: $4.Lit, Type: $6}
  564. $$.SetPosition($1.Position())
  565. }
  566. | expr IN expr
  567. {
  568. $$ = &ast.IncludeExpr{ItemExpr: $1, ListExpr: $3}
  569. $$.SetPosition($1.Position())
  570. }
  571. | MAP '{' opt_newlines expr_map opt_comma_newlines '}'
  572. {
  573. $4.TypeData = &ast.TypeStruct{Kind: ast.TypeMap, Key: &ast.TypeStruct{Name: "interface"}, SubType: &ast.TypeStruct{Name: "interface"}}
  574. $$ = $4
  575. $$.SetPosition($1.Position())
  576. }
  577. | MAP '[' type_data ']' type_data '{' opt_newlines expr_map opt_comma_newlines '}'
  578. {
  579. $8.TypeData = &ast.TypeStruct{Kind: ast.TypeMap, Key: $3, SubType: $5}
  580. $$ = $8
  581. $$.SetPosition($1.Position())
  582. }
  583. | '{' opt_newlines expr_map opt_comma_newlines '}'
  584. {
  585. $$ = $3
  586. $$.SetPosition($3.Position())
  587. }
  588. | expr_slice
  589. {
  590. $$ = $1
  591. $$.SetPosition($1.Position())
  592. }
  593. | expr_chan
  594. {
  595. $$ = $1
  596. $$.SetPosition($1.Position())
  597. }
  598. | expr_unary
  599. | expr_binary
  600. | expr_lets
  601. expr_idents :
  602. {
  603. $$ = []string{}
  604. }
  605. | IDENT
  606. {
  607. $$ = []string{$1.Lit}
  608. }
  609. | expr_idents ',' opt_newlines IDENT
  610. {
  611. if len($1) == 0 {
  612. yylex.Error("syntax error: unexpected ','")
  613. }
  614. $$ = append($1, $4.Lit)
  615. }
  616. type_data :
  617. IDENT
  618. {
  619. $$ = &ast.TypeStruct{Name: $1.Lit}
  620. }
  621. | type_data '.' IDENT
  622. {
  623. if $1.Kind != ast.TypeDefault {
  624. yylex.Error("not type default")
  625. } else {
  626. $1.Env = append($1.Env, $1.Name)
  627. $1.Name = $3.Lit
  628. }
  629. }
  630. | '*' type_data
  631. {
  632. if $2.Kind == ast.TypeDefault {
  633. $2.Kind = ast.TypePtr
  634. $$ = $2
  635. } else {
  636. $$ = &ast.TypeStruct{Kind: ast.TypePtr, SubType: $2}
  637. }
  638. }
  639. | slice_count type_data
  640. {
  641. if $2.Kind == ast.TypeDefault {
  642. $2.Kind = ast.TypeSlice
  643. $2.Dimensions = $1
  644. $$ = $2
  645. } else {
  646. $$ = &ast.TypeStruct{Kind: ast.TypeSlice, SubType: $2, Dimensions: $1}
  647. }
  648. }
  649. | MAP '[' type_data ']' type_data
  650. {
  651. $$ = &ast.TypeStruct{Kind: ast.TypeMap, Key: $3, SubType: $5}
  652. }
  653. | CHAN type_data
  654. {
  655. if $2.Kind == ast.TypeDefault {
  656. $2.Kind = ast.TypeChan
  657. $$ = $2
  658. } else {
  659. $$ = &ast.TypeStruct{Kind: ast.TypeChan, SubType: $2}
  660. }
  661. }
  662. | STRUCT '{' opt_newlines type_data_struct opt_newlines '}'
  663. {
  664. $$ = $4
  665. }
  666. type_data_struct :
  667. IDENT type_data
  668. {
  669. $$ = &ast.TypeStruct{Kind: ast.TypeStructType, StructNames: []string{$1.Lit}, StructTypes: []*ast.TypeStruct{$2}}
  670. }
  671. | type_data_struct ',' opt_newlines IDENT type_data
  672. {
  673. if $1 == nil {
  674. yylex.Error("syntax error: unexpected ','")
  675. }
  676. $$.StructNames = append($$.StructNames, $4.Lit)
  677. $$.StructTypes = append($$.StructTypes, $5)
  678. }
  679. slice_count :
  680. '[' ']'
  681. {
  682. $$ = 1
  683. }
  684. | '[' ']' slice_count
  685. {
  686. $$ = $3 + 1
  687. }
  688. expr_member_or_ident :
  689. expr_member
  690. {
  691. $$ = $1
  692. }
  693. | expr_ident
  694. {
  695. $$ = $1
  696. }
  697. expr_member :
  698. expr '.' IDENT
  699. {
  700. $$ = &ast.MemberExpr{Expr: $1, Name: $3.Lit}
  701. $$.SetPosition($1.Position())
  702. }
  703. expr_ident :
  704. IDENT
  705. {
  706. $$ = &ast.IdentExpr{Lit: $1.Lit}
  707. $$.SetPosition($1.Position())
  708. }
  709. expr_literals :
  710. '-' NUMBER
  711. {
  712. num, err := toNumber("-" + $2.Lit)
  713. if err != nil {
  714. yylex.Error("invalid number: -" + $2.Lit)
  715. }
  716. $$ = &ast.LiteralExpr{Literal: num}
  717. $$.SetPosition($2.Position())
  718. }
  719. | NUMBER
  720. {
  721. num, err := toNumber($1.Lit)
  722. if err != nil {
  723. yylex.Error("invalid number: " + $1.Lit)
  724. }
  725. $$ = &ast.LiteralExpr{Literal: num}
  726. $$.SetPosition($1.Position())
  727. }
  728. | STRING
  729. {
  730. $$ = &ast.LiteralExpr{Literal: stringToValue($1.Lit)}
  731. $$.SetPosition($1.Position())
  732. }
  733. | TRUE
  734. {
  735. $$ = &ast.LiteralExpr{Literal: trueValue}
  736. $$.SetPosition($1.Position())
  737. }
  738. | FALSE
  739. {
  740. $$ = &ast.LiteralExpr{Literal: falseValue}
  741. $$.SetPosition($1.Position())
  742. }
  743. | NIL
  744. {
  745. $$ = &ast.LiteralExpr{Literal: nilValue}
  746. $$.SetPosition($1.Position())
  747. }
  748. expr_map :
  749. /* nothing */
  750. {
  751. $$ = &ast.MapExpr{}
  752. }
  753. | expr ':' expr
  754. {
  755. $$ = &ast.MapExpr{Keys: []ast.Expr{$1}, Values: []ast.Expr{$3}}
  756. }
  757. | expr_map ',' opt_newlines expr ':' expr
  758. {
  759. if $1.Keys == nil {
  760. yylex.Error("syntax error: unexpected ','")
  761. }
  762. $$.Keys = append($$.Keys, $4)
  763. $$.Values = append($$.Values, $6)
  764. }
  765. expr_slice :
  766. expr_ident '[' expr ':' expr ']'
  767. {
  768. $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: $5}
  769. }
  770. | expr_ident '[' expr ':' ']'
  771. {
  772. $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: nil}
  773. }
  774. | expr_ident '[' ':' expr ']'
  775. {
  776. $$ = &ast.SliceExpr{Item: $1, Begin: nil, End: $4}
  777. }
  778. | expr_ident '[' ':' expr ':' expr ']'
  779. {
  780. $$ = &ast.SliceExpr{Item: $1, End: $4, Cap: $6}
  781. }
  782. | expr_ident '[' expr ':' expr ':' expr ']'
  783. {
  784. $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: $5, Cap: $7}
  785. }
  786. | expr '[' expr ':' expr ']'
  787. {
  788. $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: $5}
  789. }
  790. | expr '[' expr ':' ']'
  791. {
  792. $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: nil}
  793. }
  794. | expr '[' ':' expr ']'
  795. {
  796. $$ = &ast.SliceExpr{Item: $1, Begin: nil, End: $4}
  797. }
  798. | expr '[' ':' expr ':' expr ']'
  799. {
  800. $$ = &ast.SliceExpr{Item: $1, End: $4, Cap: $6}
  801. }
  802. | expr '[' expr ':' expr ':' expr ']'
  803. {
  804. $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: $5, Cap: $7}
  805. }
  806. expr_chan :
  807. expr OPCHAN expr
  808. {
  809. $$ = &ast.ChanExpr{LHS: $1, RHS: $3}
  810. }
  811. | OPCHAN expr
  812. {
  813. $$ = &ast.ChanExpr{RHS: $2}
  814. }
  815. expr_unary :
  816. '-' expr %prec UNARY
  817. {
  818. $$ = &ast.UnaryExpr{Operator: "-", Expr: $2}
  819. $$.SetPosition($2.Position())
  820. }
  821. | '!' expr %prec UNARY
  822. {
  823. $$ = &ast.UnaryExpr{Operator: "!", Expr: $2}
  824. $$.SetPosition($2.Position())
  825. }
  826. | '^' expr %prec UNARY
  827. {
  828. $$ = &ast.UnaryExpr{Operator: "^", Expr: $2}
  829. $$.SetPosition($2.Position())
  830. }
  831. | '&' expr %prec UNARY
  832. {
  833. $$ = &ast.AddrExpr{Expr: $2}
  834. $$.SetPosition($2.Position())
  835. }
  836. | '*' expr %prec UNARY
  837. {
  838. $$ = &ast.DerefExpr{Expr: $2}
  839. $$.SetPosition($2.Position())
  840. }
  841. expr_binary :
  842. op_multiply
  843. {
  844. $$ = &ast.OpExpr{Op: $1}
  845. $$.SetPosition($1.Position())
  846. }
  847. | op_add
  848. {
  849. $$ = &ast.OpExpr{Op: $1}
  850. $$.SetPosition($1.Position())
  851. }
  852. | op_comparison
  853. {
  854. $$ = &ast.OpExpr{Op: $1}
  855. $$.SetPosition($1.Position())
  856. }
  857. | op_binary
  858. {
  859. $$ = &ast.OpExpr{Op: $1}
  860. $$.SetPosition($1.Position())
  861. }
  862. expr_lets:
  863. expr PLUSPLUS
  864. {
  865. rhs := &ast.OpExpr{Op: &ast.AddOperator{LHS: $1, Operator: "+", RHS: oneLiteral}}
  866. rhs.Op.SetPosition($1.Position())
  867. rhs.SetPosition($1.Position())
  868. $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
  869. $$.SetPosition($1.Position())
  870. }
  871. | expr MINUSMINUS
  872. {
  873. rhs := &ast.OpExpr{Op: &ast.AddOperator{LHS: $1, Operator: "-", RHS: oneLiteral}}
  874. rhs.Op.SetPosition($1.Position())
  875. rhs.SetPosition($1.Position())
  876. $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
  877. $$.SetPosition($1.Position())
  878. }
  879. | expr PLUSEQ expr
  880. {
  881. rhs := &ast.OpExpr{Op: &ast.AddOperator{LHS: $1, Operator: "+", RHS: $3}}
  882. rhs.Op.SetPosition($1.Position())
  883. rhs.SetPosition($1.Position())
  884. $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
  885. $$.SetPosition($1.Position())
  886. }
  887. | expr MINUSEQ expr
  888. {
  889. rhs := &ast.OpExpr{Op: &ast.AddOperator{LHS: $1, Operator: "-", RHS: $3}}
  890. rhs.Op.SetPosition($1.Position())
  891. rhs.SetPosition($1.Position())
  892. $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
  893. $$.SetPosition($1.Position())
  894. }
  895. | expr OREQ expr
  896. {
  897. rhs := &ast.OpExpr{Op: &ast.AddOperator{LHS: $1, Operator: "|", RHS: $3}}
  898. rhs.Op.SetPosition($1.Position())
  899. rhs.SetPosition($1.Position())
  900. $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
  901. $$.SetPosition($1.Position())
  902. }
  903. | expr MULEQ expr
  904. {
  905. rhs := &ast.OpExpr{Op: &ast.MultiplyOperator{LHS: $1, Operator: "*", RHS: $3}}
  906. rhs.Op.SetPosition($1.Position())
  907. rhs.SetPosition($1.Position())
  908. $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
  909. $$.SetPosition($1.Position())
  910. }
  911. | expr DIVEQ expr
  912. {
  913. rhs := &ast.OpExpr{Op: &ast.MultiplyOperator{LHS: $1, Operator: "/", RHS: $3}}
  914. rhs.Op.SetPosition($1.Position())
  915. rhs.SetPosition($1.Position())
  916. $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
  917. $$.SetPosition($1.Position())
  918. }
  919. | expr ANDEQ expr
  920. {
  921. rhs := &ast.OpExpr{Op: &ast.MultiplyOperator{LHS: $1, Operator: "&", RHS: $3}}
  922. rhs.Op.SetPosition($1.Position())
  923. rhs.SetPosition($1.Position())
  924. $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
  925. $$.SetPosition($1.Position())
  926. }
  927. op_multiply :
  928. expr '*' expr
  929. {
  930. $$ = &ast.MultiplyOperator{LHS: $1, Operator: "*", RHS: $3}
  931. $$.SetPosition($1.Position())
  932. }
  933. | expr '/' expr
  934. {
  935. $$ = &ast.MultiplyOperator{LHS: $1, Operator: "/", RHS: $3}
  936. $$.SetPosition($1.Position())
  937. }
  938. | expr '%' expr
  939. {
  940. $$ = &ast.MultiplyOperator{LHS: $1, Operator: "%", RHS: $3}
  941. $$.SetPosition($1.Position())
  942. }
  943. | expr SHIFTLEFT expr
  944. {
  945. $$ = &ast.MultiplyOperator{LHS: $1, Operator: "<<", RHS: $3}
  946. $$.SetPosition($1.Position())
  947. }
  948. | expr SHIFTRIGHT expr
  949. {
  950. $$ = &ast.MultiplyOperator{LHS: $1, Operator: ">>", RHS: $3}
  951. $$.SetPosition($1.Position())
  952. }
  953. | expr '&' expr
  954. {
  955. $$ = &ast.MultiplyOperator{LHS: $1, Operator: "&", RHS: $3}
  956. $$.SetPosition($1.Position())
  957. }
  958. op_add :
  959. expr '+' expr
  960. {
  961. $$ = &ast.AddOperator{LHS: $1, Operator: "+", RHS: $3}
  962. $$.SetPosition($1.Position())
  963. }
  964. | expr '-' expr
  965. {
  966. $$ = &ast.AddOperator{LHS: $1, Operator: "-", RHS: $3}
  967. $$.SetPosition($1.Position())
  968. }
  969. | expr '|' expr
  970. {
  971. $$ = &ast.AddOperator{LHS: $1, Operator: "|", RHS: $3}
  972. $$.SetPosition($1.Position())
  973. }
  974. op_comparison :
  975. expr EQEQ expr
  976. {
  977. $$ = &ast.ComparisonOperator{LHS: $1, Operator: "==", RHS: $3}
  978. $$.SetPosition($1.Position())
  979. }
  980. | expr NEQ expr
  981. {
  982. $$ = &ast.ComparisonOperator{LHS: $1, Operator: "!=", RHS: $3}
  983. $$.SetPosition($1.Position())
  984. }
  985. | expr '<' expr
  986. {
  987. $$ = &ast.ComparisonOperator{LHS: $1, Operator: "<", RHS: $3}
  988. $$.SetPosition($1.Position())
  989. }
  990. | expr LE expr
  991. {
  992. $$ = &ast.ComparisonOperator{LHS: $1, Operator: "<=", RHS: $3}
  993. $$.SetPosition($1.Position())
  994. }
  995. | expr '>' expr
  996. {
  997. $$ = &ast.ComparisonOperator{LHS: $1, Operator: ">", RHS: $3}
  998. $$.SetPosition($1.Position())
  999. }
  1000. | expr GE expr
  1001. {
  1002. $$ = &ast.ComparisonOperator{LHS: $1, Operator: ">=", RHS: $3}
  1003. $$.SetPosition($1.Position())
  1004. }
  1005. op_binary :
  1006. expr ANDAND expr
  1007. {
  1008. $$ = &ast.BinaryOperator{LHS: $1, Operator: "&&", RHS: $3}
  1009. $$.SetPosition($1.Position())
  1010. }
  1011. | expr OROR expr
  1012. {
  1013. $$ = &ast.BinaryOperator{LHS: $1, Operator: "||", RHS: $3}
  1014. $$.SetPosition($1.Position())
  1015. }
  1016. opt_term :
  1017. /* nothing */
  1018. | term
  1019. term :
  1020. ';' newlines
  1021. | newlines
  1022. | ';'
  1023. opt_newlines :
  1024. /* nothing */
  1025. | newlines
  1026. newlines :
  1027. newline
  1028. | newlines newline
  1029. newline : '\n'
  1030. opt_comma_newlines :
  1031. /* nothing */
  1032. | ',' newlines
  1033. | newlines
  1034. | ','
  1035. %%