#define C T yyextra->state_ = CYClear;
#define R T yyextra->state_ = CYRestricted;
+#define E(prefix) L C BEGIN(INITIAL); { \
+ char *value(reinterpret_cast<char *>(apr_palloc(yyextra->pool_, yyleng + sizeof(prefix)))); \
+ memcpy(value, prefix, sizeof(prefix) - 1); \
+ memcpy(value + sizeof(prefix) - 1, yytext, yyleng); \
+ value[yyleng + sizeof(prefix) - 1] = '\0'; \
+ yylval->literal_ = new CYRegEx(value); \
+ return tk::RegularExpressionLiteral; \
+}
+
#define N \
if (yyextra->state_ != CYNewLine) { \
bool restricted(yyextra->state_ == CYRestricted); \
Exponent [eE][+-]?[0-9]+
Escape \\[\\'"bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\\n
+IdentifierStart [a-zA-Z$_]
+IdentifierPart [a-zA-Z$_0-9]
+
+NonTerminator [^\n]
+BackslashSequence \\{NonTerminator}
+RegularExpressionFirstChar [^\n*\\/]|{BackslashSequence}
+RegularExpressionChar [^\n\\/]|{BackslashSequence}
+RegularExpressionFlags {IdentifierPart}*
+RegularExpressionChars {RegularExpressionChar}*
+RegularExpressionBody_ {RegularExpressionChars}
+RegularExpressionBody {RegularExpressionFirstChar}{RegularExpressionBody_}
+
+RegularExpressionEnd_ \/{RegularExpressionFlags}
+RegularExpressionRest_ {RegularExpressionBody_}{RegularExpressionEnd_}
+RegularExpressionStart_ {RegularExpressionBody}{RegularExpressionEnd_}
+
+%x res
+%x rer
+
%%
+<res>{RegularExpressionStart_} E("/")
+<rer>{RegularExpressionRest_} E("/=")
+
\/\/[^\n]* ;
\/\*(\n|[^\*]|\*[^/])\*\/ if (memchr(yytext, '\n', yyleng) != NULL) N // XXX: supposedly I will be screwed on very very long multi-line comments and need to replace this with a manual lexer. http://websrv.cs.fsu.edu/~engelen/courses/COP5621/Pr2.pdf ; XXX: this rule doesn't work anyway, fucking A :(
"each" L C yylval->identifier_ = new CYIdentifier("each"); return tk::Each;
-[a-zA-Z$_][a-zA-Z$_0-9]* yylval->identifier_ = new CYIdentifier(apr_pstrmemdup(yyextra->pool_, yytext, yyleng)); L C return tk::Identifier_;
+{IdentifierStart}{IdentifierPart}* yylval->identifier_ = new CYIdentifier(apr_pstrmemdup(yyextra->pool_, yytext, yyleng)); L C return tk::Identifier_;
(\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?){Exponent}? yylval->number_ = new CYNumber(strtod(yytext, NULL)); L C return tk::NumericLiteral;
void CYDriver::ScannerDestroy() {
cylex_destroy(scanner_);
}
+
+void CYDriver::SetCondition(Condition condition) {
+ struct yyguts_t *yyg(reinterpret_cast<struct yyguts_t *>(scanner_));
+
+ switch (condition) {
+ case RegExStart:
+ BEGIN(res);
+ break;
+ case RegExRest:
+ BEGIN(rer);
+ break;
+ default:
+ _assert(false);
+ }
+}
union {
bool bool_;
+ CYDriver::Condition condition_;
+
CYArgument *argument_;
CYAssignment *assignment_;
CYBoolean *boolean_;
//%glr-parser
//%expect 1
-%debug
-
%error-verbose
%parse-param { CYDriver &driver }
%token <identifier_> Identifier_
%token <number_> NumericLiteral
%token <string_> StringLiteral
+%token <literal_> RegularExpressionLiteral
%type <expression_> AdditiveExpression
%type <expression_> AdditiveExpressionNoBF
%type <property_> PropertyNameAndValueList
%type <property_> PropertyNameAndValueList_
%type <property_> PropertyNameAndValueListOpt
+%type <literal_> RegularExpressionLiteral_
+%type <condition_> RegularExpressionToken
%type <expression_> RelationalExpression
%type <infix_> RelationalExpression_
%type <expression_> RelationalExpressionNoBF
| { $$ = NULL; }
;
+RegularExpressionToken
+ : "/" { $$ = CYDriver::RegExStart; }
+ | "/=" { $$ = CYDriver::RegExRest; }
+ ;
+
+RegularExpressionLiteral_
+ : RegularExpressionToken { driver.SetCondition($1); } RegularExpressionLiteral { $$ = $3; }
+ ;
+
Literal
: NullLiteral { $$ = $1; }
| BooleanLiteral { $$ = $1; }
| NumericLiteral { $$ = $1; }
| StringLiteral { $$ = $1; }
+ | RegularExpressionLiteral_ { $$ = $1; }
;
NullLiteral
;
/* }}} */
+/* 11.2 Left-Hand-Side Expressions {{{ */
MemberExpression_
: "new" MemberExpression Arguments { $$ = new(driver.pool_) CYNew($2, $3); }
;
: NewExpressionNoBF { $$ = $1; }
| CallExpressionNoBF { $$ = $1; }
;
-
+/* }}} */
+/* 11.3 Postfix Expressions {{{ */
PostfixExpression
: AssigneeExpression { $$ = $1; }
| LeftHandSideExpression "++" { $$ = new(driver.pool_) CYPostIncrement($1); }
| LeftHandSideExpressionNoBF "++" { $$ = new(driver.pool_) CYPostIncrement($1); }
| LeftHandSideExpressionNoBF "--" { $$ = new(driver.pool_) CYPostDecrement($1); }
;
-
+/* }}} */
+/* 11.4 Unary Operators {{{ */
UnaryExpression_
: "delete" UnaryExpression { $$ = new(driver.pool_) CYDelete($2); }
| "void" UnaryExpression { $$ = new(driver.pool_) CYVoid($2); }
: PostfixExpressionNoBF { $$ = $1; }
| UnaryExpression_ { $$ = $1; }
;
-
+/* }}} */
+/* 11.5 Multiplicative Operators {{{ */
MultiplicativeExpression
: UnaryExpression { $$ = $1; }
| MultiplicativeExpression "*" UnaryExpression { $$ = new(driver.pool_) CYMultiply($1, $3); }
| MultiplicativeExpressionNoBF "/" UnaryExpression { $$ = new(driver.pool_) CYDivide($1, $3); }
| MultiplicativeExpressionNoBF "%" UnaryExpression { $$ = new(driver.pool_) CYModulus($1, $3); }
;
-
+/* }}} */
+/* 11.6 Additive Operators {{{ */
AdditiveExpression
: MultiplicativeExpression { $$ = $1; }
| AdditiveExpression "+" MultiplicativeExpression { $$ = new(driver.pool_) CYAdd($1, $3); }
| AdditiveExpressionNoBF "+" MultiplicativeExpression { $$ = new(driver.pool_) CYAdd($1, $3); }
| AdditiveExpressionNoBF "-" MultiplicativeExpression { $$ = new(driver.pool_) CYSubtract($1, $3); }
;
-
+/* }}} */
+/* 11.7 Bitwise Shift Operators {{{ */
ShiftExpression
: AdditiveExpression { $$ = $1; }
| ShiftExpression "<<" AdditiveExpression { $$ = new(driver.pool_) CYShiftLeft($1, $3); }
| ShiftExpressionNoBF ">>" AdditiveExpression { $$ = new(driver.pool_) CYShiftRightSigned($1, $3); }
| ShiftExpressionNoBF ">>>" AdditiveExpression { $$ = new(driver.pool_) CYShiftRightUnsigned($1, $3); }
;
-
+/* }}} */
+/* 11.8 Relational Operators {{{ */
RelationalExpressionNoIn_
: "<" ShiftExpression { $$ = new(driver.pool_) CYLess(NULL, $2); }
| ">" ShiftExpression { $$ = new(driver.pool_) CYGreater(NULL, $2); }
: ShiftExpressionNoBF { $$ = $1; }
| RelationalExpressionNoBF RelationalExpression_ { $2->SetLeft($1); $$ = $2; }
;
-
+/* }}} */
+/* 11.9 Equality Operators {{{ */
EqualityExpression
: RelationalExpression { $$ = $1; }
| EqualityExpression "==" RelationalExpression { $$ = new(driver.pool_) CYEqual($1, $3); }
| EqualityExpressionNoBF "===" RelationalExpression { $$ = new(driver.pool_) CYIdentical($1, $3); }
| EqualityExpressionNoBF "!==" RelationalExpression { $$ = new(driver.pool_) CYNotIdentical($1, $3); }
;
-
+/* }}} */
+/* 11.10 Binary Bitwise Operators {{{ */
BitwiseANDExpression
: EqualityExpression { $$ = $1; }
| BitwiseANDExpression "&" EqualityExpression { $$ = new(driver.pool_) CYBitwiseAnd($1, $3); }
: BitwiseXORExpressionNoBF { $$ = $1; }
| BitwiseORExpressionNoBF "|" BitwiseXORExpression { $$ = new(driver.pool_) CYBitwiseOr($1, $3); }
;
-
+/* }}} */
+/* 11.11 Binary Logical Operators {{{ */
LogicalANDExpression
: BitwiseORExpression { $$ = $1; }
| LogicalANDExpression "&&" BitwiseORExpression { $$ = new(driver.pool_) CYLogicalAnd($1, $3); }
: LogicalANDExpressionNoBF { $$ = $1; }
| LogicalORExpressionNoBF "||" LogicalANDExpression { $$ = new(driver.pool_) CYLogicalOr($1, $3); }
;
-
+/* }}} */
+/* 11.12 Conditional Operator ( ? : ) {{{ */
ConditionalExpression
: LogicalORExpression { $$ = $1; }
| LogicalORExpression "?" AssignmentExpression ":" AssignmentExpression { $$ = new(driver.pool_) CYCondition($1, $3, $5); }
: LogicalORExpressionNoBF { $$ = $1; }
| LogicalORExpressionNoBF "?" AssignmentExpression ":" AssignmentExpression { $$ = new(driver.pool_) CYCondition($1, $3, $5); }
;
-
+/* }}} */
+/* 11.13 Assignment Operators {{{ */
AssignmentExpression_
: "=" AssignmentExpression { $$ = new(driver.pool_) CYAssign(NULL, $2); }
| "*=" AssignmentExpression { $$ = new(driver.pool_) CYMultiplyAssign(NULL, $2); }
: ConditionalExpressionNoBF { $$ = $1; }
| AssigneeExpressionNoBF AssignmentExpression_ { $2->SetLeft($1); $$ = $2; }
;
-
+/* }}} */
+/* 11.14 Comma Operator {{{ */
Expression_
: "," Expression { $$ = new(driver.pool_) CYCompound($2); }
| { $$ = NULL; }
ExpressionNoBF
: AssignmentExpressionNoBF Expression_ { if ($2) { $2->AddPrev($1); $$ = $2; } else $$ = $1; }
;
+/* }}} */
+/* 12 Statements {{{ */
Statement
: Block { $$ = $1; }
| VariableStatement { $$ = $1; }
| ThrowStatement { $$ = $1; }
| TryStatement { $$ = $1; }
;
-
+/* }}} */
+/* 12.1 Block {{{ */
Block_
: "{" StatementListOpt "}" { $$ = $2; }
;
: StatementList { $$ = $1; }
| { $$ = NULL; }
;
-
+/* }}} */
+/* 12.2 Variable Statement {{{ */
VariableStatement
: "var" VariableDeclarationList Terminator { $$ = new(driver.pool_) CYVar($2); }
;
InitialiserNoIn
: "=" AssignmentExpressionNoIn { $$ = $2; }
;
-
+/* }}} */
+/* 12.3 Empty Statement {{{ */
EmptyStatement
: ";" { $$ = new(driver.pool_) CYEmpty(); }
;
-
+/* }}} */
+/* 12.4 Expression Statement {{{ */
ExpressionStatement
: ExpressionNoBF Terminator { $$ = new(driver.pool_) CYExpress($1); }
;
-
+/* }}} */
+/* 12.5 The if Statement {{{ */
ElseStatementOpt
: "else" Statement { $$ = $2; }
| %prec "if" { $$ = NULL; }
IfStatement
: "if" "(" Expression ")" Statement ElseStatementOpt { $$ = new(driver.pool_) CYIf($3, $5, $6); }
;
+/* }}} */
+/* 12.6 Iteration Statements {{{ */
IterationStatement
: DoWhileStatement { $$ = $1; }
| WhileStatement { $$ = $1; }
| ForStatement { $$ = $1; }
| ForInStatement { $$ = $1; }
;
-
+/* }}} */
+/* 12.6.1 The do-while Statement {{{ */
DoWhileStatement
: "do" Statement "while" "(" Expression ")" TerminatorOpt { $$ = new(driver.pool_) CYDoWhile($5, $2); }
;
-
+/* }}} */
+/* 12.6.2 The while Statement {{{ */
WhileStatement
: "while" "(" Expression ")" Statement { $$ = new(driver.pool_) CYWhile($3, $5); }
;
-
+/* }}} */
+/* 12.6.3 The for Statement {{{ */
ForStatement
: "for" "(" ForStatementInitialiser ";" ExpressionOpt ";" ExpressionOpt ")" Statement { $$ = new(driver.pool_) CYFor($3, $5, $7, $9); }
;
: ExpressionNoInOpt { $$ = $1; }
| "var" VariableDeclarationListNoIn { $$ = $2; }
;
-
+/* }}} */
+/* 12.6.4 The for-in Statement {{{ */
ForInStatement
: "for" "(" ForInStatementInitialiser "in" Expression ")" Statement { $$ = new(driver.pool_) CYForIn($3, $5, $7); }
;
: LeftHandSideExpression { $$ = $1; }
| "var" VariableDeclarationNoIn { $$ = $2; }
;
+/* }}} */
+/* 12.7 The continue Statement {{{ */
ContinueStatement
: "continue" IdentifierOpt Terminator { $$ = new(driver.pool_) CYContinue($2); }
;
-
+/* }}} */
+/* 12.8 The break Statement {{{ */
BreakStatement
: "break" IdentifierOpt Terminator { $$ = new(driver.pool_) CYBreak($2); }
;
-
+/* }}} */
+/* 12.9 The return Statement {{{ */
ReturnStatement
: "return" ExpressionOpt Terminator { $$ = new(driver.pool_) CYReturn($2); }
;
-
+/* }}} */
+/* 12.10 The with Statement {{{ */
WithStatement
: "with" "(" Expression ")" Statement { $$ = new(driver.pool_) CYWith($3, $5); }
;
+/* }}} */
+/* 12.11 The switch Statement {{{ */
SwitchStatement
: "switch" "(" Expression ")" CaseBlock { $$ = new(driver.pool_) CYSwitch($3, $5); }
;
DefaultClause
: "default" ":" StatementListOpt { $$ = new(driver.pool_) CYClause(NULL, $3); }
;
-
+/* }}} */
+/* 12.12 Labelled Statements {{{ */
LabelledStatement
: Identifier ":" Statement { $3->AddLabel($1); $$ = $3; }
;
-
+/* }}} */
+/* 12.13 The throw Statement {{{ */
ThrowStatement
: "throw" Expression Terminator { $$ = new(driver.pool_) CYThrow($2); }
;
-
+/* }}} */
+/* 12.14 The try Statement {{{ */
TryStatement
: "try" Block_ CatchOpt FinallyOpt { $$ = new(driver.pool_) CYTry($2, $3, $4); }
;
: "finally" Block_ { $$ = $2; }
| { $$ = NULL; }
;
+/* }}} */
+/* 13 Function Definition {{{ */
FunctionDeclaration
: "function" Identifier "(" FormalParameterList ")" "{" FunctionBody "}" { $$ = new(driver.pool_) CYFunction($2, $4, $7); }
;
FunctionBody
: SourceElements { $$ = $1; }
;
-
+/* }}} */
+/* 14 Program {{{ */
Program
: SourceElements { driver.source_ = $1; }
;
: Statement { $$ = $1; }
| FunctionDeclaration { $$ = $1; }
;
+/* }}} */
/* Cycript: @class Declaration {{{ */
ClassSuperOpt