PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/kdelibs-3.5.10/kjs/grammar.y

#
Happy | 699 lines | 606 code | 93 blank | 0 comment | 0 complexity | a5028cd6e905262a424653abc7a650b0 MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, AGPL-1.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0
  1. %{
  2. /*
  3. * This file is part of the KDE libraries
  4. * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. *
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #include "value.h"
  27. #include "object.h"
  28. #include "types.h"
  29. #include "interpreter.h"
  30. #include "nodes.h"
  31. #include "lexer.h"
  32. #include "internal.h"
  33. /* default values for bison */
  34. #define YYDEBUG 0
  35. #ifdef YYMAXDEPTH
  36. #undef YYMAXDEPTH
  37. #endif
  38. #define YYERROR_VERBOSE
  39. #define DBG(l, s, e) { l->setLoc(s.first_line, e.last_line, Parser::source); } // location
  40. extern int yylex();
  41. static int yyerror (const char *);
  42. static bool automatic();
  43. using namespace KJS;
  44. %}
  45. %union {
  46. int ival;
  47. double dval;
  48. UString *ustr;
  49. Identifier *ident;
  50. Node *node;
  51. StatementNode *stat;
  52. ParameterNode *param;
  53. FunctionBodyNode *body;
  54. FuncDeclNode *func;
  55. FunctionBodyNode *prog;
  56. AssignExprNode *init;
  57. SourceElementsNode *srcs;
  58. StatListNode *slist;
  59. ArgumentsNode *args;
  60. ArgumentListNode *alist;
  61. VarDeclNode *decl;
  62. VarDeclListNode *vlist;
  63. CaseBlockNode *cblk;
  64. ClauseListNode *clist;
  65. CaseClauseNode *ccl;
  66. ElementNode *elm;
  67. Operator op;
  68. PropertyValueNode *plist;
  69. PropertyNode *pnode;
  70. CatchNode *cnode;
  71. FinallyNode *fnode;
  72. }
  73. %start Program
  74. /* expect a shift/reduce conflict from the "dangling else" problem
  75. when using bison the warning can be supressed */
  76. // %expect 1
  77. /* literals */
  78. %token NULLTOKEN TRUETOKEN FALSETOKEN
  79. %token STRING NUMBER
  80. /* keywords */
  81. %token BREAK CASE DEFAULT FOR NEW VAR CONST CONTINUE
  82. %token FUNCTION RETURN VOID DELETE
  83. %token IF THIS DO WHILE ELSE IN INSTANCEOF TYPEOF
  84. %token SWITCH WITH RESERVED
  85. %token THROW TRY CATCH FINALLY
  86. %token DEBUGGER
  87. /* punctuators */
  88. %token EQEQ NE /* == and != */
  89. %token STREQ STRNEQ /* === and !== */
  90. %token LE GE /* < and > */
  91. %token OR AND /* || and && */
  92. %token PLUSPLUS MINUSMINUS /* ++ and -- */
  93. %token LSHIFT /* << */
  94. %token RSHIFT URSHIFT /* >> and >>> */
  95. %token PLUSEQUAL MINUSEQUAL /* += and -= */
  96. %token MULTEQUAL DIVEQUAL /* *= and /= */
  97. %token LSHIFTEQUAL /* <<= */
  98. %token RSHIFTEQUAL URSHIFTEQUAL /* >>= and >>>= */
  99. %token ANDEQUAL MODEQUAL /* &= and %= */
  100. %token XOREQUAL OREQUAL /* ^= and |= */
  101. /* terminal types */
  102. %token <dval> NUMBER
  103. %token <ustr> STRING
  104. %token <ident> IDENT FUNCEXPRIDENT
  105. /* automatically inserted semicolon */
  106. %token AUTOPLUSPLUS AUTOMINUSMINUS
  107. /* non-terminal types */
  108. %type <node> Literal PrimaryExpr Expr MemberExpr FunctionExpr NewExpr CallExpr
  109. %type <node> ArrayLiteral
  110. %type <node> LeftHandSideExpr PostfixExpr UnaryExpr
  111. %type <node> MultiplicativeExpr AdditiveExpr
  112. %type <node> ShiftExpr RelationalExpr EqualityExpr
  113. %type <node> BitwiseANDExpr BitwiseXORExpr BitwiseORExpr
  114. %type <node> LogicalANDExpr LogicalORExpr
  115. %type <node> ConditionalExpr AssignmentExpr
  116. %type <node> ExprOpt
  117. %type <cnode> Catch
  118. %type <fnode> Finally
  119. %type <stat> Statement Block
  120. %type <stat> VariableStatement ConstStatement EmptyStatement ExprStatement
  121. %type <stat> IfStatement IterationStatement ContinueStatement
  122. %type <stat> BreakStatement ReturnStatement WithStatement
  123. %type <stat> SwitchStatement LabelledStatement
  124. %type <stat> ThrowStatement TryStatement
  125. %type <stat> DebuggerStatement
  126. %type <stat> SourceElement
  127. %type <slist> StatementList
  128. %type <init> Initializer
  129. %type <func> FunctionDeclarationInternal
  130. %type <func> FunctionDeclaration
  131. %type <body> FunctionBody
  132. %type <srcs> SourceElements
  133. %type <param> FormalParameterList
  134. %type <op> AssignmentOperator
  135. %type <prog> Program
  136. %type <args> Arguments
  137. %type <alist> ArgumentList
  138. %type <vlist> VariableDeclarationList ConstDeclarationList
  139. %type <decl> VariableDeclaration ConstDeclaration
  140. %type <cblk> CaseBlock
  141. %type <ccl> CaseClause DefaultClause
  142. %type <clist> CaseClauses CaseClausesOpt
  143. %type <ival> Elision ElisionOpt
  144. %type <elm> ElementList
  145. %type <plist> PropertyNameAndValueList
  146. %type <pnode> PropertyName
  147. %%
  148. Literal:
  149. NULLTOKEN { $$ = new NullNode(); }
  150. | TRUETOKEN { $$ = new BooleanNode(true); }
  151. | FALSETOKEN { $$ = new BooleanNode(false); }
  152. | NUMBER { $$ = new NumberNode($1); }
  153. | STRING { $$ = new StringNode($1); }
  154. | '/' /* a RegExp ? */ { Lexer *l = Lexer::curr();
  155. if (!l->scanRegExp()) YYABORT;
  156. $$ = new RegExpNode(l->pattern,l->flags);}
  157. | DIVEQUAL /* a RegExp starting with /= ! */
  158. { Lexer *l = Lexer::curr();
  159. if (!l->scanRegExp()) YYABORT;
  160. $$ = new RegExpNode(UString('=')+l->pattern,l->flags);}
  161. ;
  162. PrimaryExpr:
  163. THIS { $$ = new ThisNode(); }
  164. | IDENT { $$ = new ResolveNode(*$1); }
  165. | Literal
  166. | ArrayLiteral
  167. | '(' Expr ')' { $$ = new GroupNode($2); }
  168. | '{' '}' { $$ = new ObjectLiteralNode(); }
  169. | '{' PropertyNameAndValueList '}' { $$ = new ObjectLiteralNode($2); }
  170. | '{' PropertyNameAndValueList ',' '}' { $$ = new ObjectLiteralNode($2); }
  171. ;
  172. ArrayLiteral:
  173. '[' ElisionOpt ']' { $$ = new ArrayNode($2); }
  174. | '[' ElementList ']' { $$ = new ArrayNode($2); }
  175. | '[' ElementList ',' ElisionOpt ']' { $$ = new ArrayNode($4, $2); }
  176. ;
  177. ElementList:
  178. ElisionOpt AssignmentExpr { $$ = new ElementNode($1, $2); }
  179. | ElementList ',' ElisionOpt AssignmentExpr
  180. { $$ = new ElementNode($1, $3, $4); }
  181. ;
  182. ElisionOpt:
  183. /* nothing */ { $$ = 0; }
  184. | Elision
  185. ;
  186. Elision:
  187. ',' { $$ = 1; }
  188. | Elision ',' { $$ = $1 + 1; }
  189. ;
  190. PropertyNameAndValueList:
  191. PropertyName ':' AssignmentExpr { $$ = new PropertyValueNode($1, $3); }
  192. | PropertyNameAndValueList ',' PropertyName ':' AssignmentExpr
  193. { $$ = new PropertyValueNode($3, $5, $1); }
  194. ;
  195. PropertyName:
  196. IDENT { $$ = new PropertyNode(*$1); }
  197. | STRING { $$ = new PropertyNode(Identifier(*$1)); }
  198. | NUMBER { $$ = new PropertyNode($1); }
  199. ;
  200. MemberExpr:
  201. PrimaryExpr
  202. | FunctionExpr
  203. | MemberExpr '[' Expr ']' { $$ = new AccessorNode1($1, $3); }
  204. | MemberExpr '.' IDENT { $$ = new AccessorNode2($1, *$3); }
  205. | NEW MemberExpr Arguments { $$ = new NewExprNode($2, $3); }
  206. ;
  207. NewExpr:
  208. MemberExpr
  209. | NEW NewExpr { $$ = new NewExprNode($2); }
  210. ;
  211. CallExpr:
  212. MemberExpr Arguments { $$ = new FunctionCallNode($1, $2); }
  213. | CallExpr Arguments { $$ = new FunctionCallNode($1, $2); }
  214. | CallExpr '[' Expr ']' { $$ = new AccessorNode1($1, $3); }
  215. | CallExpr '.' IDENT { $$ = new AccessorNode2($1, *$3); }
  216. ;
  217. Arguments:
  218. '(' ')' { $$ = new ArgumentsNode(); }
  219. | '(' ArgumentList ')' { $$ = new ArgumentsNode($2); }
  220. ;
  221. ArgumentList:
  222. AssignmentExpr { $$ = new ArgumentListNode($1); }
  223. | ArgumentList ',' AssignmentExpr { $$ = new ArgumentListNode($1, $3); }
  224. ;
  225. LeftHandSideExpr:
  226. NewExpr
  227. | CallExpr
  228. ;
  229. PostfixExpr: /* TODO: no line terminator here */
  230. LeftHandSideExpr
  231. | LeftHandSideExpr PLUSPLUS { $$ = new PostfixNode($1, OpPlusPlus); }
  232. | LeftHandSideExpr MINUSMINUS { $$ = new PostfixNode($1, OpMinusMinus); }
  233. ;
  234. UnaryExpr:
  235. PostfixExpr
  236. | DELETE UnaryExpr { $$ = new DeleteNode($2); }
  237. | VOID UnaryExpr { $$ = new VoidNode($2); }
  238. | TYPEOF UnaryExpr { $$ = new TypeOfNode($2); }
  239. | PLUSPLUS UnaryExpr { $$ = new PrefixNode(OpPlusPlus, $2); }
  240. | AUTOPLUSPLUS UnaryExpr { $$ = new PrefixNode(OpPlusPlus, $2); }
  241. | MINUSMINUS UnaryExpr { $$ = new PrefixNode(OpMinusMinus, $2); }
  242. | AUTOMINUSMINUS UnaryExpr { $$ = new PrefixNode(OpMinusMinus, $2); }
  243. | '+' UnaryExpr { $$ = new UnaryPlusNode($2); }
  244. | '-' UnaryExpr { $$ = new NegateNode($2); }
  245. | '~' UnaryExpr { $$ = new BitwiseNotNode($2); }
  246. | '!' UnaryExpr { $$ = new LogicalNotNode($2); }
  247. ;
  248. MultiplicativeExpr:
  249. UnaryExpr
  250. | MultiplicativeExpr '*' UnaryExpr { $$ = new MultNode($1, $3, '*'); }
  251. | MultiplicativeExpr '/' UnaryExpr { $$ = new MultNode($1, $3, '/'); }
  252. | MultiplicativeExpr '%' UnaryExpr { $$ = new MultNode($1,$3,'%'); }
  253. ;
  254. AdditiveExpr:
  255. MultiplicativeExpr
  256. | AdditiveExpr '+' MultiplicativeExpr { $$ = AddNode::create($1, $3, '+'); }
  257. | AdditiveExpr '-' MultiplicativeExpr { $$ = AddNode::create($1, $3, '-'); }
  258. ;
  259. ShiftExpr:
  260. AdditiveExpr
  261. | ShiftExpr LSHIFT AdditiveExpr { $$ = new ShiftNode($1, OpLShift, $3); }
  262. | ShiftExpr RSHIFT AdditiveExpr { $$ = new ShiftNode($1, OpRShift, $3); }
  263. | ShiftExpr URSHIFT AdditiveExpr { $$ = new ShiftNode($1, OpURShift, $3); }
  264. ;
  265. RelationalExpr:
  266. ShiftExpr
  267. | RelationalExpr '<' ShiftExpr
  268. { $$ = new RelationalNode($1, OpLess, $3); }
  269. | RelationalExpr '>' ShiftExpr
  270. { $$ = new RelationalNode($1, OpGreater, $3); }
  271. | RelationalExpr LE ShiftExpr
  272. { $$ = new RelationalNode($1, OpLessEq, $3); }
  273. | RelationalExpr GE ShiftExpr
  274. { $$ = new RelationalNode($1, OpGreaterEq, $3); }
  275. | RelationalExpr INSTANCEOF ShiftExpr
  276. { $$ = new RelationalNode($1, OpInstanceOf, $3); }
  277. | RelationalExpr IN ShiftExpr
  278. { $$ = new RelationalNode($1, OpIn, $3); }
  279. ;
  280. EqualityExpr:
  281. RelationalExpr
  282. | EqualityExpr EQEQ RelationalExpr { $$ = new EqualNode($1, OpEqEq, $3); }
  283. | EqualityExpr NE RelationalExpr { $$ = new EqualNode($1, OpNotEq, $3); }
  284. | EqualityExpr STREQ RelationalExpr { $$ = new EqualNode($1, OpStrEq, $3); }
  285. | EqualityExpr STRNEQ RelationalExpr { $$ = new EqualNode($1, OpStrNEq, $3);}
  286. ;
  287. BitwiseANDExpr:
  288. EqualityExpr
  289. | BitwiseANDExpr '&' EqualityExpr { $$ = new BitOperNode($1, OpBitAnd, $3); }
  290. ;
  291. BitwiseXORExpr:
  292. BitwiseANDExpr
  293. | BitwiseXORExpr '^' BitwiseANDExpr { $$ = new BitOperNode($1, OpBitXOr, $3); }
  294. ;
  295. BitwiseORExpr:
  296. BitwiseXORExpr
  297. | BitwiseORExpr '|' BitwiseXORExpr { $$ = new BitOperNode($1, OpBitOr, $3); }
  298. ;
  299. LogicalANDExpr:
  300. BitwiseORExpr
  301. | LogicalANDExpr AND BitwiseORExpr
  302. { $$ = new BinaryLogicalNode($1, OpAnd, $3); }
  303. ;
  304. LogicalORExpr:
  305. LogicalANDExpr
  306. | LogicalORExpr OR LogicalANDExpr
  307. { $$ = new BinaryLogicalNode($1, OpOr, $3); }
  308. ;
  309. ConditionalExpr:
  310. LogicalORExpr
  311. | LogicalORExpr '?' AssignmentExpr ':' AssignmentExpr
  312. { $$ = new ConditionalNode($1, $3, $5); }
  313. ;
  314. AssignmentExpr:
  315. ConditionalExpr
  316. | LeftHandSideExpr AssignmentOperator AssignmentExpr
  317. { $$ = new AssignNode($1, $2, $3);}
  318. ;
  319. AssignmentOperator:
  320. '=' { $$ = OpEqual; }
  321. | PLUSEQUAL { $$ = OpPlusEq; }
  322. | MINUSEQUAL { $$ = OpMinusEq; }
  323. | MULTEQUAL { $$ = OpMultEq; }
  324. | DIVEQUAL { $$ = OpDivEq; }
  325. | LSHIFTEQUAL { $$ = OpLShift; }
  326. | RSHIFTEQUAL { $$ = OpRShift; }
  327. | URSHIFTEQUAL { $$ = OpURShift; }
  328. | ANDEQUAL { $$ = OpAndEq; }
  329. | XOREQUAL { $$ = OpXOrEq; }
  330. | OREQUAL { $$ = OpOrEq; }
  331. | MODEQUAL { $$ = OpModEq; }
  332. ;
  333. Expr:
  334. AssignmentExpr
  335. | Expr ',' AssignmentExpr { $$ = new CommaNode($1, $3); }
  336. ;
  337. Statement:
  338. Block
  339. | VariableStatement
  340. | ConstStatement
  341. | EmptyStatement
  342. | ExprStatement
  343. | IfStatement
  344. | IterationStatement
  345. | ContinueStatement
  346. | BreakStatement
  347. | ReturnStatement
  348. | WithStatement
  349. | SwitchStatement
  350. | LabelledStatement
  351. | ThrowStatement
  352. | TryStatement
  353. | DebuggerStatement
  354. ;
  355. Block:
  356. '{' '}' { $$ = new BlockNode(0); DBG($$, @2, @2); }
  357. | '{' SourceElements '}' { $$ = new BlockNode($2); DBG($$, @3, @3); }
  358. ;
  359. StatementList:
  360. Statement { $$ = new StatListNode($1); }
  361. | StatementList Statement { $$ = new StatListNode($1, $2); }
  362. ;
  363. VariableStatement:
  364. VAR VariableDeclarationList ';' { $$ = new VarStatementNode($2);
  365. DBG($$, @1, @3); }
  366. | VAR VariableDeclarationList error { if (automatic()) {
  367. $$ = new VarStatementNode($2);
  368. DBG($$, @1, @2);
  369. } else {
  370. YYABORT;
  371. }
  372. }
  373. ;
  374. VariableDeclarationList:
  375. VariableDeclaration { $$ = new VarDeclListNode($1); }
  376. | VariableDeclarationList ',' VariableDeclaration
  377. { $$ = new VarDeclListNode($1, $3); }
  378. ;
  379. VariableDeclaration:
  380. IDENT { $$ = new VarDeclNode(*$1, 0, VarDeclNode::Variable); }
  381. | IDENT Initializer { $$ = new VarDeclNode(*$1, $2, VarDeclNode::Variable); }
  382. ;
  383. ConstStatement:
  384. CONST ConstDeclarationList ';' { $$ = new VarStatementNode($2);
  385. DBG($$, @1, @3); }
  386. | CONST ConstDeclarationList error { if (automatic()) {
  387. $$ = new VarStatementNode($2);
  388. DBG($$, @1, @2);
  389. } else {
  390. YYABORT;
  391. }
  392. }
  393. ;
  394. ConstDeclarationList:
  395. ConstDeclaration { $$ = new VarDeclListNode($1); }
  396. | ConstDeclarationList ',' VariableDeclaration
  397. { $$ = new VarDeclListNode($1, $3); }
  398. ;
  399. ConstDeclaration:
  400. IDENT { $$ = new VarDeclNode(*$1, 0, VarDeclNode::Constant); }
  401. | IDENT Initializer { $$ = new VarDeclNode(*$1, $2, VarDeclNode::Constant); }
  402. ;
  403. Initializer:
  404. '=' AssignmentExpr { $$ = new AssignExprNode($2); }
  405. ;
  406. EmptyStatement:
  407. ';' { $$ = new EmptyStatementNode(); DBG($$, @1, @1); }
  408. ;
  409. ExprStatement:
  410. Expr ';' { $$ = new ExprStatementNode($1);
  411. DBG($$, @1, @2); }
  412. | Expr error { if (automatic()) {
  413. $$ = new ExprStatementNode($1);
  414. DBG($$, @1, @1);
  415. } else
  416. YYABORT; }
  417. ;
  418. IfStatement: /* shift/reduce conflict due to dangling else */
  419. IF '(' Expr ')' Statement { $$ = new IfNode($3,$5,0);DBG($$,@1,@4); }
  420. | IF '(' Expr ')' Statement ELSE Statement
  421. { $$ = new IfNode($3,$5,$7);DBG($$,@1,@4); }
  422. ;
  423. IterationStatement:
  424. DO Statement WHILE '(' Expr ')' { $$=new DoWhileNode($2,$5);DBG($$,@1,@3);}
  425. | WHILE '(' Expr ')' Statement { $$ = new WhileNode($3,$5);DBG($$,@1,@4); }
  426. | FOR '(' ExprOpt ';' ExprOpt ';' ExprOpt ')'
  427. Statement { $$ = new ForNode($3,$5,$7,$9);
  428. DBG($$,@1,@8); }
  429. | FOR '(' VAR VariableDeclarationList ';' ExprOpt ';' ExprOpt ')'
  430. Statement { $$ = new ForNode($4,$6,$8,$10);
  431. DBG($$,@1,@9); }
  432. | FOR '(' LeftHandSideExpr IN Expr ')'
  433. Statement { $$ = new ForInNode($3, $5, $7);
  434. DBG($$,@1,@6); }
  435. | FOR '(' VAR IDENT IN Expr ')'
  436. Statement { $$ = new ForInNode(*$4,0,$6,$8);
  437. DBG($$,@1,@7); }
  438. | FOR '(' VAR IDENT Initializer IN Expr ')'
  439. Statement { $$ = new ForInNode(*$4,$5,$7,$9);
  440. DBG($$,@1,@8); }
  441. ;
  442. ExprOpt:
  443. /* nothing */ { $$ = 0; }
  444. | Expr
  445. ;
  446. ContinueStatement:
  447. CONTINUE ';' { $$ = new ContinueNode(); DBG($$,@1,@2); }
  448. | CONTINUE error { if (automatic()) {
  449. $$ = new ContinueNode(); DBG($$,@1,@2);
  450. } else
  451. YYABORT; }
  452. | CONTINUE IDENT ';' { $$ = new ContinueNode(*$2); DBG($$,@1,@3); }
  453. | CONTINUE IDENT error { if (automatic()) {
  454. $$ = new ContinueNode(*$2);DBG($$,@1,@2);
  455. } else
  456. YYABORT; }
  457. ;
  458. BreakStatement:
  459. BREAK ';' { $$ = new BreakNode();DBG($$,@1,@2); }
  460. | BREAK error { if (automatic()) {
  461. $$ = new BreakNode(); DBG($$,@1,@1);
  462. } else
  463. YYABORT; }
  464. | BREAK IDENT ';' { $$ = new BreakNode(*$2); DBG($$,@1,@3); }
  465. | BREAK IDENT error { if (automatic()) {
  466. $$ = new BreakNode(*$2); DBG($$,@1,@2);
  467. } else
  468. YYABORT;
  469. }
  470. ;
  471. ReturnStatement:
  472. RETURN ';' { $$ = new ReturnNode(0); DBG($$,@1,@2); }
  473. | RETURN error { if (automatic()) {
  474. $$ = new ReturnNode(0); DBG($$,@1,@1);
  475. } else
  476. YYABORT; }
  477. | RETURN Expr ';' { $$ = new ReturnNode($2); DBG($$,@1,@3); }
  478. | RETURN Expr error { if (automatic()) {
  479. $$ = new ReturnNode($2); DBG($$,@1,@1);
  480. }
  481. else
  482. YYABORT; }
  483. ;
  484. WithStatement:
  485. WITH '(' Expr ')' Statement { $$ = new WithNode($3,$5);
  486. DBG($$, @1, @4); }
  487. ;
  488. SwitchStatement:
  489. SWITCH '(' Expr ')' CaseBlock { $$ = new SwitchNode($3, $5);
  490. DBG($$, @1, @4); }
  491. ;
  492. CaseBlock:
  493. '{' CaseClausesOpt '}' { $$ = new CaseBlockNode($2, 0, 0); }
  494. | '{' CaseClausesOpt DefaultClause CaseClausesOpt '}'
  495. { $$ = new CaseBlockNode($2, $3, $4); }
  496. ;
  497. CaseClausesOpt:
  498. /* nothing */ { $$ = 0; }
  499. | CaseClauses
  500. ;
  501. CaseClauses:
  502. CaseClause { $$ = new ClauseListNode($1); }
  503. | CaseClauses CaseClause { $$ = new ClauseListNode($1, $2); }
  504. ;
  505. CaseClause:
  506. CASE Expr ':' { $$ = new CaseClauseNode($2); }
  507. | CASE Expr ':' StatementList { $$ = new CaseClauseNode($2, $4); }
  508. ;
  509. DefaultClause:
  510. DEFAULT ':' { $$ = new CaseClauseNode(0); }
  511. | DEFAULT ':' StatementList { $$ = new CaseClauseNode(0, $3); }
  512. ;
  513. LabelledStatement:
  514. IDENT ':' Statement { $3->pushLabel(*$1);
  515. $$ = new LabelNode(*$1, $3); DBG($$,@1,@2); }
  516. ;
  517. ThrowStatement:
  518. THROW Expr ';' { $$ = new ThrowNode($2); DBG($$,@1,@3); }
  519. | THROW Expr error { if (automatic()) {
  520. $$ = new ThrowNode($2); DBG($$,@1,@1);
  521. } else {
  522. YYABORT; } }
  523. ;
  524. TryStatement:
  525. TRY Block Catch { $$ = new TryNode($2, $3); DBG($$,@1,@1); }
  526. | TRY Block Finally { $$ = new TryNode($2, $3); DBG($$,@1,@1); }
  527. | TRY Block Catch Finally { $$ = new TryNode($2, $3, $4); DBG($$,@1,@1); }
  528. ;
  529. DebuggerStatement:
  530. DEBUGGER ';' { $$ = new EmptyStatementNode(); DBG($$, @1, @2); }
  531. | DEBUGGER error { if (automatic()) {
  532. $$ = new EmptyStatementNode();
  533. DBG($$, @1, @1);
  534. } else {
  535. YYABORT; } }
  536. ;
  537. Catch:
  538. CATCH '(' IDENT ')' Block { CatchNode *c; $$ = c = new CatchNode(*$3, $5);
  539. DBG(c,@1,@4); }
  540. ;
  541. Finally:
  542. FINALLY Block { FinallyNode *f; $$ = f = new FinallyNode($2); DBG(f,@1,@1); }
  543. ;
  544. FunctionDeclaration:
  545. FunctionDeclarationInternal
  546. /* Hack for IE/NS4 compatibility */
  547. | VOID FunctionDeclarationInternal { $$ = $2; }
  548. ;
  549. FunctionDeclarationInternal:
  550. FUNCTION IDENT '(' ')' FunctionBody { $$ = new FuncDeclNode(*$2, $5); DBG($$,@1,@4); }
  551. | FUNCTION IDENT '(' FormalParameterList ')' FunctionBody
  552. { $$ = new FuncDeclNode(*$2, $4, $6); DBG($$,@1,@5); }
  553. ;
  554. FunctionExpr:
  555. FUNCTION '(' ')' FunctionBody
  556. { $$ = new FuncExprNode(Identifier::null(), $4); }
  557. | FUNCTION '(' FormalParameterList ')' FunctionBody
  558. { $$ = new FuncExprNode(Identifier::null(), $3, $5); }
  559. | FUNCTION FUNCEXPRIDENT '(' ')' FunctionBody
  560. { $$ = new FuncExprNode(*$2, $5); }
  561. | FUNCTION FUNCEXPRIDENT '(' FormalParameterList ')' FunctionBody
  562. { $$ = new FuncExprNode(*$2, $4, $6); }
  563. ;
  564. FormalParameterList:
  565. IDENT { $$ = new ParameterNode(*$1); }
  566. | FormalParameterList ',' IDENT { $$ = new ParameterNode($1, *$3); }
  567. ;
  568. FunctionBody:
  569. '{' '}' /* TODO: spec ??? */ { $$ = new FunctionBodyNode(0);
  570. DBG($$, @1, @2);}
  571. | '{' SourceElements '}' { $$ = new FunctionBodyNode($2);
  572. DBG($$, @1, @3);}
  573. ;
  574. Program:
  575. /* nothing, empty script */ { $$ = new FunctionBodyNode(0);
  576. $$->setLoc(0, 0, Parser::source);
  577. Parser::progNode = $$; }
  578. | SourceElements { $$ = new FunctionBodyNode($1);
  579. Parser::progNode = $$; }
  580. ;
  581. SourceElements:
  582. SourceElement { $$ = new SourceElementsNode($1); }
  583. | SourceElements SourceElement { $$ = new SourceElementsNode($1, $2); }
  584. ;
  585. SourceElement:
  586. Statement { $$ = $1; }
  587. | FunctionDeclaration { $$ = $1; }
  588. ;
  589. %%
  590. int yyerror (const char * /* s */) /* Called by yyparse on error */
  591. {
  592. // fprintf(stderr, "ERROR: %s at line %d\n",
  593. // s, KJS::Lexer::curr()->lineNo());
  594. return 1;
  595. }
  596. /* may we automatically insert a semicolon ? */
  597. bool automatic()
  598. {
  599. if (Lexer::curr()->hadError())
  600. return false;
  601. if (yychar == '}' || yychar == 0)
  602. return true;
  603. else if (Lexer::curr()->prevTerminator())
  604. return true;
  605. return false;
  606. }