All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.tomcat.util.json.JSONParser.jj Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

options {
    CHOICE_AMBIGUITY_CHECK=3;
    OTHER_AMBIGUITY_CHECK=2;
    ERROR_REPORTING=true;
    JAVA_UNICODE_ESCAPE=true;
    UNICODE_INPUT=true;
    IGNORE_CASE=true;
    SUPPORT_CLASS_VISIBILITY_PUBLIC=true;
    FORCE_LA_CHECK=true;
    CACHE_TOKENS=true;
    SANITY_CHECK=true;
    STATIC=false;
}

PARSER_BEGIN(JSONParser)

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.tomcat.util.json;

/**
* Basic JSON parser generated by JavaCC. It consumes the input provided through the constructor when
* {@code parseObject()}, {@code parseList()}, or {@code parse()} are called, and there is no way to directly
* reset the state.
*/
@SuppressWarnings("all") // Ignore warnings in generated code
public class JSONParser {

    protected static final org.apache.tomcat.util.res.StringManager sm = org.apache.tomcat.util.res.StringManager.getManager(JSONParser.class);

    private boolean nativeNumbers = false;

    public JSONParser(String input) {
        this(new java.io.StringReader(input));
    }

    /**
     * Parses a JSON object into a Java {@code Map}.
     */
    public java.util.LinkedHashMap parseObject() throws ParseException {
        java.util.LinkedHashMap toReturn = object();
        if (!ensureEOF()) {
            throw new IllegalStateException(sm.getString("parser.expectedEOF"));
        }
        return toReturn;
    }

    /**
     * Parses a JSON array into a Java {@code List}.
     */
    public java.util.ArrayList parseArray() throws ParseException {
        java.util.ArrayList toReturn = list();
        if (!ensureEOF()) {
            throw new IllegalStateException(sm.getString("parser.expectedEOF"));
        }
        return toReturn;
    }

    /**
     * Parses any JSON-parseable object, returning the value.
     */
    public Object parse() throws ParseException {
        Object toReturn = anything();
        if (!ensureEOF()) {
            throw new IllegalStateException(sm.getString("parser.expectedEOF"));
        }
        return toReturn;
    }

    private static String substringBefore(String str, char delim) {
        int pos = str.indexOf(delim);
        if (pos == -1) {
            return str;
        }
        return str.substring(0, pos);
    }

    public void setNativeNumbers(boolean value) {
        this.nativeNumbers = value;
    }

    public boolean getNativeNumbers() {
        return this.nativeNumbers;
    }

}

PARSER_END(JSONParser)

// Ignore comments
SKIP: {
    >
| 
| >
| 
| 
}

// Common tokens
TOKEN: {
    
}

// Object tokens
TOKEN:{
    
| 
| 
}

// Array tokens
TOKEN:{
    
| 
}

// Number token
TOKEN:{
    <#ZERO: "0">
| <#DIGIT_NONZERO: ["1"-"9"]>
| <#DIGIT: ( | ) >
| )+ | (  ()* ) )
    >
| )+ | (  ()* ) )
        ("."
            ()+
            (
                ["e","E"]
                ("+" | "-")?
                ()+
            )?
        )
    >
}

// Boolean tokens
TOKEN:{
    
| 
}

// Null token
TOKEN:{
    
}

// String tokens
TOKEN:{
    <#QUOTE_DOUBLE: "\"">
| <#QUOTE_SINGLE: "'">
| 
| 
| <#STRING_SINGLE_BODY: (
        (~["'","\\","\r","\n","\f","\t"]) |
        ( "\\" ( "r" | "n" | "f" | "\\" | "/" | "'" | "b" | "t" ) )
    )+>
| <#STRING_DOUBLE_BODY: (
        (~["\"","\\","\r","\n","\f","\t"]) |
        ( "\\" ( "r" | "n" | "f" | "\\" | "/" | "\"" | "b" | "t" ) )
    )+>
|   >
|   >
}

// Raw symbol tokens
TOKEN:{
    
}


boolean ensureEOF() : {}{
    
    { return true; }
}

Object anything() : {
    Object x;
}{
    ( x = object()
    | x = list()
    | x = value()
    )
    { return x; }
}

String objectKey() : {
    Object o;
    String key;
} {
    (
        key = string()
    | key = symbol()
    | (
        nullValue()
        { key = null; }
        )
    | (
            ( o = booleanValue() | o = number() )
            { key = o.toString(); }
        )
    )
    { return key; }
}

java.util.LinkedHashMap object() : {
    final java.util.LinkedHashMap map = new java.util.LinkedHashMap();
    String key;
    Object value;
}{
    
    [
        key = objectKey()
        
        value = anything()
        { map.put(key, value); }
        { key = null; value = null; }
        (
            
            key = objectKey()
            
            value = anything()
            { map.put(key, value); }
            { key = null; value = null; }
        )*
    ]
    
    { return map; }
}

java.util.ArrayList list() : {
    final java.util.ArrayList list = new java.util.ArrayList();
    Object value;
}{
    
    [
        value = anything()
        { list.add(value); }
        { value = null; }
        (
            
            value = anything()
            { list.add(value); }
            { value = null; }
        )*
    ]
    
    {
        list.trimToSize();
        return list;
    }
}

Object value() : {
    Object x;
}{
    ( x = string()
    | x = number()
    | x = booleanValue()
    | x = nullValue()
    )
    { return x; }
}

Object nullValue(): {}{
    
    { return null; }
}

Boolean booleanValue(): {
    Boolean b;
}{
    (
        (
            
            { b = Boolean.TRUE; }
        ) | (
            
            { b = Boolean.FALSE; }
        )
    )
    { return b; }
}

Number number(): {
    Token t;
}{
    (
        t = 
        {
            if (nativeNumbers) {
                return new Long(t.image);
            } else {
                return new java.math.BigDecimal(t.image);
            }
        }
    ) | (
        t = 
        {
            if (nativeNumbers) {
                return new Double(t.image);
            } else {
                return new java.math.BigInteger(substringBefore(t.image, '.'));
            }
        }
    )
}

String string() : {
    String s;
}{
    ( s = doubleQuoteString()
    | s = singleQuoteString()
    )
    { return s; }
}

String doubleQuoteString() : {
}{
    (
        
        { return ""; }
    ) | (
        
        {
            String image = token.image;
            return image.substring(1, image.length() - 1);
        }
    )
}

String singleQuoteString() : {
}{
    (
        
        { return ""; }
    ) | (
        
        {
            String image = token.image;
            return image.substring(1, image.length() - 1);
        }
    )
}

String symbol() : {
}{
    
    { return token.image; }
}