From cb02f8aec13cb7ffea9631c401293e80447e6ae7 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Sun, 25 Oct 2009 19:35:14 +0000 Subject: [PATCH] Began work on implementing E4X. --- Cycript.l => Cycript.l.in | 73 ++++++++++++++--------- Cycript.y.in | 120 +++++++++++++++++++++++++++++++++++++- Parser.hpp | 5 +- makefile | 5 +- 4 files changed, 170 insertions(+), 33 deletions(-) rename Cycript.l => Cycript.l.in (90%) diff --git a/Cycript.l b/Cycript.l.in similarity index 90% rename from Cycript.l rename to Cycript.l.in index c2142bd..f3201bb 100644 --- a/Cycript.l +++ b/Cycript.l.in @@ -1,4 +1,6 @@ %{ +// XXX: supposedly I will be screwed on very very long multi-line comments and need to replace these with a manual lexer. http://websrv.cs.fsu.edu/~engelen/courses/COP5621/Pr2.pdf + #define YYLTYPE cy::location #include "Cycript.tab.hh" typedef cy::parser::token tk; @@ -28,6 +30,22 @@ typedef cy::parser::token tk; yyextra->state_ = CYNewLine; \ } +#define M { \ + if (const char *nl = reinterpret_cast(memchr(yytext, '\n', yyleng))) { \ + unsigned lines(0); \ + size_t left; \ + do { \ + ++lines; \ + left = yyleng - (nl - yytext) - 1; \ + nl = reinterpret_cast(memchr(nl + 1, '\n', left)); \ + } while (nl != NULL); \ + yylloc->end.lines(lines); \ + yylloc->end.columns(left); \ + yylloc->step(); \ + N \ + } else L \ +} + #define L { \ yylloc->step(); \ yylloc->columns(yyleng); \ @@ -88,38 +106,32 @@ RegularExpressionEnd_ \/{RegularExpressionFlags} RegularExpressionRest_ {RegularExpressionBody_}{RegularExpressionEnd_} RegularExpressionStart_ {RegularExpressionBody}{RegularExpressionEnd_} -%x res -%x rer +%x RegExp +%x RegExpSlash +%x RegExpSlashEqual +%x RegExpSlashRight %% -{RegularExpressionStart_} E("/") -{RegularExpressionRest_} E("/=") +{RegularExpressionStart_} E("/") +{RegularExpressionRest_} E("/=") +{RegularExpressionRest_} E("/>") \/\/[^\n]* L +\/\*(\n|[^\*]|\*[^/])*\*\/ M -\/\*(\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 - - if (const char *nl = reinterpret_cast(memchr(yytext, '\n', yyleng))) { - unsigned lines(0); - size_t left; - - do { - ++lines; - left = yyleng - (nl - yytext) - 1; - nl = reinterpret_cast(memchr(nl + 1, '\n', left)); - } while (nl != NULL); - - yylloc->end.lines(lines); - yylloc->end.columns(left); - yylloc->step(); - - N - } else L -} +@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; "&&" L C return tk::AmpersandAmpersand; @@ -175,9 +187,11 @@ RegularExpressionStart_ {RegularExpressionBody}{RegularExpressionEnd_} "[" L C return tk::OpenBracket; "]" L C return tk::CloseBracket; +@begin ObjectiveC "@class" L C return tk::AtClass; "@end" L C return tk::AtEnd; "@selector" L C return tk::AtSelector; +@end "false" L C yylval->false_ = new(yyextra->pool_) CYFalse(); return tk::False; "null" L C yylval->null_ = new(yyextra->pool_) CYNull(); return tk::Null; @@ -321,11 +335,14 @@ void CYDriver::SetCondition(Condition condition) { struct yyguts_t *yyg(reinterpret_cast(scanner_)); switch (condition) { - case RegExStart: - BEGIN(res); + case RegExpSlash: + BEGIN(RegExpSlash); + break; + case RegExpSlashEqual: + BEGIN(RegExpSlashEqual); break; - case RegExRest: - BEGIN(rer); + case RegExpSlashRight: + BEGIN(RegExpSlashRight); break; default: _assert(false); diff --git a/Cycript.y.in b/Cycript.y.in index a0ce2cc..7918f27 100644 --- a/Cycript.y.in +++ b/Cycript.y.in @@ -124,7 +124,17 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner); %parse-param { CYDriver &driver } %lex-param { void *scanner } +@begin E4X %token At "@" +%token ColonColon "::" +%token LeftRight "<>" +%token LeftSlashRight "" +%token PeriodPeriod ".." + +%token XMLCDATA +%token XMLComment +%token XMLPI +@end %token Ampersand "&" %token AmpersandAmpersand "&&" @@ -577,8 +587,11 @@ IdentifierOpt ; RegularExpressionToken - : "/" { $$ = CYDriver::RegExStart; } - | "/=" { $$ = CYDriver::RegExRest; } + : "/" { $$ = CYDriver::RegExpSlash; } + | "/=" { $$ = CYDriver::RegExpSlashEqual; } +@begin E4X + | "/>" { $$ = CYDriver::RegExpSlashRight; } +@end ; RegularExpressionLiteral_ @@ -1461,6 +1474,109 @@ MemberAccess /* }}} */ @end +@begin E4X +/* 8.3 XML Initialiser Input Elements {{{ */ +XMLMarkup + : XMLComment + | XMLCDATA + | XMLPI + ; +/* }}} */ +/* 11.1 Primary Expressions {{{ */ +PrimaryExpression_ + : PropertyIdentifier + | XMLInitialiser + | XMLListInitialiser + ; + +PropertyIdentifier + : AttributeIdentifier + | QualifiedIdentifier + | WildcardIdentifier + ; +/* }}} */ +/* 11.1.1 Attribute Identifiers {{{ */ +AttributeIdentifier + : "@" PropertySelector + | "@" QualifiedIdentifier + | "@" "[" Expression "]" + ; + +PropertySelector + : Identifier + | WildcardIdentifier + ; +/* }}} */ +/* 11.1.2 Qualified Identifiers {{{ */ +QualifiedIdentifier + : PropertySelector "::" PropertySelector + | PropertySelector "::" "[" Expression "]" + ; +/* }}} */ +/* 11.1.3 Wildcard Identifiers {{{ */ +WildcardIdentifier + : "*" + ; +/* }}} */ +/* 11.1.4 XML Initialiser {{{ */ +XMLInitialiser + : XMLMarkup + | XMLElement + ; + +XMLElement + : "<" XMLTagContent XMLWhitespaceOpt "/>" + | "<" XMLTagContent XMLWhitespace ">" XMLElementContentOpt "" + ; + +XMLTagContent + : XMLTagName XMLAttributesOpt + ; + +XMLTagName + : "{" Expression "}" + | XMLName + ; + +XMLAttributes + : XMLWhitespace "{" Expression "}" + | XMLAttributeOpt XMLAttributes + ; + +XMLAttributesOpt + : XMLAttributes + | + ; + +XMLAttribute + : XMLWhitespace XMLName XMLWhitespaceOpt "=" XMLWhitespaceOpt "{" Expression "}" + | XMLWhitespace XMLName XMLWhitespaceOpt "=" XMLWhitespaceOpt XMLAttributeValue + ; + +XMLAttributeOpt + : XMLAttribute + | + ; + +XMLElementContent + : "{" Expression "}" XMLElementContentOpt + | XMLMarkup XMLElementContentOpt + | XMLText XMLElementContentOpt + | XMLElement XMLElementContentOpt + ; + +XMLElementContentOpt + : XMLElementContent + | + ; +/* }}} */ +/* 11.1.5 XMLList Initialiser {{{ */ +XMLListInitialiser + : "<>" XMLElementContent "" + ; +/* }}} */ +@end + /* ECMAScript5: Object Literal Trailing Comma {{{ */ PropertyNameAndValueList_ : "," { $$ = NULL; } diff --git a/Parser.hpp b/Parser.hpp index 86b7d17..578b515 100644 --- a/Parser.hpp +++ b/Parser.hpp @@ -310,8 +310,9 @@ class CYDriver { bool strict_; enum Condition { - RegExStart, - RegExRest + RegExpSlash, + RegExpSlashEqual, + RegExpSlashRight, }; std::string filename_; diff --git a/makefile b/makefile index fbcc62f..f85f998 100644 --- a/makefile +++ b/makefile @@ -89,7 +89,10 @@ libcycript.plist: Bridge.def echo '})'; \ } >$@ -Cycript.y: Cycript.y.in +%.y: %.y.in + ./Filter.sh <$< >$@ $(filters) + +%.l: %.l.in ./Filter.sh <$< >$@ $(filters) Cycript.tab.cc Cycript.tab.hh location.hh position.hh: Cycript.y -- 2.47.2