From db5e284073ce1f951343c5825a7e4d64d159582b Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Thu, 1 Oct 2009 00:23:57 +0000 Subject: [PATCH] Unified scanner state. --- Cycript.l | 202 +++++++++++++++++++++++++++-------------------------- Library.mm | 6 +- Parser.hpp | 9 ++- 3 files changed, 111 insertions(+), 106 deletions(-) diff --git a/Cycript.l b/Cycript.l index 45dbe3e..08b7cd5 100644 --- a/Cycript.l +++ b/Cycript.l @@ -2,9 +2,11 @@ #include "Cycript.tab.hh" typedef cy::parser::token tk; #define YY_EXTRA_TYPE CYDriver * -#define N yylval->newline_ = yyextra->newline_; yyextra->newline_ = false; yyextra->restricted_ = false; -#define R yyextra->restricted_ = true; -#define L { bool restricted(yyextra->restricted_); yyextra->restricted_ = false; if (restricted) return tk::NewLine; else yyextra->newline_ = true; } + +#define T yylval->newline_ = yyextra->state_ == CYNewLine; +#define C T yyextra->state_ = CYClear; +#define R T yyextra->state_ = CYRestricted; +#define N { bool restricted(yyextra->state_ == CYRestricted); if (restricted) { yyextra->state_ = CYClear; return tk::NewLine; } else yyextra->state_ = CYNewLine; } %} %option prefix="cy" @@ -22,103 +24,103 @@ Escape \\['"\\bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4} %% \/\/[^\n]* ; -\/\*(\n|[^\*]|\*[^/])\*\/ if (memchr(yytext, '\n', yyleng) != NULL) L // 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 :( - -"&" N return tk::Ampersand; -"&&" N return tk::AmpersandAmpersand; -"&=" N return tk::AmpersandEqual; -"^" N return tk::Carrot; -"^=" N return tk::CarrotEqual; -"=" N return tk::Equal; -"==" N return tk::EqualEqual; -"===" N return tk::EqualEqualEqual; -"!" N return tk::Exclamation; -"!=" N return tk::ExclamationEqual; -"!==" N return tk::ExclamationEqualEqual; -"-" N return tk::Hyphen; -"-=" N return tk::HyphenEqual; -"--" N return yylval->newline_ ? tk::HyphenHyphen_ : tk::HyphenHyphen; -"->" N return tk::HyphenRight; -"<" N return tk::Left; -"<=" N return tk::LeftEqual; -"<<" N return tk::LeftLeft; -"<<=" N return tk::LeftLeftEqual; -"%" N return tk::Percent; -"%=" N return tk::PercentEqual; -"." N return tk::Period; -"|" N return tk::Pipe; -"|=" N return tk::PipeEqual; -"||" N return tk::PipePipe; -"+" N return tk::Plus; -"+=" N return tk::PlusEqual; -"++" N return yylval->newline_ ? tk::PlusPlus_ : tk::PlusPlus; -">" N return tk::Right; -">=" N return tk::RightEqual; -">>" N return tk::RightRight; -">>=" N return tk::RightRightEqual; -">>>" N return tk::RightRightRight; -">>>=" N return tk::RightRightRightEqual; -"/" N return tk::Slash; -"/=" N return tk::SlashEqual; -"*" N return tk::Star; -"*=" N return tk::StarEqual; -"~" N return tk::Tilde; - -":" N return tk::Colon; -"," N return tk::Comma; -"?" N return tk::Question; -";" N return tk::SemiColon; - -"(" N return tk::OpenParen; -")" N return tk::CloseParen; - -"{" N return tk::OpenBrace; -"}" N return tk::CloseBrace; - -"[" N return tk::OpenBracket; -"]" N return tk::CloseBracket; - -"break" N R yylval->word_ = new CYWord("break"); return tk::Break; -"case" N yylval->word_ = new CYWord("case"); return tk::Case; -"catch" N yylval->word_ = new CYWord("catch"); return tk::Catch; -"continue" N R yylval->word_ = new CYWord("continue"); return tk::Continue; -"default" N yylval->word_ = new CYWord("default"); return tk::Default; -"delete" N yylval->word_ = new CYWord("delete"); return tk::Delete; -"do" N yylval->word_ = new CYWord("do"); return tk::Do; -"else" N yylval->word_ = new CYWord("else"); return tk::Else; -"false" N yylval->false_ = new CYFalse(); return tk::False; -"finally" N yylval->word_ = new CYWord("finally"); return tk::Finally; -"for" N yylval->word_ = new CYWord("for"); return tk::For; -"function" N yylval->word_ = new CYWord("function"); return tk::Function; -"if" N yylval->word_ = new CYWord("if"); return tk::If; -"in" N yylval->word_ = new CYWord("in"); return tk::In; -"instanceof" N yylval->word_ = new CYWord("instanceof"); return tk::InstanceOf; -"new" N yylval->word_ = new CYWord("new"); return tk::New; -"null" N yylval->null_ = new CYNull(); return tk::Null; -"return" N R yylval->word_ = new CYWord("return"); return tk::Return; -"switch" N yylval->word_ = new CYWord("switch"); return tk::Switch; -"this" N yylval->this_ = new CYThis(); return tk::This; -"throw" N R yylval->word_ = new CYWord("throw"); return tk::Throw; -"true" N yylval->true_ = new CYTrue(); return tk::True; -"try" N yylval->word_ = new CYWord("try"); return tk::Try; -"typeof" N yylval->word_ = new CYWord("typeof"); return tk::TypeOf; -"var" N yylval->word_ = new CYWord("var"); return tk::Var; -"void" N yylval->word_ = new CYWord("void"); return tk::Void; -"while" N yylval->word_ = new CYWord("while"); return tk::While; -"with" N yylval->word_ = new CYWord("with"); return tk::With; - -[a-zA-Z$_][a-zA-Z$_0-9]* yylval->identifier_ = new CYIdentifier(apr_pstrmemdup(yyextra->pool_, yytext, yyleng)); N return tk::Identifier; - -(\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?){Exponent}? yylval->number_ = new CYNumber(strtod(yytext, NULL)); N return tk::NumericLiteral; - -0[xX][0-9a-fA-F]+ N yylval->number_ = new CYNumber(strtoull(yytext + 2, NULL, 16)); return tk::NumericLiteral; - -0[bB][0-1]+ N yylval->number_ = new CYNumber(strtoull(yytext + 2, NULL, 2)); return tk::NumericLiteral; - -\"([^"\\\n]|{Escape})*\" N return tk::StringLiteral; -'([^'\\\n]|{Escape})*' N return tk::StringLiteral; - -\n L +\/\*(\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 :( + +"&" C return tk::Ampersand; +"&&" C return tk::AmpersandAmpersand; +"&=" C return tk::AmpersandEqual; +"^" C return tk::Carrot; +"^=" C return tk::CarrotEqual; +"=" C return tk::Equal; +"==" C return tk::EqualEqual; +"===" C return tk::EqualEqualEqual; +"!" C return tk::Exclamation; +"!=" C return tk::ExclamationEqual; +"!==" C return tk::ExclamationEqualEqual; +"-" C return tk::Hyphen; +"-=" C return tk::HyphenEqual; +"--" C return yylval->newline_ ? tk::HyphenHyphen_ : tk::HyphenHyphen; +"->" C return tk::HyphenRight; +"<" C return tk::Left; +"<=" C return tk::LeftEqual; +"<<" C return tk::LeftLeft; +"<<=" C return tk::LeftLeftEqual; +"%" C return tk::Percent; +"%=" C return tk::PercentEqual; +"." C return tk::Period; +"|" C return tk::Pipe; +"|=" C return tk::PipeEqual; +"||" C return tk::PipePipe; +"+" C return tk::Plus; +"+=" C return tk::PlusEqual; +"++" C return yylval->newline_ ? tk::PlusPlus_ : tk::PlusPlus; +">" C return tk::Right; +">=" C return tk::RightEqual; +">>" C return tk::RightRight; +">>=" C return tk::RightRightEqual; +">>>" C return tk::RightRightRight; +">>>=" C return tk::RightRightRightEqual; +"/" C return tk::Slash; +"/=" C return tk::SlashEqual; +"*" C return tk::Star; +"*=" C return tk::StarEqual; +"~" C return tk::Tilde; + +":" C return tk::Colon; +"," C return tk::Comma; +"?" C return tk::Question; +";" C return tk::SemiColon; + +"(" C return tk::OpenParen; +")" C return tk::CloseParen; + +"{" C return tk::OpenBrace; +"}" C return tk::CloseBrace; + +"[" C return tk::OpenBracket; +"]" C return tk::CloseBracket; + +"break" R yylval->word_ = new CYWord("break"); return tk::Break; +"case" C yylval->word_ = new CYWord("case"); return tk::Case; +"catch" C yylval->word_ = new CYWord("catch"); return tk::Catch; +"continue" R yylval->word_ = new CYWord("continue"); return tk::Continue; +"default" C yylval->word_ = new CYWord("default"); return tk::Default; +"delete" C yylval->word_ = new CYWord("delete"); return tk::Delete; +"do" C yylval->word_ = new CYWord("do"); return tk::Do; +"else" C yylval->word_ = new CYWord("else"); return tk::Else; +"false" C yylval->false_ = new CYFalse(); return tk::False; +"finally" C yylval->word_ = new CYWord("finally"); return tk::Finally; +"for" C yylval->word_ = new CYWord("for"); return tk::For; +"function" C yylval->word_ = new CYWord("function"); return tk::Function; +"if" C yylval->word_ = new CYWord("if"); return tk::If; +"in" C yylval->word_ = new CYWord("in"); return tk::In; +"instanceof" C yylval->word_ = new CYWord("instanceof"); return tk::InstanceOf; +"new" C yylval->word_ = new CYWord("new"); return tk::New; +"null" C yylval->null_ = new CYNull(); return tk::Null; +"return" R yylval->word_ = new CYWord("return"); return tk::Return; +"switch" C yylval->word_ = new CYWord("switch"); return tk::Switch; +"this" C yylval->this_ = new CYThis(); return tk::This; +"throw" R yylval->word_ = new CYWord("throw"); return tk::Throw; +"true" C yylval->true_ = new CYTrue(); return tk::True; +"try" C yylval->word_ = new CYWord("try"); return tk::Try; +"typeof" C yylval->word_ = new CYWord("typeof"); return tk::TypeOf; +"var" C yylval->word_ = new CYWord("var"); return tk::Var; +"void" C yylval->word_ = new CYWord("void"); return tk::Void; +"while" C yylval->word_ = new CYWord("while"); return tk::While; +"with" C yylval->word_ = new CYWord("with"); return tk::With; + +[a-zA-Z$_][a-zA-Z$_0-9]* yylval->identifier_ = new CYIdentifier(apr_pstrmemdup(yyextra->pool_, yytext, yyleng)); C return tk::Identifier; + +(\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?){Exponent}? yylval->number_ = new CYNumber(strtod(yytext, NULL)); C return tk::NumericLiteral; + +0[xX][0-9a-fA-F]+ C yylval->number_ = new CYNumber(strtoull(yytext + 2, NULL, 16)); return tk::NumericLiteral; + +0[bB][0-1]+ C yylval->number_ = new CYNumber(strtoull(yytext + 2, NULL, 2)); return tk::NumericLiteral; + +\"([^"\\\n]|{Escape})*\" C return tk::StringLiteral; +'([^'\\\n]|{Escape})*' C return tk::StringLiteral; + +\n N [ \t] ; %% diff --git a/Library.mm b/Library.mm index 425c8e2..b818ad2 100644 --- a/Library.mm +++ b/Library.mm @@ -918,8 +918,7 @@ static JSStaticValue Pointer_staticValues[2] = { }; CYDriver::CYDriver(const std::string &filename) : - newline_(false), - restricted_(false), + state_(CYClear), filename_(filename), source_(NULL) { @@ -931,8 +930,7 @@ CYDriver::~CYDriver() { } void CYDriver::Clear() { - newline_ = false; - restricted_ = false; + state_ = CYClear; source_.clear(); pool_.Clear(); } diff --git a/Parser.hpp b/Parser.hpp index 6de5888..d7322aa 100644 --- a/Parser.hpp +++ b/Parser.hpp @@ -99,11 +99,16 @@ struct CYStatement : } }; +enum CYState { + CYClear, + CYRestricted, + CYNewLine +}; + class CYDriver { public: CYPool pool_; - bool newline_; - bool restricted_; + CYState state_; std::string filename_; std::vector source_; void *scanner_; -- 2.45.2