Advertisement
Guest User

Untitled

a guest
Nov 16th, 2019
287
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.29 KB | None | 0 0
  1. %lex
  2.  
  3. %{
  4.  
  5. /* After reading a lexeme go to "delimit" state to
  6. expect delimiter and return the lexeme. Arrow function
  7. is used to bind this. */
  8. var delimit = (terminal) => { this.begin('delimit'); return terminal }
  9.  
  10. %}
  11.  
  12. DELIMITER ";"
  13.  
  14. %x delimit
  15. %x string_literal
  16.  
  17. %%
  18.  
  19. "LT" { return delimit('LT') }
  20. "LE" { return delimit('LE') }
  21. "EQ" { return delimit('EQ') }
  22. "NE" { return delimit('NE') }
  23. "GE" { return delimit('GE') }
  24. "GT" { return delimit('GT') }
  25.  
  26. "PLUS" { return delimit('PLUS') }
  27. "MINUS" { return delimit('MINUS') }
  28. "MUL" { return delimit('MUL') }
  29. "DIV" { return delimit('DIV') }
  30. "MOD" { return delimit('MOD') }
  31.  
  32. "TRUE" { return delimit('TRUE') }
  33. "FALSE" { return delimit('FALSE') }
  34. "NOT" { return delimit('NOT') }
  35. "OR" { return delimit('OR') }
  36. "AND" { return delimit('AND') }
  37.  
  38. "ASSIGN" { return delimit('ASSIGN') }
  39. "NONE" { return delimit('NONE') }
  40.  
  41. "LPAR" { return delimit('LPAR') }
  42. "RPAR" { return delimit('RPAR') }
  43. "LBRA" { return delimit('LBRA') }
  44. "RBRA" { return delimit('RBRA') }
  45. "LCURLY" { return delimit('LCURLY') }
  46. "RCURLY" { return delimit('RCURLY') }
  47.  
  48. "IF" { return delimit('IF') }
  49. "ELSE" { return delimit('ELSE') }
  50. "WHILE" { return delimit('WHILE') }
  51. "FOR" { return delimit('FOR') }
  52.  
  53. "CLASS" { return delimit('CLASS') }
  54. "FUNCTION" { return delimit('FUNCTION') }
  55. "RETURN" { return delimit('RETURN') }
  56. "CONTINUE" { return delimit('CONTINUE') }
  57. "BREAK" { return delimit('BREAK') }
  58.  
  59. "SPACE" {
  60. /* ignore spaces unless in string literal */
  61. this.begin('delimit')
  62. }
  63. <string_literal>"SPACE" { yytext = ' '; return delimit('LETTER') }
  64. "SEMICOLON" { return delimit('SEMICOLON') }
  65. "DOT" { return delimit('DOT') }
  66. "PROP" { return delimit('PROP') }
  67. "COMMA" { return delimit('COMMA') }
  68. "QUOTE" { this.begin('string_literal'); return delimit('QUOTE') }
  69. <string_literal>"QUOTE" { this.popState(); return delimit('QUOTE') }
  70. <INITIAL,string_literal>D[0-9]
  71. { yytext = yytext.substr(1); return delimit('DIGIT') }
  72. <INITIAL,string_literal>[A-Z_]
  73. { return delimit('LETTER') }
  74.  
  75. <delimit>{DELIMITER} { this.popState() }
  76.  
  77. <INITIAL,delimit,string_literal>\s+ /* ignore whitespace */
  78. <delimit>. { throw new Error('Delimiter expected: ' + yytext) }
  79. <string_literal>. { throw new Error('End of string literal expected: ' + yytext) }
  80. <INITIAL>. { throw new Error(`Unknown gifcode "${yytext}"`) }
  81.  
  82. <delimit><<EOF>> { throw new Error('Delimiter expected') }
  83. <<EOF>> { return 'EOF' }
  84.  
  85. /lex
  86.  
  87. /* operator associations and precedence */
  88. %left OR
  89. %left AND
  90. %left EQ NE
  91. %left LT LE GE GT
  92. %left PLUS MINUS
  93. %left MUL DIV MOD
  94.  
  95. %nonassoc IF_WITHOUT_ELSE
  96. %nonassoc ELSE
  97.  
  98. %start Program
  99.  
  100. %%
  101.  
  102. Program
  103. : Primitives EOF { return new yy.Stmt.ProgramStmt($1, @$) }
  104. ;
  105.  
  106. Primitives
  107. : Primitives Statement { $1.push($2); $$ = $1 }
  108. | Primitives ClassDefinition { $1.push($2); $$ = $1 }
  109. | %epsilon { $$ = [] }
  110. ;
  111.  
  112. Identifier
  113. : LETTER Alfanum { $$ = $1 + $2 }
  114. ;
  115.  
  116. Alfanum
  117. : AlfanumAtom Alfanum { $$ = $1 + $2 }
  118. | %epsilon { $$ = '' }
  119. ;
  120.  
  121. AlfanumAtom
  122. : LETTER { $$ = $1 }
  123. | DIGIT { $$ = $1 }
  124. ;
  125.  
  126. UFloat
  127. : UInt DOT UInt { $$ = $1 + '.' + $3 }
  128. ;
  129.  
  130. UInt
  131. : UInt DIGIT { $$ = $1 + $2 }
  132. | DIGIT { $$ = $1 }
  133. ;
  134.  
  135. String
  136. : QUOTE Alfanum QUOTE { $$ = $2 }
  137. ;
  138.  
  139. PrimaryComnon
  140. : Identifier { $$ = new yy.Expr.VariableRefExpr($1, @$) }
  141. | LPAR Expr RPAR { $$ = $2 }
  142. | ArrayLiteral { $$ = $1 }
  143. | Literal { $$ = $1 }
  144. ;
  145.  
  146. Literal
  147. : TRUE { $$ = new yy.Expr.VariableRefExpr('TRUE', @$) }
  148. | FALSE { $$ = new yy.Expr.VariableRefExpr('FALSE', @$) }
  149. | NONE { $$ = new yy.Expr.NoneValueExpr(@$) }
  150. | UInt { $$ = new yy.Expr.NumberValueExpr($1, @$) }
  151. | UFloat { $$ = new yy.Expr.NumberValueExpr($1, @$) }
  152. | String { $$ = new yy.Expr.StringValueExpr($1, @$) }
  153. ;
  154.  
  155. ArrayLiteral
  156. : LBRA ElementList RBRA { $$ = new yy.Expr.ArrayValueExpr($2, @$) }
  157. | LBRA RBRA { $$ = new yy.Expr.ArrayValueExpr([], @$) }
  158. ;
  159.  
  160. ElementList
  161. : Expr { $$ = [$1] }
  162. | ElementList COMMA Expr { $1.push($3); $$ = $1 }
  163. ;
  164.  
  165. MemberExpr
  166. : MemberExpr PROP Identifier { $$ = new yy.Expr.DotAccessorRefExpr($1, $3, @$) }
  167. | MemberExpr LBRA Expr RBRA { $$ = new yy.Expr.SquareAccessorRefExpr($1, $3, @$) }
  168. | PrimaryComnon { $$ = $1 }
  169. ;
  170.  
  171. CallExpr
  172. : MemberExpr Arguments { $$ = new yy.Expr.CallValueExpr($1, $2, @$) }
  173. | CallExpr Arguments { $$ = new yy.Expr.CallValueExpr($1, $2, @$) }
  174. | CallExpr PROP Identifier { $$ = new yy.Expr.DotAccessorRefExpr($1, $3, @$) }
  175. | CallExpr LBRA Expr RBRA { $$ = new yy.Expr.SquareAccessorRefExpr($1, $3, @$) }
  176. ;
  177.  
  178. Arguments
  179. : LPAR RPAR { $$ = [] }
  180. | LPAR ElementList RPAR { $$ = $2 }
  181. ;
  182.  
  183. PrimaryExpr
  184. : CallExpr { $$ = $1 }
  185. | MemberExpr { $$ = $1 }
  186. ;
  187.  
  188. UnaryExpr
  189. : PLUS UnaryExpr { $$ = new yy.Expr.UnaryPlusMinusValueExpr(yy.Operator.PLUS, $2, @$) }
  190. | MINUS UnaryExpr { $$ = new yy.Expr.UnaryPlusMinusValueExpr(yy.Operator.MINUS, $2, @$) }
  191. | NOT UnaryExpr { $$ = new yy.Expr.UnaryNotValueExpr($2, @$) }
  192. | PrimaryExpr { $$ = $1 }
  193. ;
  194.  
  195. BinaryExpr
  196. : BinaryExpr MUL BinaryExpr { $$ = new yy.Expr.BinaryValueExpr(yy.Operator.MUL, $1, $3, @$) }
  197. | BinaryExpr DIV BinaryExpr { $$ = new yy.Expr.BinaryValueExpr(yy.Operator.DIV, $1, $3, @$) }
  198. | BinaryExpr MOD BinaryExpr { $$ = new yy.Expr.BinaryValueExpr(yy.Operator.MOD, $1, $3, @$) }
  199.  
  200. | BinaryExpr PLUS BinaryExpr { $$ = new yy.Expr.BinaryValueExpr(yy.Operator.PLUS, $1, $3, @$) }
  201. | BinaryExpr MINUS BinaryExpr { $$ = new yy.Expr.BinaryValueExpr(yy.Operator.MINUS, $1, $3, @$) }
  202.  
  203. | BinaryExpr LT BinaryExpr { $$ = new yy.Expr.BinaryValueExpr(yy.Operator.LT, $1, $3, @$) }
  204. | BinaryExpr LE BinaryExpr { $$ = new yy.Expr.BinaryValueExpr(yy.Operator.LE, $1, $3, @$) }
  205. | BinaryExpr GE BinaryExpr { $$ = new yy.Expr.BinaryValueExpr(yy.Operator.GE, $1, $3, @$) }
  206. | BinaryExpr GT BinaryExpr { $$ = new yy.Expr.BinaryValueExpr(yy.Operator.GT, $1, $3, @$) }
  207.  
  208. | BinaryExpr EQ BinaryExpr { $$ = new yy.Expr.BinaryValueExpr(yy.Operator.EQ, $1, $3, @$) }
  209. | BinaryExpr NE BinaryExpr { $$ = new yy.Expr.BinaryValueExpr(yy.Operator.NE, $1, $3, @$) }
  210.  
  211. | BinaryExpr AND BinaryExpr { $$ = new yy.Expr.BinaryValueExpr(yy.Operator.AND, $1, $3, @$) }
  212. | BinaryExpr OR BinaryExpr { $$ = new yy.Expr.BinaryValueExpr(yy.Operator.OR, $1, $3, @$) }
  213. | UnaryExpr { $$ = $1 }
  214. ;
  215.  
  216. Expr
  217. : PrimaryExpr ASSIGN Expr {
  218. if ($1 instanceof yy.Expr.VariableRefExpr
  219. || $1 instanceof yy.Expr.DotAccessorRefExpr
  220. || $1 instanceof yy.Expr.SquareAccessorRefExpr) {
  221. $$ = new yy.Expr.AssignmentValueExpr($1, $3, @$)
  222. } else {
  223. // TODO: Update this when working on error reporting.
  224. throw new Error('TODO: Cannot assign to non-lvalue type.')
  225. YYABORT;
  226. }
  227. }
  228. | BinaryExpr { $$ = $1 }
  229. ;
  230.  
  231. Statement
  232. : Block { $$ = $1 }
  233. | Expr SEMICOLON { $$ = new yy.Stmt.ExprStmt($1, @$) }
  234. | FunctionDeclaration { $$ = $1 }
  235. | /* Empty statement */ SEMICOLON
  236. { $$ = new yy.Stmt.EmptyStmt(@$) }
  237. | IfStatement { $$ = $1 }
  238. | IterationStatement { $$ = $1 }
  239. | ReturnStatement SEMICOLON { $$ = $1 }
  240. | ContinueStatement SEMICOLON { $$ = $1 }
  241. | BreakStatement SEMICOLON { $$ = $1 }
  242. ;
  243.  
  244. Block
  245. : LCURLY RCURLY { $$ = new yy.Stmt.BlockStmt([], @$) }
  246. | LCURLY StatementList RCURLY { $$ = new yy.Stmt.BlockStmt($2, @$) }
  247. ;
  248.  
  249. StatementList
  250. : Statement { $$ = [$1] }
  251. | StatementList Statement { $1.push($2); $$ = $1 }
  252. ;
  253.  
  254. FunctionDeclaration
  255. : FUNCTION Identifier Parameters Block
  256. { $$ = new yy.Stmt.FunctionDeclStmt($2, $3, $4, @$) }
  257. ;
  258.  
  259. Parameters
  260. : LPAR IdentifierList RPAR { $$ = $2 }
  261. | LPAR RPAR { $$ = [] }
  262. ;
  263.  
  264. IdentifierList
  265. : Identifier { $$ = [$1] }
  266. | IdentifierList COMMA Identifier
  267. { $1.push($3); $$ = $1 }
  268. ;
  269.  
  270. IfStatement
  271. : IF LPAR Expr RPAR Statement %prec IF_WITHOUT_ELSE
  272. { $$ = new yy.Stmt.IfStmt($3, $5, null, @$) }
  273. | IF LPAR Expr RPAR Statement ELSE Statement
  274. { $$ = new yy.Stmt.IfStmt($3, $5, $7, @$) }
  275. ;
  276.  
  277. IterationStatement
  278. : WHILE LPAR Expr RPAR Statement
  279. { $$ = new yy.Stmt.WhileStmt($3, $5, @$) }
  280. | FOR LPAR
  281. ExprListOptional SEMICOLON
  282. ExprOptional SEMICOLON
  283. ExprListOptional
  284. RPAR Statement { $$ = new yy.Stmt.ForStmt($3, $5, $7, $9, @$) }
  285. ;
  286.  
  287. ExprOptional
  288. : Expr { $$ = $1 }
  289. | %epsilon { $$ = null }
  290. ;
  291.  
  292. ExprList
  293. : ExprList COMMA Expr { $1.push($3); $$ = $1 }
  294. | Expr { $$ = [$1] }
  295. ;
  296.  
  297. ExprListOptional
  298. : ExprList { $$ = $1 }
  299. | %epsilon { $$ = [] }
  300. ;
  301.  
  302. ReturnStatement
  303. : RETURN { $$ = new yy.Stmt.CompletionStmt(yy.CompletionType.RETURN, null, @$) }
  304. | RETURN Expr { $$ = new yy.Stmt.CompletionStmt(yy.CompletionType.RETURN, $2, @$) }
  305. ;
  306.  
  307. ContinueStatement
  308. : CONTINUE { $$ = new yy.Stmt.CompletionStmt(yy.CompletionType.CONTINUE, null, @$) }
  309. ;
  310.  
  311. BreakStatement
  312. : BREAK { $$ = new yy.Stmt.CompletionStmt(yy.CompletionType.BREAK, null, @$) }
  313. ;
  314.  
  315. ClassDefinition
  316. : CLASS Identifier ClassBlock { $$ = new yy.Stmt.ClassDefStmt($2, null, $3, @$) }
  317. | CLASS Identifier LPAR Identifier RPAR ClassBlock
  318. { $$ = new yy.Stmt.ClassDefStmt($2, $4, $6, @$) }
  319. ;
  320.  
  321. ClassBlock
  322. : LCURLY RCURLY { $$ = [] }
  323. | LCURLY InClassStatementList RCURLY
  324. { $$ = $2 }
  325. ;
  326.  
  327. InClassStatementList
  328. : InClassStatementList InClassStatement
  329. { $$ = $1.concat($2) }
  330. | InClassStatement
  331. { $$ = [$1] }
  332. ;
  333.  
  334. InClassStatement
  335. : FunctionDeclaration { $$ = $1 }
  336. ;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement