//JSON Object
//It has mandatory properties 'value' and 'type' plus optional
//properties 'lang', 'xml:lang' and 'datatype'
Node obj = null;
Token value = null, type = null, lang = null, datatype = null;
//First we expect to see the { character to start the JSON Object
if (lookingAt(TokenType.LBRACE))
{
//Discard the {
nextToken();
//Then see a stream of tokens which are property value pairs
//representing the properties of the object
boolean first = true;
boolean propertyNameExpected = true;
while (true)
{
if (isPropertyName())
{
first = false;
propertyNameExpected = false;
Token t = nextToken();
String name = t.getImage();
//Must always be a : after a property name
checkColon();
//Is this one of our valid properties
if (name.equals("value"))
{
if (value == null)
{
value = checkValidForObjectProperty();
}
else
{
exception(t, "Encountered the value property on an Object when the value property has already been specified") ;
}
}
else if (name.equals("type"))
{
if (type == null)
{
type = checkValidForObjectProperty();
}
else
{
exception(t, "Encountered the type property on an Object when the type property has already been specified") ;
}
}
else if (name.equals("lang") || name.equals("xml:lang"))
{
if (lang == null && datatype == null)
{
lang = checkValidForObjectProperty();
}
else
{
exception(t, "Encountered the %s property on an Object when lang/datatype has already been specified", name) ;
}
}
else if (name.equals("datatype"))
{
if (lang == null && datatype == null)
{
datatype = checkValidForObjectProperty();
}
else
{
exception(t, "Encountered the %s property on an Object when lang/datatype has already been specified", name) ;
}
}
else
{
exception(t, "Unexpected Property Name %s encountered, expected one of value, type, lang or datatype", t.getImage()) ;
}
//After each Property Value pair we may optionally
//see a comma to indicate further pairs are present
if (lookingAt(TokenType.COMMA))