BNF for X3DRelaxedParser.jj

TOKENS

//---------------------------------------------------------------------------
//  TOKENS declaration
//---------------------------------------------------------------------------
<*> SKIP : {
" "
| "\t"
| "\n"
| "\r"
| "\f"
| ","
}

   
/* COMMENTS */
<DEFAULT> SPECIAL : {
<SINGLE_LINE_COMMENT: "#" ~["/"] (~["\n","\r"])* ("\n" | "\r" | "\r\n")> : DEFAULT
}

   
<DEFAULT> MORE : {
"#/*" : IN_MULTI_LINE_COMMENT
}

   
<IN_MULTI_LINE_COMMENT> SPECIAL : {
<MULTI_LINE_COMMENT: "*/#"> : DEFAULT
}

   
<IN_MULTI_LINE_COMMENT> MORE : {
<~[]>
}

   
<DEFAULT> TOKEN : {
<NUMBER_LITERAL: ("-")? (".")? ["0"-"9"] (["0"-"9","a"-"f","A"-"F","x",".","+","-"])*>
| <STRING_LITERAL: "\"" (~["\\","\""] | "\\" (["n","t","b","r","f","\\","\'","\""] | ["0"-"7"] (["0"-"7"])? | ["0"-"3"] ["0"-"7"] ["0"-"7"]))* "\"">
}

   
<DEFAULT> TOKEN : {
<LBRACE: "{">
| <RBRACE: "}">
| <LBRACKET: "[">
| <RBRACKET: "]">
}

   
<DEFAULT> TOKEN : {
<DEF: "DEF">
| <USE: "USE">
| <NULL: "NULL">
| <META: "META">
| <PROTO: "PROTO">
| <INPUT_ONLY: "inputOnly">
| <OUTPUT_ONLY: "outputOnly">
| <INITIALIZE_ONLY: "initializeOnly">
| <INPUT_OUTPUT: "inputOutput">
| <EXTERNPROTO: "EXTERNPROTO">
| <ROUTE: "ROUTE">
| <TO: "TO">
| <IS: "IS">
| <DOT: ".">
| <PROFILE: "PROFILE">
| <COMPONENT: "COMPONENT">
| <EXPORT: "EXPORT">
| <IMPORT: "IMPORT">
| <AS: "AS">
}

   
<DEFAULT> TOKEN : {
<SCRIPT: "Script">
| <TRUE: "TRUE">
| <FALSE: "FALSE">
}

   
<DEFAULT> TOKEN : {
<ID: <ID_FIRST> (<ID_REST>)*> : DEFAULT
| <#ID_FIRST: ["!","$"-"&","("-"*","/",":"-"Z","^"-"z","\u0080"-"\ufaff"]>
| <#ID_REST: ["!","$"-"&","("-"+","-","/"-"Z","^"-"z","|","~","\u0080"-"\ufaff"]>
}

   

NON-TERMINALS

// Grammar follows the structure in the ISO spec, except that TOKENS are
// at the bottom. Where we have a rule of the form
// statements ::= statement | statement statements
// this is translated to a single (statement())* expression.
// The empty declaration is handled implicitly by JavaCC

//---------------------------------------------------------------------------
//  Grammar from A.2 General
//---------------------------------------------------------------------------

