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

com.ibm.commons.util.io.json.parser.Json.jj Maven / Gradle / Ivy

The newest version!
options {
  JAVA_UNICODE_ESCAPE = false; // Should not pre parse the unicode escape
  UNICODE_INPUT = true; // Should accept unicode character from the Reader
  STATIC = false;
  JDK_VERSION = "1.5";
//  DEBUG_TOKEN_MANAGER=true;  
//  DEBUG_PARSER=true;
//  DEBUG_LOOKAHEAD=true;
//  MULTI = true;
//  NODE_DEFAULT_VOID=true;
}

PARSER_BEGIN(Json)


package com.ibm.commons.util.io.json.parser;

import com.ibm.commons.util.io.json.*;
import java.util.*;

/**
 *
 */
public class Json {

	public JsonFactory factory;
	
	public String getStringValue(String image) throws ParseException {
		int l = image.length()-1; // Leading & trailing quotes, see loop index starting at 1...
		StringBuilder sb = new StringBuilder(l);
		for (int i = 1; i < l; i++) {
			char c = image.charAt(i);
			if (c == '\\') {
				i++;
				if(i='0' && c<='7';
	}
	private static boolean isHexaDigit(char c) {
		return (c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f');
	}
	private static int hexval(char c) throws ParseException {
		switch (c) {
			case '0':
				return 0;
			case '1':
				return 1;
			case '2':
				return 2;
			case '3':
				return 3;
			case '4':
				return 4;
			case '5':
				return 5;
			case '6':
				return 6;
			case '7':
				return 7;
			case '8':
				return 8;
			case '9':
				return 9;
	
			case 'a':
			case 'A':
				return 10;
			case 'b':
			case 'B':
				return 11;
			case 'c':
			case 'C':
				return 12;
			case 'd':
			case 'D':
				return 13;
			case 'e':
			case 'E':
				return 14;
			case 'f':
			case 'F':
				return 15;
		}
        throw new ParseException("Internal error when evaluating hexadecimal escape sequence"); // $NLS-ASTLiteral.Internalerrorwhenevaluatinghexade-1$
	}

	private static int octval(char c) throws ParseException {
		switch (c) {
			case '0':
				return 0;
			case '1':
				return 1;
			case '2':
				return 2;
			case '3':
				return 3;
			case '4':
				return 4;
			case '5':
				return 5;
			case '6':
				return 6;
			case '7':
				return 7;
			case '8':
				return 8;
			case '9':
				return 9;
		}
        throw new ParseException("Internal error when evaluating octal escape sequence"); // $NLS-ASTLiteral.Internalerrorwhenevaluatingoctale-1$
	}

}// end of Json

PARSER_END(Json)

/* WHITE SPACES */
SKIP: {
  " "
| "\t"
| "\f"
| "\u000b"
}

SPECIAL_TOKEN: {
  
}

/* COMMENTS */

MORE :
{

//  "//" : IN_SINGLE_LINE_COMMENT
//|
  <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT
|
  "/*" : IN_MULTI_LINE_COMMENT
}



SPECIAL_TOKEN :
{
   {input_stream.backup(1);} : DEFAULT
}

SPECIAL_TOKEN :{
// <"//" (~["\n","\r"])* (["\n","\r"])? > {input_stream.backup(1);}
 <"//" (~["\n","\r"])*> {}
}


SPECIAL_TOKEN :
{
   : DEFAULT
}


SPECIAL_TOKEN :
{
   : DEFAULT
}


MORE :
{
  < ~[] >
}
  
/* LITERALS */

TOKEN: {
   < FALSE: "false" >
  | < NULL: "null" >
  | < TRUE: "true" >
}


/* LITERALS */

TOKEN: {
  < INTEGER_LITERAL:
         (["l","L"])?
      |  (["l","L"])?
      |  (["l","L"])?
  >
| < #DECIMAL_LITERAL: ("-")? ["1"-"9"] (["0"-"9"])* >
| < #HEX_LITERAL: ("-")? "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
| < #OCTAL_LITERAL: ("-")? "0" (["0"-"7"])* >
| < FLOATING_POINT_LITERAL:
        ("-")? (["0"-"9"])+ "." (["0"-"9"])* ()? (["f","F","d","D"])?
      | ("-")? "." (["0"-"9"])+ ()? (["f","F","d","D"])?
      | ("-")? (["0"-"9"])+  (["f","F","d","D"])?
      | ("-")? (["0"-"9"])+ ()? ["f","F","d","D"]
  >
| < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
| < STRING_LITERAL:
        "\""
        (   (~["\"","\\","\n","\r"])
        | 
        )*
        "\""
// Extension to JSON: we support single quotes as well
      | "'"
        (   (~["'","\\","\n","\r"])
        | 
        )*
        "'"
  >
| < #ESCAPE_SEQUENCE: // Maybe x and u could be x,X and u,U
      "\\"
        ( ~["\b","\f","\n","\r","\t","\u000B"]
        | ["0"-"7"] ( ["0"-"7"] )?
        | ["0"-"3"] ["0"-"7"] ["0"-"7"]
        | ["x"] ["0"-"9","a"-"f","A"-"F"] ["0"-"9","a"-"f","A"-"F"]
        | ["u"] ["0"-"9","a"-"f","A"-"F"] ["0"-"9","a"-"f","A"-"F"] ["0"-"9","a"-"f","A"-"F"] ["0"-"9","a"-"f","A"-"F"]
        )
  >
}

/* IDENTIFIERS */

TOKEN :
{
  < IDENTIFIER: (|"@") (|)* >
|
  < #LETTER:
      [
       "\u0024",
       "\u0041"-"\u005a",
       "\u005f",
       "\u0061"-"\u007a",
       "\u00c0"-"\u00d6",
       "\u00d8"-"\u00f6",
       "\u00f8"-"\u00ff",
       "\u0100"-"\u1fff",
       "\u3040"-"\u318f",
       "\u3300"-"\u337f",
       "\u3400"-"\u3d2d",
       "\u4e00"-"\u9fff",
       "\uf900"-"\ufaff"
      ]
  >
|
  < #DIGIT:
      [
       "\u0030"-"\u0039",
       "\u0660"-"\u0669",
       "\u06f0"-"\u06f9",
       "\u0966"-"\u096f",
       "\u09e6"-"\u09ef",
       "\u0a66"-"\u0a6f",
       "\u0ae6"-"\u0aef",
       "\u0b66"-"\u0b6f",
       "\u0be7"-"\u0bef",
       "\u0c66"-"\u0c6f",
       "\u0ce6"-"\u0cef",
       "\u0d66"-"\u0d6f",
       "\u0e50"-"\u0e59",
       "\u0ed0"-"\u0ed9",
       "\u1040"-"\u1049"
      ]
  >
}


/* SEPARATORS */
TOKEN: {
    < LBRACE: "{" >
  | < RBRACE: "}" >
  | < LBRACKET: "[" >
  | < RBRACKET: "]" >
  | < COLON: ":" >
  | < COMMA: "," >
  }

Object nullLiteral() throws JsonException: 
    {}
    {
        "null" {return factory.createNull();}
    }

Object booleanLiteral() throws JsonException:
    {}
    {
        "true"   {return factory.createBoolean(true);}
        |"false" {return factory.createBoolean(false);}
    }

Object numericLiteral() throws JsonException:
    {Token t;}
    {
        t=
        {
         	String image=t.image;
         	if (image.startsWith("0x") || image.startsWith("0X") ) {
				String imageWithout0x = image.substring(2);
				return factory.createNumber((Long.parseLong(imageWithout0x, 16)));
         	} else if (image.startsWith("0") && !image.equals("0") && !image.startsWith("0.") ){
				String imageWithout0 = image.length()>1 ? image.substring(1) : image;
				return factory.createNumber((Long.parseLong(imageWithout0, 8)));
         	} else {
				return factory.createNumber((Double.parseDouble(image)));
         	}
        }
        |t=
        {
			return factory.createNumber((Double.parseDouble(t.image)));
        }
    }

Object stringLiteral() throws JsonException:
    {Token t;}
    {
        t=
        {
            return factory.createString(getStringValue(t.image));
        }
    }

Object literal(Object parent, String property) throws JsonException:
    {Object value;}
    {
      (   value=nullLiteral()
        |value=booleanLiteral()
        |value=numericLiteral()
        |value=stringLiteral()
        |value=objectLiteral(parent,property)
        |value=arrayLiteral(parent,property)
      ){
        return value;
      }
    }


Object objectLiteral(Object parent, String property) throws JsonException: 
	{Object object;}
    {
        "{" 	
        		{ object = factory.createObject(parent,property); }
        [propertyNameAndValueList(object)] 
        "}" 
       			{return object;}
    }

void propertyNameAndValueList(Object parent)throws JsonException:
    {String name; Object value; }	
    {
        ( name=propertyName() ":" value=literal(parent,name) ) 
    {
          factory.setProperty(parent, name, value);
    }
	( "," name=propertyName() ":" value=literal(parent,name) 
    {
          factory.setProperty(parent, name, value);
    })*
}

String propertyName():
    {Token t;}
    {
         // JSON extension: we support identifier not enquoted
         t=
        {
            return t.image;
        }
        |t=
        {
            return getStringValue(t.image);
        }
    }

Object arrayLiteral(Object parent, String property)throws JsonException:
	{List array;
     int count=0; 
    }
    {
        "[" {array = factory.createTemporaryArray(parent); }
          count=elision()
          {
           for(int i=0; i the array is like [,,,,] so we must add an empty member at the end.
			int cnt = array.size();
            if(cnt==count && count!=0){
           		array.add(factory.createNull());
            }
          }
        "]"
        {
            return factory.createArray(parent,property,array);
        }
    }


void elementList(Object parent, String property, List array)throws JsonException:
    {int count=0; Object value;
    }
    {
        (
          value=literal(parent,property)
          {
           	  array.add(value);
          }
          count=elision()
          {
          	if(count>0) {
           		for(int i=0; i0){// take the last ',' into account
          	array.add(factory.createNull());
          }
        }
    }


int elision():
    {int count=0;}
    {
        (
         ","
         { count++;}
        )*
        {
            return count;
        }
    }

Object parseJsonLiteral()throws JsonException:
    {Object object;}
    {
        object=literal(null,null) 
        	{return object;}
    }

Object parseJson()throws JsonException:
    {Object object;}
    {
      (
         object=objectLiteral(null,null)
        |object=arrayLiteral(null,null)

        |object=nullLiteral()		// extension to JSON
        |object=booleanLiteral()	// extension to JSON
        |object=numericLiteral()	// extension to JSON
        |object=stringLiteral()		// extension to JSON
      	|"(" object=parseJson() ")" // extension to JSON
      ){
        return object;
       }
    }

void parseJsonList(List list) throws JsonException:
    { Object value; }
    {
        (
          	value=parseJson()
          	{
         		if(list!=null) {
					list.add(value);
				}
			}
        )*
      	  
    }

void parseJsonCallback(com.ibm.commons.util.io.json.JsonParser.ParseCallback callback) throws JsonException:
    { Object value; }
    {
        (
          	value=parseJson()
          	{
         		if(callback!=null) {
					callback.jsonEntry(value);
				}
			}
        )*
      	  
    }