Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
385 lines (346 sloc) 8.74 KB
/*
* 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<String, Object> parseObject() throws ParseException {
java.util.LinkedHashMap<String, Object> 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<Object> parseArray() throws ParseException {
java.util.ArrayList<Object> 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: {
<C_SINGLE_COMMENT: "//" (~["\n","\r","\f"])* <EOL>>
| <C_MULTILINE_COMMENT: "/*" (~[])* "*/">
| <SH_SINGLE_COMMENT: "#" (~["\n","\r","\f"])* <EOL>>
| <WHITESPACE: " " | "\t">
| <EOL: "\n" | "\r" | "\f">
}
// Common tokens
TOKEN: {
<COMMA: ",">
}
// Object tokens
TOKEN:{
<BRACE_OPEN: "{">
| <BRACE_CLOSE: "}">
| <COLON: ":">
}
// Array tokens
TOKEN:{
<BRACKET_OPEN: "[">
| <BRACKET_CLOSE: "]">
}
// Number token
TOKEN:{
<#ZERO: "0">
| <#DIGIT_NONZERO: ["1"-"9"]>
| <#DIGIT: (<DIGIT_NONZERO> | <ZERO>) >
| <NUMBER_INTEGER:
("-")?
( (<ZERO>)+ | ( <DIGIT_NONZERO> (<DIGIT>)* ) )
>
| <NUMBER_DECIMAL:
("-")?
( (<ZERO>)+ | ( <DIGIT_NONZERO> (<DIGIT>)* ) )
("."
(<DIGIT>)+
(
["e","E"]
("+" | "-")?
(<DIGIT>)+
)?
)
>
}
// Boolean tokens
TOKEN:{
<TRUE: "true">
| <FALSE: "false">
}
// Null token
TOKEN:{
<NULL: "null">
}
// String tokens
TOKEN:{
<#QUOTE_DOUBLE: "\"">
| <#QUOTE_SINGLE: "'">
| <STRING_SINGLE_EMPTY: "''">
| <STRING_DOUBLE_EMPTY: "\"\"">
| <#STRING_SINGLE_BODY: (
(~["'","\\","\r","\n","\f","\t"]) |
( "\\" ( "r" | "n" | "f" | "\\" | "/" | "'" | "b" | "t" ) )
)+>
| <#STRING_DOUBLE_BODY: (
(~["\"","\\","\r","\n","\f","\t"]) |
( "\\" ( "r" | "n" | "f" | "\\" | "/" | "\"" | "b" | "t" ) )
)+>
| <STRING_SINGLE_NONEMPTY: <QUOTE_SINGLE> <STRING_SINGLE_BODY> <QUOTE_SINGLE>>
| <STRING_DOUBLE_NONEMPTY: <QUOTE_DOUBLE> <STRING_DOUBLE_BODY> <QUOTE_DOUBLE>>
}
// Raw symbol tokens
TOKEN:{
<SYMBOL: (["a"-"z", "A"-"Z", "0", "1"-"9"])+ >
}
boolean ensureEOF() : {}{
<EOF>
{ 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<String, Object> object() : {
final java.util.LinkedHashMap<String, Object> map = new java.util.LinkedHashMap<String, Object>();
String key;
Object value;
}{
<BRACE_OPEN>
[
key = objectKey()
<COLON>
value = anything()
{ map.put(key, value); }
{ key = null; value = null; }
(
<COMMA>
key = objectKey()
<COLON>
value = anything()
{ map.put(key, value); }
{ key = null; value = null; }
)*
]
<BRACE_CLOSE>
{ return map; }
}
java.util.ArrayList<Object> list() : {
final java.util.ArrayList<Object> list = new java.util.ArrayList<Object>();
Object value;
}{
<BRACKET_OPEN>
[
value = anything()
{ list.add(value); }
{ value = null; }
(
<COMMA>
value = anything()
{ list.add(value); }
{ value = null; }
)*
]
<BRACKET_CLOSE>
{
list.trimToSize();
return list;
}
}
Object value() : {
Object x;
}{
( x = string()
| x = number()
| x = booleanValue()
| x = nullValue()
)
{ return x; }
}
Object nullValue(): {}{
<NULL>
{ return null; }
}
Boolean booleanValue(): {
Boolean b;
}{
(
(
<TRUE>
{ b = Boolean.TRUE; }
) | (
<FALSE>
{ b = Boolean.FALSE; }
)
)
{ return b; }
}
Number number(): {
Token t;
}{
(
t = <NUMBER_DECIMAL>
{
if (nativeNumbers) {
return new Long(t.image);
} else {
return new java.math.BigDecimal(t.image);
}
}
) | (
t = <NUMBER_INTEGER>
{
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() : {
}{
(
<STRING_DOUBLE_EMPTY>
{ return ""; }
) | (
<STRING_DOUBLE_NONEMPTY>
{
String image = token.image;
return image.substring(1, image.length() - 1);
}
)
}
String singleQuoteString() : {
}{
(
<STRING_SINGLE_EMPTY>
{ return ""; }
) | (
<STRING_SINGLE_NONEMPTY>
{
String image = token.image;
return image.substring(1, image.length() - 1);
}
)
}
String symbol() : {
}{
<SYMBOL>
{ return token.image; }
}
You can’t perform that action at this time.