/**
 * Rule 0 - Parse the complete scene.
 * 
 * vrmlScene ::=
 *     header |
 *     header statement *
 * 
* The scene assumes that the caller will make the startDocument() and * endDocument() calls on the ContentHandler before and after this method. */
Scene ::= ( Header ) ( Statement )* <EOF>
/**
 * Rule 1 - parse a header item.
 * 
 *  header ::=
 *    profileDecl componentDecls
 * 
*/
Header ::= ( ProfileDecl ) ( ComponentDecl )* ( MetaDecl )*
/**
 * Rule 2 - Parse a profile name declaration
 * 
 *  profileDecl ::=
 *    PROFILE profileName |
 *    empty;
 * 
*/
ProfileDecl ::= <PROFILE> Id
/**
 * Rule 3 - Parse a component name declaration
 * 
 *  componentDecl ::=
 *    COMPONENT componentName |
 *    COMPONENT componentName ":" integer |
 *    empty;
 * 
*/
ComponentDecl ::= <COMPONENT> Id
/**
 * Rule 4 - Parse a component name declaration
 * 
 *  componentDecl ::=
 *    META "key string" "value string"
 *    empty;
 * 
*/
MetaDecl ::= <META> <STRING_LITERAL> <STRING_LITERAL>
/**
 * Rule 5 - Parse a statement.
 * 
 * statement ::=
 *     nodeStatement |
 *     protoStatement |
 *     routeStatement |
 *     importStatement |
 *     exportStatement ;
 * 
*/
Statement ::= NodeStatement
| ProtoStatement
| RouteStatement
| ImportStatement
| ExportStatement
/**
 * Rule 6 - Parse a proto body statement.
 * 
 * protoBodyStatement ::=
 *     nodeStatement |
 *     protoStatement |
 *     routeStatement |
 *     importStatement ;
 * 
*/
ProtoBodyStatement ::= NodeStatement
| ProtoStatement
| RouteStatement
| ImportStatement
| <EXPORT>
/**
 * Rule 7 - Parse a node statement.
 * 
 * nodeStatement ::=
 *     node |
 *     DEF NodeNameId node |
 *     USE NodeNameId ;
 * 
*/
NodeStatement ::= Node
| <DEF> NodeNameId Node
| <USE> NodeNameId
/**
 * Rule 8 - Parse a node statement.
 * 
 * rootNodeStatement ::=
 *      node |
 *      DEF NodeNameId node ;
 * 
*/
RootNodeStatement ::= Node
| <DEF> NodeNameId Node
/**
 * Rule 9 - Parse a node statement.
 * 
 * protoStatement ::=
 *      proto |
 *      externproto ;
 * 
*/
ProtoStatement ::= Proto
| ExternProto
/**
 * Rule 10 - Parse a PROTO declaration.
 * 
 * proto ::=
 *      PROTO NodeTypeId [ interfaceDeclaration* ] { protoBody } ;
 * 
*/
Proto ::= <PROTO> NodeTypeId <LBRACKET> ( InterfaceDecl )* <RBRACKET> <LBRACE> ProtoBody <RBRACE>
/**
 * Rule 11 - Parse a node statement.
 * 
 * protoBody ::=
 *      protoStatement* rootNodeStatement statement* ;
 * 
*/
ProtoBody ::= ( ProtoStatement )* RootNodeStatement ( ProtoBodyStatement )*
/**
 * Rule 12 - Parse an interface declaration that allows everything except
 * exposedFields.
 * 
 * restrictedInterfaceDeclaration ::=
 *      eventIn fieldNameId eventId |
 *      eventOut fieldNameId eventId |
 *      field fieldNameId eventId fieldValue ;
 * 
* Unfortunately we also need some context information here to know if we are in * A script or a proto to know which handler to call. */
RestrictedInterfaceDecl ::= ( <INPUT_ONLY> FieldId FieldNameId | <OUTPUT_ONLY> FieldId FieldNameId | <INITIALIZE_ONLY> FieldId FieldNameId FieldValue )
/**
 * Rule 13 - Parse a single field interface declaration.
 * 
 * interfaceDeclaration ::=
 *      restrictedInterfaceDeclaration |
 *      exposedField fieldNameId eventId fieldValue ;
 * 
*/
InterfaceDecl ::= ( RestrictedInterfaceDecl | <INPUT_OUTPUT> FieldId FieldNameId FieldValue )
/**
 * Rule 14 - Parse a node statement.
 * 
 * externproto ::=
 *      EXTERNPROTO NodeTypeId [ externInterfaceDeclaration* ] URLList ;
 * 
*/
ExternProto ::= <EXTERNPROTO> NodeTypeId <LBRACKET> ( ExternInterfaceDecl )* <RBRACKET> URIList
/**
 * Rule 15 - Parse a node statement.
 * 
 * externInterfaceDeclaration ::=
 *      accessType fieldNameId eventId
 * 
*/
ExternInterfaceDecl ::= AccessType FieldId FieldNameId
/**
 * Rule 16 - Parse a node statement.
 * 
 * routeStatement ::=
 *      ROUTE NodeNameId . eventOutId TO NodeNameId . eventInId ;
 * 
*/
RouteStatement ::= <ROUTE> NodeNameId <DOT> FieldNameId <TO> NodeNameId <DOT> FieldNameId
/**
 * Rule 17 - Parse an IMPORT statement.
 * 
 * ImportStatement ::=
 *    "IMPORT" NodeNameId '.' NodeNameId |
 *    "IMPORT" NodeNameId '.' NodeNameId "AS" NodeNameId
 * 
*/
ImportStatement ::= <IMPORT> NodeNameId <DOT> NodeNameId ( <AS> NodeNameId )+
/**
 * Rule 18 - Parse an EXPORT statement.
 * 
 * ImportStatement ::=
 *    "EXPORT" NodeNameId |
 *    "EXPORT" NodeNameId "AS" NodeNameId
 * 
*/
ExportStatement ::= <EXPORT> NodeNameId ( <AS> NodeNameId )?
/**
 * Rule 19 - Parse an MFField statement - principally a URIList on the
 * EXTERNPROTO.
 * 
 * URLList ::=
 *    "[" STRING_LITERAL* "]" |
 *    STRING_LITERAL ;
 * 
*/
URIList ::= <LBRACKET> ( <STRING_LITERAL> )* <RBRACKET>
| <STRING_LITERAL>
//---------------------------------------------------------------------------
//  A.3 Node declarations
//---------------------------------------------------------------------------

