Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2009 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef LiteralParser_h
     27 #define LiteralParser_h
     28 
     29 #include "JSGlobalObjectFunctions.h"
     30 #include "JSValue.h"
     31 #include "UString.h"
     32 
     33 namespace JSC {
     34 
     35     class LiteralParser {
     36     public:
     37         typedef enum { StrictJSON, NonStrictJSON } ParserMode;
     38         LiteralParser(ExecState* exec, const UString& s, ParserMode mode)
     39             : m_exec(exec)
     40             , m_lexer(s, mode)
     41             , m_mode(mode)
     42         {
     43         }
     44 
     45         JSValue tryLiteralParse()
     46         {
     47             m_lexer.next();
     48             JSValue result = parse(m_mode == StrictJSON ? StartParseExpression : StartParseStatement);
     49             if (m_lexer.currentToken().type != TokEnd)
     50                 return JSValue();
     51             return result;
     52         }
     53     private:
     54         enum ParserState { StartParseObject, StartParseArray, StartParseExpression,
     55                            StartParseStatement, StartParseStatementEndStatement,
     56                            DoParseObjectStartExpression, DoParseObjectEndExpression,
     57                            DoParseArrayStartExpression, DoParseArrayEndExpression };
     58         enum TokenType { TokLBracket, TokRBracket, TokLBrace, TokRBrace,
     59                          TokString, TokIdentifier, TokNumber, TokColon,
     60                          TokLParen, TokRParen, TokComma, TokTrue, TokFalse,
     61                          TokNull, TokEnd, TokError };
     62 
     63         class Lexer {
     64         public:
     65             struct LiteralParserToken {
     66                 TokenType type;
     67                 const UChar* start;
     68                 const UChar* end;
     69                 UString stringToken;
     70                 double numberToken;
     71             };
     72             Lexer(const UString& s, ParserMode mode)
     73                 : m_string(s)
     74                 , m_mode(mode)
     75                 , m_ptr(s.characters())
     76                 , m_end(s.characters() + s.length())
     77             {
     78             }
     79 
     80             TokenType next()
     81             {
     82                 return lex(m_currentToken);
     83             }
     84 
     85             const LiteralParserToken& currentToken()
     86             {
     87                 return m_currentToken;
     88             }
     89 
     90         private:
     91             TokenType lex(LiteralParserToken&);
     92             template <ParserMode mode> TokenType lexString(LiteralParserToken&);
     93             TokenType lexNumber(LiteralParserToken&);
     94             LiteralParserToken m_currentToken;
     95             UString m_string;
     96             ParserMode m_mode;
     97             const UChar* m_ptr;
     98             const UChar* m_end;
     99         };
    100 
    101         class StackGuard;
    102         JSValue parse(ParserState);
    103 
    104         ExecState* m_exec;
    105         LiteralParser::Lexer m_lexer;
    106         ParserMode m_mode;
    107     };
    108 }
    109 
    110 #endif
    111