-/* Cycript - Remote Execution Server and Disassembler
+/* Cycript - Inlining/Optimizing JavaScript Compiler
* Copyright (C) 2009 Jay Freeman (saurik)
*/
#include "Parser.hpp"
@begin ObjectiveC
-#include "ObjectiveC.hpp"
+#include "ObjectiveC/Syntax.hpp"
+@end
+
+@begin E4X
+#include "E4X.hpp"
@end
typedef struct {
CYAssignment *assignment_;
CYBoolean *boolean_;
CYClause *clause_;
- CYCatch *catch_;
+ cy::Syntax::Catch *catch_;
CYComprehension *comprehension_;
CYCompound *compound_;
CYDeclaration *declaration_;
CYMessageParameter *messageParameter_;
CYSelectorPart *selector_;
@end
+
+@begin E4X
+ CYAttribute *attribute_;
+@end
};
} YYSTYPE;
%parse-param { CYDriver &driver }
%lex-param { void *scanner }
+@begin E4X
+%token XMLCDATA
+%token XMLComment
+%token XMLPI
+
+%token XMLAttributeValue
+%token XMLName
+%token XMLTagCharacters
+%token XMLText
+%token XMLWhitespace
+@end
+
+@begin E4X
+%token LeftRight "<>"
+%token LeftSlashRight "</>"
+
+%token SlashRight "/>"
+%token LeftSlash "</"
+
%token At "@"
+%token ColonColon "::"
+%token PeriodPeriod ".."
+@end
%token Ampersand "&"
%token AmpersandAmpersand "&&"
// Woah?!
%token <identifier_> Each "each"
+@begin E4X
+// E4X Conditional
+%token <identifier_> Namespace "namespace"
+%token <identifier_> XML "xml"
+@end
+
%token <identifier_> Identifier_
%token <number_> NumericLiteral
%token <string_> StringLiteral
%type <argument_> Arguments
%type <literal_> ArrayLiteral
%type <expression_> AssigneeExpression
-%type <expression_> AssigneeExpression_
%type <expression_> AssigneeExpressionNoBF
%type <expression_> AssignmentExpression
%type <assignment_> AssignmentExpression_
%type <expression_> PrimaryExpression
%type <expression_> PrimaryExpression_
%type <expression_> PrimaryExpressionNoBF
+%type <expression_> PrimaryExpressionNoBF_
%type <statement_> Program
%type <propertyName_> PropertyName
%type <property_> PropertyNameAndValueList
%type <property_> PropertyNameAndValueList_
%type <property_> PropertyNameAndValueListOpt
-%type <literal_> RegularExpressionLiteral_
-%type <condition_> RegularExpressionToken
%type <expression_> RelationalExpression
%type <infix_> RelationalExpression_
%type <expression_> RelationalExpressionNoBF
%type <expression_> ShiftExpression
%type <expression_> ShiftExpressionNoBF
%type <statement_> SourceElement
+%type <statement_> SourceElement_
%type <statement_> SourceElements
%type <statement_> Statement
%type <statement_> Statement_
%type <statement_> SwitchStatement
%type <statement_> ThrowStatement
%type <statement_> TryStatement
+%type <expression_> UnaryAssigneeExpression
%type <expression_> UnaryExpression
%type <expression_> UnaryExpression_
%type <expression_> UnaryExpressionNoBF
%type <word_> WordOpt
@end
+@begin E4X
+%type <identifier_> PropertyIdentifier_
+%type <identifier_> PropertySelector
+%type <identifier_> PropertySelector_
+%type <identifier_> QualifiedIdentifier
+%type <identifier_> QualifiedIdentifier_
+%type <identifier_> WildcardIdentifier
+%type <identifier_> XMLComment
+%type <identifier_> XMLCDATA
+%type <identifier_> XMLElement
+%type <identifier_> XMLElementContent
+%type <identifier_> XMLMarkup
+%type <identifier_> XMLPI
+
+%type <attribute_> AttributeIdentifier
+%type <statement_> DefaultXMLNamespaceStatement
+%type <expression_> PropertyIdentifier
+%type <expression_> XMLListInitialiser
+%type <expression_> XMLInitialiser
+@end
+
+/*
%left "*" "/" "%"
%left "+" "-"
%left "<<" ">>" ">>>"
%left "||"
%right "=" "*=" "/=" "%=" "+=" "-=" "<<=" ">>=" ">>>=" "&=" "^=" "|="
+*/
%nonassoc "if"
%nonassoc "else"
%%
+/* Lexer State {{{ */
+LexSetRegExp
+ : { driver.SetCondition(CYDriver::RegExpCondition); }
+ ;
+/* }}} */
+
StrictSemi
: { driver.Warning(yylloc, "warning, automatic semi-colon insertion required"); }
;
| { $$ = NULL; }
;
-RegularExpressionToken
- : "/" { $$ = CYDriver::RegExStart; }
- | "/=" { $$ = CYDriver::RegExRest; }
- ;
-
-RegularExpressionLiteral_
- : RegularExpressionToken { driver.SetCondition($1); } RegularExpressionLiteral { $$ = $3; }
- ;
-
Literal
: NullLiteral { $$ = $1; }
| BooleanLiteral { $$ = $1; }
| NumericLiteral { $$ = $1; }
| StringLiteral { $$ = $1; }
- | RegularExpressionLiteral_ { $$ = $1; }
+ | RegularExpressionLiteral { $$ = $1; }
;
NullLiteral
/* 11.1 Primary Expressions {{{ */
PrimaryExpression_
+ : ObjectLiteral { $$ = $1; }
+ | PrimaryExpressionNoBF_ { $$ = $1; }
+ ;
+
+PrimaryExpressionNoBF_
: "this" { $$ = $1; }
| Identifier { $$ = new(driver.pool_) CYVariable($1); }
| Literal { $$ = $1; }
;
PrimaryExpression
- : ObjectLiteral { $$ = $1; }
- | PrimaryExpression_ { $$ = $1; }
+ : LexSetRegExp PrimaryExpression_ { $$ = $2; }
;
PrimaryExpressionNoBF
- : PrimaryExpression_ { $$ = $1; }
+ : PrimaryExpressionNoBF_ { $$ = $1; }
;
/* }}} */
/* 11.1.4 Array Initialiser {{{ */
ElementOpt
: Element { $$ = $1; }
- | { $$ = NULL; }
+ | LexSetRegExp { $$ = NULL; }
;
ElementListOpt
: ElementList { $$ = $1; }
- | { $$ = NULL; }
+ | LexSetRegExp { $$ = NULL; }
;
ElementList
: PrimaryExpression { $$ = $1; }
| FunctionExpression { $$ = $1; }
| MemberExpression MemberAccess { $2->SetLeft($1); $$ = $2; }
- | MemberExpression_ { $$ = $1; }
+ | LexSetRegExp MemberExpression_ { $$ = $2; }
;
MemberExpressionNoBF
NewExpression
: MemberExpression { $$ = $1; }
- | NewExpression_ { $$ = $1; }
+ | LexSetRegExp NewExpression_ { $$ = $2; }
;
NewExpressionNoBF
ArgumentListOpt
: ArgumentList { $$ = $1; }
- | { $$ = NULL; }
+ | LexSetRegExp { $$ = NULL; }
;
ArgumentList
UnaryExpression
: PostfixExpression { $$ = $1; }
- | UnaryExpression_ { $$ = $1; }
+ | LexSetRegExp UnaryExpression_ { $$ = $2; }
;
UnaryExpressionNoBF
AssigneeExpression
: LeftHandSideExpression { $$ = $1; }
- | AssigneeExpression_ { $$ = $1; }
+ | LexSetRegExp UnaryAssigneeExpression { $$ = $2; }
;
AssigneeExpressionNoBF
: LeftHandSideExpressionNoBF { $$ = $1; }
- | AssigneeExpression_ { $$ = $1; }
+ | UnaryAssigneeExpression { $$ = $1; }
;
AssignmentExpression
ExpressionOpt
: Expression { $$ = $1; }
- | { $$ = NULL; }
+ | LexSetRegExp { $$ = NULL; }
;
ExpressionNoInOpt
: ExpressionNoIn { $$ = $1; }
- | { $$ = NULL; }
+ | LexSetRegExp { $$ = NULL; }
;
Expression
;
Statement
- : Statement_ { $$ = $1; }
+ : LexSetRegExp Statement_ { $$ = $2; }
;
/* }}} */
/* 12.1 Block {{{ */
StatementListOpt
: StatementList { $$ = $1; }
- | { $$ = NULL; }
+ | LexSetRegExp { $$ = NULL; }
;
/* }}} */
/* 12.2 Variable Statement {{{ */
ForStatementInitialiser
: ExpressionNoInOpt { $$ = $1; }
- | "var" VariableDeclarationListNoIn { $$ = $2; }
+ | LexSetRegExp "var" VariableDeclarationListNoIn { $$ = $3; }
;
/* }}} */
/* 12.6.4 The for-in Statement {{{ */
ForInStatementInitialiser
: LeftHandSideExpression { $$ = $1; }
- | "var" VariableDeclarationNoIn { $$ = $2; }
+ | LexSetRegExp "var" VariableDeclarationNoIn { $$ = $3; }
;
/* }}} */
/* }}} */
/* 12.13 The throw Statement {{{ */
ThrowStatement
- : "throw" Expression Terminator { $$ = new(driver.pool_) CYThrow($2); }
+ : "throw" Expression Terminator { $$ = new(driver.pool_) cy::Syntax::Throw($2); }
;
/* }}} */
/* 12.14 The try Statement {{{ */
TryStatement
- : "try" Block_ CatchOpt FinallyOpt { $$ = new(driver.pool_) CYTry($2, $3, $4); }
+ : "try" Block_ CatchOpt FinallyOpt { $$ = new(driver.pool_) cy::Syntax::Try($2, $3, $4); }
;
CatchOpt
- : "catch" "(" Identifier ")" Block_ { $$ = new(driver.pool_) CYCatch($3, $5); }
+ : "catch" "(" Identifier ")" Block_ { $$ = new(driver.pool_) cy::Syntax::Catch($3, $5); }
| { $$ = NULL; }
;
;
FunctionExpression
- : "function" IdentifierOpt "(" FormalParameterList ")" "{" FunctionBody "}" { $$ = new(driver.pool_) CYFunctionExpression($2, $4, $7); }
+ : LexSetRegExp "function" IdentifierOpt "(" FormalParameterList ")" "{" FunctionBody "}" { $$ = new(driver.pool_) CYFunctionExpression($3, $5, $8); }
;
FormalParameterList_
SourceElements
: SourceElement SourceElements { $1->SetNext($2); $$ = $1; }
- | { $$ = NULL; }
+ | LexSetRegExp { $$ = NULL; }
;
-SourceElement
+SourceElement_
: Statement_ { $$ = $1; }
| FunctionDeclaration { $$ = $1; }
;
+
+SourceElement
+ : LexSetRegExp SourceElement_ { $$ = $2; }
+ ;
/* }}} */
@begin ObjectiveC
/* Cycript (Objective-C): @class Declaration {{{ */
ClassSuperOpt
- : ":" MemberExpressionNoBF { $$ = $2; }
+ /* XXX: why the hell did I choose MemberExpressionNoBF? */
+ : ":" LexSetRegExp MemberExpressionNoBF { $$ = $3; }
| { $$ = NULL; }
;
: "@class" ClassName ClassMessageDeclarationListOpt "@end" { $$ = new(driver.pool_) CYCategory($2, $3); }
;
-PrimaryExpression
+PrimaryExpression_
: ClassExpression { $$ = $1; }
;
;
MessageExpression
- : "[" AssignmentExpression SelectorList "]" { $$ = new(driver.pool_) CYSend($2, $3); }
+ : "[" AssignmentExpression SelectorList "]" { $$ = new(driver.pool_) CYSendDirect($2, $3); }
+ | "[" LexSetRegExp "super" SelectorList "]" { $$ = new(driver.pool_) CYSendSuper($4); }
;
SelectorExpressionOpt
| Word { $$ = new(driver.pool_) CYSelectorPart($1, false, NULL); }
;
-PrimaryExpression_
+PrimaryExpressionNoBF_
: MessageExpression { $$ = $1; }
| "@selector" "(" SelectorExpression ")" { $$ = new(driver.pool_) CYSelector($3); }
;
@begin C
/* Cycript (C): Pointer Indirection/Addressing {{{ */
-AssigneeExpression_
- : "*" UnaryExpression { $$ = new(driver.pool_) CYIndirect($2); }
+UnaryAssigneeExpression
+ : "^" UnaryExpression { $$ = new(driver.pool_) CYIndirect($2); }
;
UnaryExpression_
/* }}} */
@end
+@begin E4X
+/* Lexer State {{{ */
+LexPushRegExp
+ : { driver.PushCondition(CYDriver::RegExpCondition); }
+ ;
+
+LexPushXMLContent
+ : { driver.PushCondition(CYDriver::XMLContentCondition); }
+ ;
+
+LexPushXMLTag
+ : { driver.PushCondition(CYDriver::XMLTagCondition); }
+ ;
+
+LexPop
+ : { driver.PopCondition(); }
+ ;
+
+LexSetXMLContent
+ : { driver.SetCondition(CYDriver::XMLContentCondition); }
+ ;
+
+LexSetXMLTag
+ : { driver.SetCondition(CYDriver::XMLTagCondition); }
+ ;
+/* }}} */
+
+XMLWhitespaceOpt
+ : XMLWhitespace
+ |
+ ;
+
+/* 8.1 Context Keywords {{{ */
+Identifier
+ : "namespace" { $$ = $1; }
+ | "xml" { $$ = $1; }
+ ;
+/* }}} */
+/* 8.3 XML Initialiser Input Elements {{{ */
+XMLMarkup
+ : XMLComment { $$ = $1; }
+ | XMLCDATA { $$ = $1; }
+ | XMLPI { $$ = $1; }
+ ;
+/* }}} */
+/* 11.1 Primary Expressions {{{ */
+PrimaryExpressionNoBF_
+ : PropertyIdentifier { $$ = $1; }
+ | XMLInitialiser { $$ = $1; }
+ | XMLListInitialiser { $$ = $1; }
+ ;
+
+PropertyIdentifier
+ : AttributeIdentifier { $$ = $1; }
+ | QualifiedIdentifier { $$ = $1; }
+ | WildcardIdentifier { $$ = $1; }
+ ;
+/* }}} */
+/* 11.1.1 Attribute Identifiers {{{ */
+AttributeIdentifier
+ : "@" QualifiedIdentifier_ { $$ = new(driver.pool_) CYAttribute($2); }
+ ;
+
+PropertySelector_
+ : PropertySelector
+ | "[" Expression "]"
+ ;
+
+PropertySelector
+ : Word { $$ = $1; }
+ | WildcardIdentifier { $$ = $1; }
+ ;
+/* }}} */
+/* 11.1.2 Qualified Identifiers {{{ */
+QualifiedIdentifier_
+ : PropertySelector_ { $$ = $1; }
+ | QualifiedIdentifier { $$ = $1; }
+ ;
+
+QualifiedIdentifier
+ : PropertySelector "::" PropertySelector_ { $$ = new(driver.pool_) CYQName($1, $3); }
+ ;
+/* }}} */
+/* 11.1.3 Wildcard Identifiers {{{ */
+WildcardIdentifier
+ : "*" { $$ = new(driver.pool_) CYWildcard(); }
+ ;
+/* }}} */
+/* 11.1.4 XML Initialiser {{{ */
+XMLInitialiser
+ : XMLMarkup { $$ = $1; }
+ | XMLElement { $$ = $1; }
+ ;
+
+XMLElement
+ : "<" XMLTagContent_ "/>" LexPop
+ | "<" XMLTagContent_ ">" LexSetXMLContent XMLElementContentOpt "</" LexSetXMLTag XMLTagName XMLWhitespaceOpt ">" LexPop
+ ;
+
+XMLTagContent_
+ : LexPushXMLTag XMLTagContent XMLWhitespaceOpt
+ ;
+
+XMLTagContent
+ : XMLTagName XMLAttributesOpt
+ ;
+
+XMLExpression
+ : "{" LexPushRegExp Expression "}" LexPop
+ ;
+
+XMLTagName
+ : XMLExpression
+ | XMLName
+ ;
+
+XMLAttributes
+ : XMLWhitespace XMLExpression
+ | XMLAttributeOpt XMLAttributes
+ ;
+
+XMLAttributesOpt
+ : XMLAttributes
+ |
+ ;
+
+XMLAttributeValue_
+ : XMLExpression
+ | XMLAttributeValue
+ ;
+
+XMLAttribute
+ : XMLWhitespace XMLName XMLWhitespaceOpt "=" XMLWhitespaceOpt XMLAttributeValue_
+ ;
+
+XMLAttributeOpt
+ : XMLAttribute
+ |
+ ;
+
+XMLElementContent
+ : XMLExpression XMLElementContentOpt
+ | XMLMarkup XMLElementContentOpt
+ | XMLText XMLElementContentOpt
+ | XMLElement XMLElementContentOpt
+ ;
+
+XMLElementContentOpt
+ : XMLElementContent
+ |
+ ;
+/* }}} */
+/* 11.1.5 XMLList Initialiser {{{ */
+XMLListInitialiser
+ : "<>" LexPushXMLContent XMLElementContent "</>" LexPop { $$ = new(driver.pool_) CYXMLList($3); }
+ ;
+/* }}} */
+/* 11.2 Left-Hand-Side Expressions {{{ */
+PropertyIdentifier_
+ : Word { $$ = $1; }
+ | PropertyIdentifier { $$ = $1; }
+ ;
+
+MemberAccess
+ : "." PropertyIdentifier { $$ = new(driver.pool_) CYPropertyMember(NULL, $2); }
+ | ".." PropertyIdentifier_ { $$ = new(driver.pool_) CYDescendantMember(NULL, $2); }
+ | "." "(" Expression ")" { $$ = new(driver.pool_) CYFilteringPredicate(NULL, $3); }
+ ;
+/* }}} */
+/* 12.1 The default xml namespace Statement {{{ */
+DefaultXMLNamespaceStatement
+ : "default" "xml" "namespace" "=" Expression Terminator { $$ = new(driver.pool_) CYDefaultXMLNamespace($5); }
+ ;
+
+Statement_
+ : DefaultXMLNamespaceStatement { $$ = $1; }
+ ;
+/* }}} */
+@end
+
/* ECMAScript5: Object Literal Trailing Comma {{{ */
PropertyNameAndValueList_
: "," { $$ = NULL; }
: ForComprehension ComprehensionListOpt { $1->SetNext($2); $$ = $1; }
;
-PrimaryExpression_
+PrimaryExpressionNoBF_
: "[" AssignmentExpression ComprehensionList "]" { $$ = new(driver.pool_) CYArrayComprehension($2, $3); }
;
/* }}} */
: "let" "(" VariableDeclarationList ")" Block_ { $$ = new(driver.pool_) CYLet($3, $5); }
;
-Statement
+Statement_
: LetStatement
;
*//* }}} */
/* JavaScript FTW: Function Statements {{{ */
Statement
- : FunctionDeclaration { driver.Warning(yylloc, "warning, FunctionDeclaration is a SourceElement, not a Statement"); } { $$ = $1; }
+ : LexSetRegExp FunctionDeclaration { driver.Warning(yylloc, "warning, FunctionDeclaration is a SourceElement, not a Statement"); } { $$ = $2; }
;
/* }}} */