/**
 * Rule 20 - Parse a node statement.
 * 
 * node ::=
 *      nodeTypeId { nodeBody } |
 *      "Script" { scriptBody } ;
 *  We also handle the empty cases for both body and script here
 * 
*/
Node ::= ( Id <LBRACE> ( NodeBody )? <RBRACE> | <SCRIPT> <LBRACE> ( ScriptBody )? <RBRACE> )
/**
 * Rule 21 - Parse a node statement.
 * 
 * nodeBody ::=
 *      nodeBodyElement |
 *      nodeBodyElement nodeBody
 * 
* The empty case is handled in the Node declaration */
NodeBody ::= ( NodeBodyElement )+
/**
 * Rule 22 - Parse a node statement.
 * 
 * nodeBodyElement ::=
 *      fieldNameId fieldValue |
 *      fieldNameId IS fieldNameId |
 *      routeStatement |
 *      protoStatement ;
 * 
*/
NodeBodyElement ::= ( FieldNameId FieldValue | FieldNameId <IS> FieldNameId | RouteStatement | ProtoStatement )
/**
 * Rule 23 - Parse a node statement.
 * 
 * scriptBody ::=
 *      scriptBodyElement |
 *      scriptBodyElement scriptBody
 * 
* The empty case is handled in the Node declaration */
ScriptBody ::= ( ScriptBodyElement )+
/**
 * Rule 24 - Parse a node statement.
 * 
 * scriptBodyElement ::=
 *      nodeBodyElement |
 *      interfaceDeclaration |
 *      inputOnly fieldType eventInId IS eventInId |
 *      outputOnly fieldType eventInId IS eventInId |
 *      inputOutput fieldType eventOutId IS eventOutId |
 *      initializeOnly fieldType fieldNameId IS fieldNameId ;
 * 
*/
ScriptBodyElement ::= ( NodeBodyElement | <INPUT_ONLY> FieldId FieldNameId ( <IS> FieldNameId )? | <OUTPUT_ONLY> FieldId FieldNameId ( <IS> FieldNameId )? | ( <INITIALIZE_ONLY> | <INPUT_OUTPUT> ) FieldId FieldNameId ( <IS> FieldNameId | FieldValue ) )
/**
 * Rule 24 - Parse a node statement.
 * 
 * nodeNameId ::= Id ;
 * 
*/
NodeNameId ::= Id
/**
 * Rule 25 - Parse a NodeType identifier.
 * 
 * nodeTypeId ::= Id ;
 * 
*/
NodeTypeId ::= Id
/**
 * Rule 26 - Parse a field name string.
 * 
 * fieldNameId ::= Id ;
 * eventInId ::= Id ;
 * eventOutId ::= Id ;
 * exposedFieldId ::= Id ;
 * 
*/
FieldNameId ::= Id
/**
 * Rule 27 - Turn a string into the {@link org.web3d.vrml.lang.FieldConstants}
 * value.
 * 
 *    "field" = FieldConstants.FIELD;
 *    "eventIn" = FieldConstants.EVENTIN;
 *    "eventOut" = FieldConstants.EVENTOUT;
 *    "exposedField" = FieldConstants.EXPOSEDFIELD;
 * 
*/
AccessType ::= <INITIALIZE_ONLY>
| <INPUT_ONLY>
| <OUTPUT_ONLY>
| <INPUT_OUTPUT>
/**
 * Rule 28 - Parse a field identifier.
 * 
 *   Id
 * 
* Concatention of fieldType that we really only care about the ID if the * user wants to provided expanded types. */
FieldId ::= Id
/**
 * Rule 29 - Parse a field value statement.
 * 
 *  The value of a field. Just a literral string to pass back to the caller
 *  FieldValue :: =
 *     SingleFieldValue |
 *     MultiFieldValue
 * 
* */
FieldValue ::= ( SingleFieldValue | MultiFieldValue )
/**
 * Rule 30 - Parse a single value of a field statement.
 * 
 * SingleFieldValue ::=
 *     NodeStatement |         # SFNode
 *     "NULL" |                # empty SFNode or empty MFNode
 *     LiteralValue
 * 
*/
SingleFieldValue ::= ( NodeStatement | <NULL> | LiteralValue )
/**
 * Rule 31 - Parse a multi value field statement.
 * 
 * MultiFieldValue ::=
 *     "["(NodeStatment)+ "]" | # MFNode
 *     "[ (SingleFieldvalue)* ]
 * 
*/
MultiFieldValue ::= <LBRACKET> ( ( NodeStatement )+ | NumberArray | BooleanArray | StringArray ) <RBRACKET>
/**
 * Rule 32 - Parse a literal value for a single field value.
 * 
 * LiteralValue ::=
 *    TRUE |
 *    FALSE |
 *    NumberArray |
 *    STRING_LITERAL
 * 
* We do allow a full number array here - ie more than the max 4 values that * an SFRotation contains. This makes our parsing faster, but less correct. * Basically we assume the callback will deal with any extra numbers if they * want to by either discarding them or throwing an error. */
LiteralValue ::= ( <TRUE> | <FALSE> | FixedNumberArray | <STRING_LITERAL> )
/**
 * Rule 33 - Parse an array of string literals.
 * 
 * StringArray ::=
 *   STRING_LITERAL+
 * 
*/
StringArray ::= ( <STRING_LITERAL> )*
/**
 * Rule 34 - Parse a number that may contain multiple whitespace values - such
 * as an SFVec3f.
 * 
 * NumberArray ::=
 *    NUMBER_LITERAL+
 * 
*/
NumberArray ::= ( <NUMBER_LITERAL> )+
/**
 * Rule 29 - Parse a number that may contain multiple whitespace values - such
 * as an SFVec3f.
 * 
 * NumberArray ::=
 *    NUMBER_LITERAL+
 * 
*/
FixedNumberArray ::= ( <NUMBER_LITERAL> )+
/**
 * Rule 35 - Parse a MFBool array
 * 
 * NumberArray ::=
 *    (TRUE | FALSE)+
 * 
*/
BooleanArray ::= ( <TRUE> | <FALSE> )+
//---------------------------------------------------------------------------
//  Miscellaneous methods to use
//---------------------------------------------------------------------------

/**
 * Generate an identifier as a string from the parsed token.
 */
Id ::= <ID>