%code {
+typedef cy::parser::token tk;
+
#undef yylex
_finline int yylex(cy::parser::semantic_type *semantic, CYLocation *location, CYDriver &driver) {
if (driver.mark_ == CYMarkIgnore);
return cy::parser::token::MarkModule;
}
+ lex:
+ if (driver.newline_ == CYDriver::NewLineHere)
+ driver.newline_ = CYDriver::NewLineLast;
+ else if (driver.newline_ == CYDriver::NewLineLast)
+ driver.newline_ = CYDriver::NewLineNone;
+
YYSTYPE data;
int token(cylex(&data, location, driver.scanner_));
*semantic = data.semantic_;
+
+ switch (token) {
+ case tk::_in_:
+ if (driver.in_.top())
+ token = tk::_in__;
+ break;
+
+ case tk::_return_:
+ if (driver.return_.top())
+ token = tk::_return__;
+ break;
+
+ case tk::_yield_:
+ if (driver.yield_.top())
+ token = tk::_yield__;
+ break;
+
+ case tk::HyphenHyphen:
+ if (driver.newline_ == CYDriver::NewLineLast)
+ token = tk::HyphenHyphen_;
+ break;
+
+ case tk::NewLine:
+ driver.newline_ = CYDriver::NewLineHere;
+ if (!driver.next_)
+ goto lex;
+ break;
+
+ case tk::PlusPlus:
+ if (driver.newline_ == CYDriver::NewLineLast)
+ token = tk::PlusPlus_;
+ break;
+ }
+
+ driver.next_ = false;
return token;
}
yyla.type = yytranslate_(token::to); \
} while (false)
+#define CYLIN(from) do { \
+ CYLEX(); \
+ if (yyla.type == yytranslate_(token::from) && driver.newline_ == CYDriver::NewLineLast) \
+ yyla.type = yytranslate_(token::from ## _); \
+} while (false)
+
#define CYERR(location, message) do { \
error(location, message); \
YYABORT; \
%token _import_ "import"
%token _in_ "in"
%token _in__ "!in"
+%token _Infinity_ "Infinity"
%token _instanceof_ "instanceof"
%token _new_ "new"
%token _return_ "return"
%token _return__ "!return"
%token _super_ "super"
-%token _super__ "!super"
%token _switch_ "switch"
+%token _target_ "target"
%token _this_ "this"
%token _throw_ "throw"
%token _try_ "try"
%type <element_> ElementList
%type <element_> ElementListOpt
%type <statement_> ElseStatementOpt
-%type <statement_> EmptyStatement
+%type <for_> EmptyStatement
%type <expression_> EqualityExpression
%type <expression_> Expression
%type <expression_> ExpressionOpt
+%type <for_> ExpressionStatement_
%type <statement_> ExpressionStatement
%type <finally_> Finally
%type <declaration_> ForBinding
%type <identifier_> LabelIdentifier
%type <statement_> LabelledItem
%type <statement_> LabelledStatement
+%type <assignment_> LeftHandSideAssignment
%type <target_> LeftHandSideExpression
%type <bool_> LetOrConst
%type <declaration_> LexicalBinding
+%type <for_> LexicalDeclaration_
%type <statement_> LexicalDeclaration
%type <literal_> Literal
%type <propertyName_> LiteralPropertyName
%type <declaration_> VariableDeclaration
%type <declarations_> VariableDeclarationList_
%type <declarations_> VariableDeclarationList
+%type <for_> VariableStatement_
%type <statement_> VariableStatement
%type <statement_> WithStatement
%type <word_> Word
@end
@begin ObjectiveC
+%type <expression_> AssignmentExpressionClassic
%type <expression_> BoxableExpression
%type <statement_> CategoryStatement
%type <expression_> ClassSuperOpt
+%type <expression_> ConditionalExpressionClassic
%type <implementationField_> ImplementationFieldListOpt
%type <implementationField_> ImplementationFields
%type <message_> ClassMessageDeclaration
| "return" { $$ = CYNew CYWord("return"); }
| "!return" { $$ = CYNew CYWord("return"); }
| "super" { $$ = CYNew CYWord("super"); }
- | "!super" { $$ = CYNew CYWord("super"); }
| "switch" { $$ = CYNew CYWord("switch"); }
| "this" { $$ = CYNew CYWord("this"); }
| "throw" { $$ = CYNew CYWord("throw"); }
Terminator
: ";"
- | error { if (yyla.type_get() != yyeof_ && yyla.type != yytranslate_(token::CloseBrace) && !driver.newline_) { CYERR(@1, "required semi-colon"); } else { yyerrok; driver.errors_.pop_back(); } } StrictSemi
+ | error { if (yyla.type_get() != yyeof_ && yyla.type != yytranslate_(token::CloseBrace) && driver.newline_ == CYDriver::NewLineNone) { CYERR(@1, "required semi-colon"); } else { yyerrok; driver.errors_.pop_back(); } } StrictSemi
;
TerminatorOpt
| "get" { $$ = CYNew CYIdentifier("get"); }
| "goto" { $$ = CYNew CYIdentifier("goto"); }
| "implements" { $$ = CYNew CYIdentifier("implements"); }
+ | "Infinity" { $$ = CYNew CYIdentifier("Infinity"); }
| "interface" { $$ = CYNew CYIdentifier("interface"); }
| "native" { $$ = CYNew CYIdentifier("native"); }
| "of" { $$ = CYNew CYIdentifier("of"); }
| "public" { $$ = CYNew CYIdentifier("public"); }
| "set" { $$ = CYNew CYIdentifier("set"); }
| "synchronized" { $$ = CYNew CYIdentifier("synchronized"); }
+ | "target" { $$ = CYNew CYIdentifier("target"); }
| "throws" { $$ = CYNew CYIdentifier("throws"); }
| "transient" { $$ = CYNew CYIdentifier("transient"); }
| "undefined" { $$ = CYNew CYIdentifier("undefined"); }
;
SuperProperty
- : LexSetRegExp "!super" "[" Expression "]" { $$ = CYNew CYSuperAccess($4); }
- | LexSetRegExp "!super" "." IdentifierName { $$ = CYNew CYSuperAccess(CYNew CYString($4)); }
+ : LexSetRegExp "super" { if (!driver.super_.top()) CYERR(@2, "invalid super"); } "[" Expression "]" { $$ = CYNew CYSuperAccess($5); }
+ | LexSetRegExp "super" { if (!driver.super_.top()) CYERR(@2, "invalid super"); } "." IdentifierName { $$ = CYNew CYSuperAccess(CYNew CYString($5)); }
;
MetaProperty
;
SuperCall
- : LexSetRegExp "!super" Arguments { $$ = CYNew CYSuperCall($3); }
+ : LexSetRegExp "super" { if (!driver.super_.top()) CYERR(@2, "invalid super"); } Arguments { $$ = CYNew CYSuperCall($4); }
;
Arguments
;
UnaryExpression
- : %prec "" PostfixExpression { $$ = $1; }
+ : %prec "" PostfixExpression LexOpenBrace { $$ = $1; }
| LexSetRegExp UnaryExpression_ { $$ = $2; }
;
/* }}} */
;
/* }}} */
/* 12.13 Conditional Operator ( ? : ) {{{ */
+@begin ObjectiveC
+ConditionalExpressionClassic
+ : LogicalORExpression { $$ = $1; }
+ | LogicalORExpression "?" LexPushInOff AssignmentExpression ":" LexPopIn AssignmentExpressionClassic { $$ = CYNew CYCondition($1, $4, $7); }
+ ;
+@end
+
ConditionalExpression
: LogicalORExpression { $$ = $1; }
| LogicalORExpression "?" LexPushInOff AssignmentExpression ":" LexPopIn AssignmentExpression { $$ = CYNew CYCondition($1, $4, $7); }
;
/* }}} */
/* 12.14 Assignment Operators {{{ */
+LeftHandSideAssignment
+ : LeftHandSideExpression "=" { $$ = CYNew CYAssign($1, NULL); }
+ | LeftHandSideExpression "*=" { $$ = CYNew CYMultiplyAssign($1, NULL); }
+ | LeftHandSideExpression "/=" { $$ = CYNew CYDivideAssign($1, NULL); }
+ | LeftHandSideExpression "%=" { $$ = CYNew CYModulusAssign($1, NULL); }
+ | LeftHandSideExpression "+=" { $$ = CYNew CYAddAssign($1, NULL); }
+ | LeftHandSideExpression "-=" { $$ = CYNew CYSubtractAssign($1, NULL); }
+ | LeftHandSideExpression "<<=" { $$ = CYNew CYShiftLeftAssign($1, NULL); }
+ | LeftHandSideExpression ">>=" { $$ = CYNew CYShiftRightSignedAssign($1, NULL); }
+ | LeftHandSideExpression ">>>=" { $$ = CYNew CYShiftRightUnsignedAssign($1, NULL); }
+ | LeftHandSideExpression "&=" { $$ = CYNew CYBitwiseAndAssign($1, NULL); }
+ | LeftHandSideExpression "^=" { $$ = CYNew CYBitwiseXOrAssign($1, NULL); }
+ | LeftHandSideExpression "|=" { $$ = CYNew CYBitwiseOrAssign($1, NULL); }
+ ;
+
+@begin ObjectiveC
+AssignmentExpressionClassic
+ : ConditionalExpressionClassic { $$ = $1; }
+ | LeftHandSideAssignment AssignmentExpressionClassic { $1->SetRight($2); $$ = $1; }
+ ;
+@end
+
AssignmentExpression
: ConditionalExpression { $$ = $1; }
| LexSetRegExp YieldExpression { $$ = $2; }
| ArrowFunction { $$ = $1; }
- | LeftHandSideExpression "=" AssignmentExpression { $$ = CYNew CYAssign($1, $3); }
- | LeftHandSideExpression "*=" AssignmentExpression { $$ = CYNew CYMultiplyAssign($1, $3); }
- | LeftHandSideExpression "/=" AssignmentExpression { $$ = CYNew CYDivideAssign($1, $3); }
- | LeftHandSideExpression "%=" AssignmentExpression { $$ = CYNew CYModulusAssign($1, $3); }
- | LeftHandSideExpression "+=" AssignmentExpression { $$ = CYNew CYAddAssign($1, $3); }
- | LeftHandSideExpression "-=" AssignmentExpression { $$ = CYNew CYSubtractAssign($1, $3); }
- | LeftHandSideExpression "<<=" AssignmentExpression { $$ = CYNew CYShiftLeftAssign($1, $3); }
- | LeftHandSideExpression ">>=" AssignmentExpression { $$ = CYNew CYShiftRightSignedAssign($1, $3); }
- | LeftHandSideExpression ">>>=" AssignmentExpression { $$ = CYNew CYShiftRightUnsignedAssign($1, $3); }
- | LeftHandSideExpression "&=" AssignmentExpression { $$ = CYNew CYBitwiseAndAssign($1, $3); }
- | LeftHandSideExpression "^=" AssignmentExpression { $$ = CYNew CYBitwiseXOrAssign($1, $3); }
- | LeftHandSideExpression "|=" AssignmentExpression { $$ = CYNew CYBitwiseOrAssign($1, $3); }
+ | LeftHandSideAssignment AssignmentExpression { $1->SetRight($2); $$ = $1; }
;
AssignmentExpressionOpt
;
/* }}} */
/* 13.3 Let and Const Declarations {{{ */
+LexicalDeclaration_
+ : LetOrConst BindingList { $$ = CYNew CYLet($1, $2); }
+ ;
+
LexicalDeclaration
- : LetOrConst BindingList Terminator { $$ = CYNew CYLet($1, $2); }
+ : LexicalDeclaration_ Terminator { $$ = $1; }
;
LetOrConst
;
/* }}} */
/* 13.3.2 Variable Statement {{{ */
+VariableStatement_
+ : Var_ VariableDeclarationList { $$ = CYNew CYVar($2); }
+ ;
+
VariableStatement
- : Var_ VariableDeclarationList Terminator { $$ = CYNew CYVar($2); }
+ : VariableStatement_ Terminator { $$ = $1; }
;
VariableDeclarationList_
;
/* }}} */
/* 13.5 Expression Statement {{{ */
+ExpressionStatement_
+ : Expression { $$ = CYNew CYExpress($1); }
+
ExpressionStatement
- : Expression Terminator { $$ = CYNew CYExpress($1); }
+ : ExpressionStatement_ Terminator { $$ = $1; }
;
/* }}} */
/* 13.6 The if Statement {{{ */
IterationStatement
: "do" Statement "while" "(" Expression ")" TerminatorOpt { $$ = CYNew CYDoWhile($5, $2); }
| "while" "(" Expression ")" Statement { $$ = CYNew CYWhile($3, $5); }
- | "for" "(" LexPushInOn ForStatementInitializer ";" LexPopIn ExpressionOpt ";" ExpressionOpt ")" Statement { $$ = CYNew CYFor($4, $7, $9, $11); }
+ | "for" "(" LexPushInOn ForStatementInitializer LexPopIn ExpressionOpt ";" ExpressionOpt ")" Statement { $$ = CYNew CYFor($4, $6, $8, $10); }
+ | "for" "(" LexPushInOn LexSetRegExp Var_ BindingIdentifier Initializer "!in" LexPopIn Expression ")" Statement { $$ = CYNew CYForInitialized(CYNew CYDeclaration($6, $7), $10, $12); }
| "for" "(" LexPushInOn ForInStatementInitializer "!in" LexPopIn Expression ")" Statement { $$ = CYNew CYForIn($4, $7, $9); }
| "for" "(" LexPushInOn ForInStatementInitializer "of" LexPopIn AssignmentExpression ")" Statement { $$ = CYNew CYForOf($4, $7, $9); }
;
ForStatementInitializer
- : ExpressionOpt { $$ = $1; }
- | LexSetRegExp Var_ VariableDeclarationList { $$ = CYNew CYForDeclarations($3); }
- | LexSetRegExp LexicalDeclaration { CYNOT(@$); }
+ : LexSetRegExp EmptyStatement { $$ = $2; }
+ | ExpressionStatement_ ";" { $$ = $1; }
+ | LexSetRegExp VariableStatement_ ";" { $$ = $2; }
+ | LexSetRegExp LexicalDeclaration_ ";" { $$ = $2; }
;
ForInStatementInitializer
;
/* }}} */
/* 14.2 Arrow Function Definitions {{{ */
+LexEqualRight
+ : { CYLIN(EqualRight); }
+ ;
+
ArrowFunction
- : LexSetRegExp ArrowParameters "=>" LexNoBrace ConciseBody { $$ = CYNew CYFatArrow($2, $5); }
+ : LexSetRegExp ArrowParameters LexEqualRight "=>" LexNoBrace ConciseBody { $$ = CYNew CYFatArrow($2, $6); }
;
ArrowParameters
;
YieldExpression
- : Yield LexSetRegExp "\n" { CYNOT(@$); /* $$ = CYNew CYYieldValue(NULL); */ }
+ : Yield LexSetRegExp NewLineOpt { CYNOT(@$); /* $$ = CYNew CYYieldValue(NULL); */ }
| Yield AssignmentExpression { CYNOT(@$); /* $$ = CYNew CYYieldValue($2); */ }
| Yield LexSetRegExp YieldStar AssignmentExpression { CYNOT(@$); /* $$ = CYNew CYYieldGenerator($4); */ }
;
;
ImplementationFieldListOpt
- : TypedIdentifier ";" ImplementationFieldListOpt { $$ = CYNew CYImplementationField($1, $3); }
+ : LexSetRegExp TypedIdentifier ";" ImplementationFieldListOpt { $$ = CYNew CYImplementationField($2, $4); }
| LexSetRegExp { $$ = NULL; }
;
/* }}} */
/* Cycript (Objective-C): Send Message {{{ */
VariadicCall
- : "," AssignmentExpression VariadicCall { $$ = CYNew CYArgument(NULL, $2, $3); }
+ : "," AssignmentExpressionClassic VariadicCall { $$ = CYNew CYArgument(NULL, $2, $3); }
| { $$ = NULL; }
;
;
SelectorCall
- : SelectorWordOpt ":" AssignmentExpression SelectorCall_ { $$ = CYNew CYArgument($1 ?: CYNew CYWord(""), $3, $4); }
+ : SelectorWordOpt ":" AssignmentExpressionClassic SelectorCall_ { $$ = CYNew CYArgument($1 ?: CYNew CYWord(""), $3, $4); }
;
SelectorList
;
MessageExpression
- : "[" LexPushInOff AssignmentExpression { driver.contexts_.push_back($3); } SelectorList "]" LexPopIn { driver.contexts_.pop_back(); } { $$ = CYNew CYSendDirect($3, $5); }
- | "[" LexPushInOff LexSetRegExp "!super" { driver.context_ = NULL; } SelectorList "]" LexPopIn { $$ = CYNew CYSendSuper($6); }
+ : "[" LexPushInOff AssignmentExpressionClassic { driver.contexts_.push_back($3); } SelectorList "]" LexPopIn { driver.contexts_.pop_back(); } { $$ = CYNew CYSendDirect($3, $5); }
+ | "[" LexPushInOff LexSetRegExp "super" { driver.context_ = NULL; } SelectorList "]" LexPopIn { $$ = CYNew CYSendSuper($6); }
;
SelectorExpression_
;
ComprehensionFor
- : "for" "(" LexPushInOn LexicalBinding "!in" LexPopIn Expression ")" { $$ = CYNew CYForInComprehension($4, $7); }
- | "for" "(" LexPushInOn LexicalBinding "of" LexPopIn Expression ")" { $$ = CYNew CYForOfComprehension($4, $7); }
+ : "for" "(" LexPushInOn ForBinding "!in" LexPopIn Expression ")" { $$ = CYNew CYForInComprehension($4, $7); }
+ | "for" "(" LexPushInOn ForBinding "of" LexPopIn Expression ")" { $$ = CYNew CYForOfComprehension($4, $7); }
;
ComprehensionIf
RubyProcParametersOpt
: RubyProcParameters { $$ = $1; }
- | { $$ = NULL; }
+ | LexSetRegExp { $$ = NULL; }
+ ;
+
+LexOpenBrace
+ : { CYLIN(OpenBrace); }
;
RubyProcExpression
;
PostfixExpression
- : PostfixExpression RubyProcExpression { $$ = CYNew CYRubyBlock($1, $2); }
+ : PostfixExpression LexOpenBrace RubyProcExpression { $$ = CYNew CYRubyBlock($1, $3); }
;
/* }}} */