yyextra->state_ = CYNewLine; \
}
-#define M { \
+#define V(more) { \
if (const char *nl = reinterpret_cast<const char *>(memchr(yytext, '\n', yyleng))) { \
unsigned lines(0); \
size_t left; \
yylloc->end.lines(lines); \
yylloc->end.columns(left); \
yylloc->step(); \
- N \
+ more \
} else L \
}
%option nounput
%option interactive
%option reentrant
+%option stack
Exponent [eE][+-]?[0-9]+
Escape \\[\\'"bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\\n
RegularExpressionChars {RegularExpressionChar}*
RegularExpressionBody {RegularExpressionFirstChar}{RegularExpressionChars}
+@begin E4X
+XMLNameStart [a-zA-Z_:]
+XMLNamePart [a-zA-Z0-9.-_:]
+XMLName {XMLNameStart}{XMLNamePart}*
+@end
+
%s Div
%s RegExp
+@begin E4X
+%x XMLContent
+%x XMLTag
+@end
+
%%
<RegExp>\/{RegularExpressionBody}\/{RegularExpressionFlags} E("")
\/\/[^\n]* L
-\/\*(\n|[^\*]|\*[^/])*\*\/ M
+\/\*(\n|[^\*]|\*[^/])*\*\/ V(N)
@begin E4X
-<RegExp>\<!--(\n|[^-]|-[^-])*-->
-<RegExp>\<!\[CDATA\[(\n|[^[]|\[[^[]|\[\[[^>])*]]>
-<RegExp>\<?(\n|[^?]|\?[^>])*?>
+<RegExp>"<>" L return tk::LeftRight;
+<XMLContent>"</>" L return tk::LeftSlashRight;
+
+<RegExp,XMLContent>\<!\[CDATA\[(\n|[^[]|\[[^[]|\[\[[^>])*]]> V() return tk::XMLCDATA;
+<RegExp,XMLContent>\<!--(\n|[^-]|-[^-])*--> V() return tk::XMLComment;
+<RegExp,XMLContent>\<?(\n|[^?]|\?[^>])*?> V() return tk::XMLPI;
+
+<XMLTag>"=" L return tk::Equal;
+<XMLTag>">" L return tk::Right;
+<XMLTag>"/>" L return tk::SlashRight;
+<XMLTag>"{" L return tk::OpenBrace;
+
+<XMLTag>\"(\n|[^"])*\"|'(\n|[^'])*' V() {
+ return tk::XMLAttributeValue;
+}
+
+<XMLTag>{XMLName} L return tk::XMLName;
+<XMLTag>[ \t\r\n] V() return tk::XMLWhitespace;
+<XMLContent>"{" L return tk::OpenBrace;
+<XMLContent>"<" L return tk::Left;
+<XMLContent>"</" L return tk::LeftSlash;
+@end
+
+@begin E4X
"@" L C return tk::At;
"::" L C return tk::ColonColon;
-"<>" L C return tk::LeftRight;
-"</>" L C return tk::LeftSlashRight;
".." L C return tk::PeriodPeriod;
-"/>" L C return tk::SlashRight;
@end
"&" L C return tk::Ampersand;
"each" L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("each"); return tk::Each;
+@begin E4X
+"namespace" L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("namespace"); return tk::Namespace;
+"xml" L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("xml"); return tk::XML;
+@end
+
{IdentifierStart}{IdentifierPart}* L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier(apr_pstrmemdup(yyextra->pool_, yytext, yyleng)); return tk::Identifier_;
(\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?){Exponent}? L C yylval->number_ = new(yyextra->pool_) CYNumber(strtod(yytext, NULL)); return tk::NumericLiteral;
cylex_destroy(scanner_);
}
-void CYDriver::BeginCondition(Condition condition) {
+CYDriver::Condition CYDriver::GetCondition() {
+ switch (yy_top_state(scanner_)) {
+ case RegExp:
+ return RegExpCondition;
+@begin E4X
+ case XMLContent:
+ return XMLContentCondition;
+ case XMLTag:
+ return XMLTagCondition;
+@end
+ default:
+ _assert(false);
+ }
+}
+
+void CYDriver::SetCondition(Condition condition) {
struct yyguts_t *yyg(reinterpret_cast<struct yyguts_t *>(scanner_));
switch (condition) {
case RegExpCondition:
BEGIN(RegExp);
break;
+@begin E4X
+ case XMLContentCondition:
+ BEGIN(XMLContent);
+ break;
+ case XMLTagCondition:
+ BEGIN(XMLTag);
+ break;
+@end
default:
_assert(false);
}
}
+
+void CYDriver::PushCondition(Condition condition) {
+ switch (condition) {
+ case RegExpCondition:
+ yy_push_state(RegExp, scanner_);
+ break;
+@begin E4X
+ case XMLContentCondition:
+ yy_push_state(XMLContent, scanner_);
+ break;
+ case XMLTagCondition:
+ yy_push_state(XMLTag, scanner_);
+ break;
+@end
+ default:
+ _assert(false);
+ }
+}
+
+void CYDriver::PopCondition() {
+ yy_pop_state(scanner_);
+}
#include "ObjectiveC.hpp"
@end
+@begin E4X
+#include "E4X.hpp"
+@end
+
typedef struct {
bool newline_;
CYMessageParameter *messageParameter_;
CYSelectorPart *selector_;
@end
+
+@begin E4X
+ CYAttribute *attribute_;
+@end
};
} YYSTYPE;
%lex-param { void *scanner }
@begin E4X
-%token At "@"
-%token ColonColon "::"
-%token LeftRight "<>"
-%token LeftSlashRight "</>"
-%token PeriodPeriod ".."
-
%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 "&"
// 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 <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"); }
;
| "(" Expression ")" { $$ = $2; }
;
-LexBeginRegExp
- : { driver.BeginCondition(CYDriver::RegExpCondition); }
- ;
-
PrimaryExpression
- : LexBeginRegExp PrimaryExpression_ { $$ = $2; }
+ : LexSetRegExp PrimaryExpression_ { $$ = $2; }
;
PrimaryExpressionNoBF
ElementOpt
: Element { $$ = $1; }
- | LexBeginRegExp { $$ = NULL; }
+ | LexSetRegExp { $$ = NULL; }
;
ElementListOpt
: ElementList { $$ = $1; }
- | LexBeginRegExp { $$ = NULL; }
+ | LexSetRegExp { $$ = NULL; }
;
ElementList
: PrimaryExpression { $$ = $1; }
| FunctionExpression { $$ = $1; }
| MemberExpression MemberAccess { $2->SetLeft($1); $$ = $2; }
- | LexBeginRegExp MemberExpression_ { $$ = $2; }
+ | LexSetRegExp MemberExpression_ { $$ = $2; }
;
MemberExpressionNoBF
NewExpression
: MemberExpression { $$ = $1; }
- | LexBeginRegExp NewExpression_ { $$ = $2; }
+ | LexSetRegExp NewExpression_ { $$ = $2; }
;
NewExpressionNoBF
ArgumentListOpt
: ArgumentList { $$ = $1; }
- | LexBeginRegExp { $$ = NULL; }
+ | LexSetRegExp { $$ = NULL; }
;
ArgumentList
UnaryExpression
: PostfixExpression { $$ = $1; }
- | LexBeginRegExp UnaryExpression_ { $$ = $2; }
+ | LexSetRegExp UnaryExpression_ { $$ = $2; }
;
UnaryExpressionNoBF
AssigneeExpression
: LeftHandSideExpression { $$ = $1; }
- | LexBeginRegExp UnaryAssigneeExpression { $$ = $2; }
+ | LexSetRegExp UnaryAssigneeExpression { $$ = $2; }
;
AssigneeExpressionNoBF
ExpressionOpt
: Expression { $$ = $1; }
- | LexBeginRegExp { $$ = NULL; }
+ | LexSetRegExp { $$ = NULL; }
;
ExpressionNoInOpt
: ExpressionNoIn { $$ = $1; }
- | LexBeginRegExp { $$ = NULL; }
+ | LexSetRegExp { $$ = NULL; }
;
Expression
;
Statement
- : LexBeginRegExp Statement_ { $$ = $2; }
+ : LexSetRegExp Statement_ { $$ = $2; }
;
/* }}} */
/* 12.1 Block {{{ */
StatementListOpt
: StatementList { $$ = $1; }
- | LexBeginRegExp { $$ = NULL; }
+ | LexSetRegExp { $$ = NULL; }
;
/* }}} */
/* 12.2 Variable Statement {{{ */
ForStatementInitialiser
: ExpressionNoInOpt { $$ = $1; }
- | LexBeginRegExp "var" VariableDeclarationListNoIn { $$ = $3; }
+ | LexSetRegExp "var" VariableDeclarationListNoIn { $$ = $3; }
;
/* }}} */
/* 12.6.4 The for-in Statement {{{ */
ForInStatementInitialiser
: LeftHandSideExpression { $$ = $1; }
- | LexBeginRegExp "var" VariableDeclarationNoIn { $$ = $3; }
+ | LexSetRegExp "var" VariableDeclarationNoIn { $$ = $3; }
;
/* }}} */
;
FunctionExpression
- : LexBeginRegExp "function" IdentifierOpt "(" FormalParameterList ")" "{" FunctionBody "}" { $$ = new(driver.pool_) CYFunctionExpression($3, $5, $8); }
+ : LexSetRegExp "function" IdentifierOpt "(" FormalParameterList ")" "{" FunctionBody "}" { $$ = new(driver.pool_) CYFunctionExpression($3, $5, $8); }
;
FormalParameterList_
SourceElements
: SourceElement SourceElements { $1->SetNext($2); $$ = $1; }
- | LexBeginRegExp { $$ = NULL; }
+ | LexSetRegExp { $$ = NULL; }
;
SourceElement_
;
SourceElement
- : LexBeginRegExp SourceElement_ { $$ = $2; }
+ : LexSetRegExp SourceElement_ { $$ = $2; }
;
/* }}} */
/* Cycript (Objective-C): @class Declaration {{{ */
ClassSuperOpt
/* XXX: why the hell did I choose MemberExpressionNoBF? */
- : ":" LexBeginRegExp MemberExpressionNoBF { $$ = $3; }
+ : ":" LexSetRegExp MemberExpressionNoBF { $$ = $3; }
| { $$ = NULL; }
;
MessageExpression
: "[" AssignmentExpression SelectorList "]" { $$ = new(driver.pool_) CYSendDirect($2, $3); }
- | "[" LexBeginRegExp "super" SelectorList "]" { $$ = new(driver.pool_) CYSendSuper($4); }
+ | "[" LexSetRegExp "super" SelectorList "]" { $$ = new(driver.pool_) CYSendSuper($4); }
;
SelectorExpressionOpt
@begin C
/* Cycript (C): Pointer Indirection/Addressing {{{ */
UnaryAssigneeExpression
- : "*" UnaryExpression { $$ = new(driver.pool_) CYIndirect($2); }
+ : "^" 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
- | XMLCDATA
- | XMLPI
+ : XMLComment { $$ = $1; }
+ | XMLCDATA { $$ = $1; }
+ | XMLPI { $$ = $1; }
;
/* }}} */
/* 11.1 Primary Expressions {{{ */
PrimaryExpressionNoBF_
- : PropertyIdentifier
- | XMLInitialiser
- | XMLListInitialiser
+ : PropertyIdentifier { $$ = $1; }
+ | XMLInitialiser { $$ = $1; }
+ | XMLListInitialiser { $$ = $1; }
;
PropertyIdentifier
- : AttributeIdentifier
- | QualifiedIdentifier
- | WildcardIdentifier
+ : AttributeIdentifier { $$ = $1; }
+ | QualifiedIdentifier { $$ = $1; }
+ | WildcardIdentifier { $$ = $1; }
;
/* }}} */
/* 11.1.1 Attribute Identifiers {{{ */
AttributeIdentifier
- : "@" PropertySelector
- | "@" QualifiedIdentifier
- | "@" "[" Expression "]"
+ : "@" QualifiedIdentifier_ { $$ = new(driver.pool_) CYAttribute($2); }
+ ;
+
+PropertySelector_
+ : PropertySelector
+ | "[" Expression "]"
;
PropertySelector
- : Identifier
- | WildcardIdentifier
+ : Word { $$ = $1; }
+ | WildcardIdentifier { $$ = $1; }
;
/* }}} */
/* 11.1.2 Qualified Identifiers {{{ */
+QualifiedIdentifier_
+ : PropertySelector_ { $$ = $1; }
+ | QualifiedIdentifier { $$ = $1; }
+ ;
+
QualifiedIdentifier
- : PropertySelector "::" PropertySelector
- | PropertySelector "::" "[" Expression "]"
+ : 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
- | XMLElement
+ : XMLMarkup { $$ = $1; }
+ | XMLElement { $$ = $1; }
;
XMLElement
- : "<" XMLTagContent XMLWhitespaceOpt "/>"
- | "<" XMLTagContent XMLWhitespace ">" XMLElementContentOpt "</" XMLTagName XMLWhitespaceOpt ">"
+ : "<" XMLTagContent_ "/>" LexPop
+ | "<" XMLTagContent_ ">" LexSetXMLContent XMLElementContentOpt "</" LexSetXMLTag XMLTagName XMLWhitespaceOpt ">" LexPop
+ ;
+
+XMLTagContent_
+ : LexPushXMLTag XMLTagContent XMLWhitespaceOpt
;
XMLTagContent
: XMLTagName XMLAttributesOpt
;
+XMLExpression
+ : "{" LexPushRegExp Expression "}" LexPop
+ ;
+
XMLTagName
- : "{" Expression "}"
+ : XMLExpression
| XMLName
;
XMLAttributes
- : XMLWhitespace "{" Expression "}"
+ : XMLWhitespace XMLExpression
| XMLAttributeOpt XMLAttributes
;
|
;
+XMLAttributeValue_
+ : XMLExpression
+ | XMLAttributeValue
+ ;
+
XMLAttribute
- : XMLWhitespace XMLName XMLWhitespaceOpt "=" XMLWhitespaceOpt "{" Expression "}"
- | XMLWhitespace XMLName XMLWhitespaceOpt "=" XMLWhitespaceOpt XMLAttributeValue
+ : XMLWhitespace XMLName XMLWhitespaceOpt "=" XMLWhitespaceOpt XMLAttributeValue_
;
XMLAttributeOpt
;
XMLElementContent
- : "{" Expression "}" XMLElementContentOpt
+ : XMLExpression XMLElementContentOpt
| XMLMarkup XMLElementContentOpt
| XMLText XMLElementContentOpt
| XMLElement XMLElementContentOpt
/* }}} */
/* 11.1.5 XMLList Initialiser {{{ */
XMLListInitialiser
- : "<>" XMLElementContent "</>"
+ : "<>" 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
*//* }}} */
/* JavaScript FTW: Function Statements {{{ */
Statement
- : LexBeginRegExp FunctionDeclaration { driver.Warning(yylloc, "warning, FunctionDeclaration is a SourceElement, not a Statement"); } { $$ = $2; }
+ : LexSetRegExp FunctionDeclaration { driver.Warning(yylloc, "warning, FunctionDeclaration is a SourceElement, not a Statement"); } { $$ = $2; }
;
/* }}} */
--- /dev/null
+/* Cycript - Remote Execution Server and Disassembler
+ * Copyright (C) 2009 Jay Freeman (saurik)
+*/
+
+/* Modified BSD License {{{ */
+/*
+ * Redistribution and use in source and binary
+ * forms, with or without modification, are permitted
+ * provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the
+ * above copyright notice, this list of conditions
+ * and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions
+ * and the following disclaimer in the documentation
+ * and/or other materials provided with the
+ * distribution.
+ * 3. The name of the author may not be used to endorse
+ * or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/* }}} */
+
+#ifndef CYCRIPT_E4X_HPP
+#define CYCRIPT_E4X_HPP
+
+#include "Parser.hpp"
+
+struct CYDefaultXMLNamespace :
+ CYStatement
+{
+ CYExpression *expression_;
+
+ CYDefaultXMLNamespace(CYExpression *expression) :
+ expression_(expression)
+ {
+ }
+
+ virtual CYStatement *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+#endif/*CYCRIPT_E4X_HPP*/