translation_unit ::= #ignore(C++) #continue #readIdentifier:sType [ #check(sType == "package") #continue object_type_path ';' #readIdentifier:sType ]? object_type(this) [post_processing]? ; object_type<"class">(parent : node) ::= #continue object_type_path:sObjectName => insert parent.classes[sObjectName]; [template_clause_decl]? object_type_body<"class">(parent.classes[sObjectName]) ; template_clause_decl ::= '<' #continue template_parameter_decl [ ',' #continue template_parameter_decl ]* '>' ; template_parameter_decl ::= identifier [ #readIdentifier:"conforms" #continue object_type_path ]? ; object_type<"interface">(parent : node) ::= #continue => local objectTypeName; object_type_path:sObjectName => insert parent.interfaces[sObjectName]; object_type_body<"interface">(parent.interfaces[sObjectName]) ; object_type_body(object : node) ::= #continue '{' => local env; [ access_mode:env.access_mode [declarator(object, env)]* ]* '}' ; declarator(object : node, env : node) ::= constructor(object, env) | destructor(object, env) | => local declQualifiers; [ declarator_qualifier:sQual => insert declQualifiers[sQual]; ]* => local typeSpec; type_specifier(typeSpec) #continue identifier:sMemberName [ !!'(' #continue method_declaration<((declQualifiers.findElement("abstract")) ? "interface" : sObjectType)>(declQualifiers, typeSpec, sMemberName, object, env) | attribute_declaration(declQualifiers, typeSpec, sMemberName, object, env) ] ; constructor<"class">(object : node, env : node) ::= #readIdentifier:"constructor" #continue method_parameters [ ':' #continue constructor_attribute_initialization [',' #continue constructor_attribute_initialization]* ]? method_body<"class"> ; constructor_attribute_initialization ::= #continue identifier '(' constant_initializer ')' ; constant_initializer ::= #readIdentifier:"new" #continue object_type_path '(' [ => local expr; constant_expression(expr) [ ',' #continue => local expr; constant_expression(expr) ]* ]? ')' | => local expr; constant_expression(expr) ; destructor<"class">(object : node, env : node) ::= #readIdentifier:"destructor" #continue '(' ')' method_body<"class"> ; declarator_qualifier:value ::= #readIdentifier:{"abstract", "virtual", "final", "static", "weak"}:declarator_qualifier; type_specifier(typeSpec : node) ::= [ #readIdentifier:{"void", "char", "short", "int", "long", "float", "double", "signed", "unsigned"}:typeSpec.name => typeSpec = "base"; | object_type_path:typeSpec.name [template_clause]? => typeSpec = "object"; ] [ '[' #continue => pushItem typeSpec.array; array_size(typeSpec.array) [ ',' #continue => pushItem typeSpec.array; array_size(typeSpec.array) ]* ']' ]? ; template_clause ::= '<' #continue => local typeSpec; type_specifier(typeSpec) [ ',' #continue type_specifier(typeSpec) ]* '>' ; method_declaration(declQualifiers : node, typeSpec : node, sMemberName : value, object : node, env : node) ::= #continue method_parameters [ #readIdentifier:"throws" object_type_path [',' object_type_path]* ]? method_body ; method_parameters ::= '(' [parameter_declaration [',' parameter_declaration]*]? ')' ; parameter_declaration ::= [parameter_mode]? => local typeSpec; type_specifier(typeSpec) [identifier]? ; parameter_mode ::= #readIdentifier:{"in", "inout", "out"}; method_body<"interface"> ::= #continue ';'; method_body<"class"> ::= #continue => local theStatement; /*TO DO*/ compound_statement(theStatement) ; attribute_declaration<"interface">(declQualifiers : node, typeSpec : node, sMemberName : value, object : node, env : node) ::= => error("an interface admits method declarations only"); ; attribute_declaration<"class">(declQualifiers : node, typeSpec : node, sMemberName : value, object : node, env : node) ::= [attribute_specifier]* #continue ';' ; attribute_specifier ::= [ '=' constant_initializer | #readIdentifier:sSpecifier attribute_specifier ]; attribute_specifier<"getter"> ::= #continue method_body<"class">; attribute_specifier<"setter"> ::= #continue '(' identifier ')' method_body<"class">; post_processing ::= '#' #readIdentifier:"CodeWorker" #continue ->(:sScript)['#' #readIdentifier:"CodeWorker"] => executeString(this, sScript); ; object_type_path : value ::= [ identifier:sId '.' => object_type_path += sId + '.'; ]* identifier:object_type_path ; //---------------------------------------------------------------------------- // E X P R E S S I O N S //---------------------------------------------------------------------------- constant_expression(expr : node) ::= conditional_expression<"constant">(expr); conditional_expression(expr : node) ::= logical_or_expression(expr) [ '?' #continue => slideNodeContent(expr, condition); => insert expr.operator = '?'; expression(expr.then) ':' conditional_expression(expr.else) ]? ; logical_or_expression(expr : node) ::= logical_and_expression(expr) [ "||" #continue => slideNodeContent(expr, left); => insert expr.operator = "||"; logical_and_expression(expr.right) ]* ; logical_and_expression(expr : node) ::= inclusive_or_expression(expr) [ "&&" #continue => slideNodeContent(expr, left); => insert expr.operator = "&&"; inclusive_or_expression(expr.right) ]* ; inclusive_or_expression(expr : node) ::= exclusive_or_expression(expr) [ ['|' #!ignore !'|'] #continue => slideNodeContent(expr, left); => insert expr.operator = '|'; exclusive_or_expression(expr.right) ]* ; exclusive_or_expression(expr : node) ::= and_expression(expr) [ '^' #continue => slideNodeContent(expr, left); => insert expr.operator = '^'; and_expression(expr.right) ]* ; and_expression(expr : node) ::= equality_expression(expr) [ ['&' #!ignore !'&'] #continue => slideNodeContent(expr, left); => insert expr.operator = '&'; equality_expression(expr.right) ]* ; equality_expression(expr : node) ::= relational_expression(expr) [ ["==" | "!="]:sOperator #continue => slideNodeContent(expr, left); => insert expr.operator = sOperator; relational_expression(expr.right) ]* ; relational_expression(expr : node) ::= shift_expression(expr) [ ['<' #!ignore !'<' | '>' #!ignore !'>' | "<=" | ">="]:sOperator #continue => slideNodeContent(expr, left); => insert expr.operator = sOperator; shift_expression(expr.right) ]* ; shift_expression(expr : node) ::= additive_expression(expr) [ ["<<" | ">>"]:sOperator #continue => slideNodeContent(expr, left); => insert expr.operator = sOperator; additive_expression(expr.right) ]* ; additive_expression(expr : node) ::= multiplicative_expression(expr) [ ['+' | '-']:sOperator #continue => slideNodeContent(expr, left); => insert expr.operator = sOperator; multiplicative_expression(expr.right) ]* ; multiplicative_expression(expr : node) ::= cast_expression(expr) [ ['*' | '/' | '%']:sOperator #continue => slideNodeContent(expr, left); => insert expr.operator = sOperator; cast_expression(expr.right) ]* ; cast_expression(expr : node) ::= '(' type_name(theType) ')' cast_expression(theCast) => insert expr.operator = "cast"; => setall expr.cast = theType; => setall expr.expr = theCast; | unary_expression(expr) ; unary_expression(expr : node) ::= postfix_expression(expr) | ["++" | "--"]:expr.operator #continue unary_expression(expr.expr) | unary_operator:expr.operator #continue cast_expression(expr.expr) | #readIdentifier:"sizeof":expr.operator #continue [ unary_expression(sExpr) | type_name(theType) ] ; postfix_expression(expr : node) ::= primary_expression(expr) [ '[' #continue expression(expr.post.array) ']' => insert expr.post.operator = "[]"; | #check(T != "constant") '(' /*[assignment_expression]* replaced by ->*/ [function_call_parameter_list(expr.post.parameters)]? ')' => insert expr.post.operator = "()"; => ref expr = expr.post; | '.':expr.post.operator #continue identifier:expr.post.id => ref expr = expr.post; | "->":expr.post.operator #continue identifier:expr.post.id => ref expr = expr.post; | ["++" | "--"]:expr.post.operator => ref expr = expr.post; ]*; // added by CL function_call_parameter_list(expr : node) ::= #pushItem(expr) assignment_expression<"">(expr#back) [ ',' #continue => pushItem expr; assignment_expression<"">(expr#back) ]* ; primary_expression(expr : node) ::= identifier:expr.value => insert expr.operator = "id"; | constant:expr.value => insert expr.operator = "const"; | '(' expression(expr) ')' ; primary_expression<"constant">(expr : node) ::= constant:expr.value => insert expr.operator = "const"; | '(' expression<"constant">(expr) ')' ; constant ::= #readNumeric /*| integer_constant*/ | #readCString | #readCChar | enumeration_constant; enumeration_constant ::= identifier; expression(expr : node) ::= assignment_expression(expr); assignment_expression(expr : node) ::= => local theExpr; unary_expression(theExpr) assignment_operator:expr.operator #continue => setall expr.right = theExpr; assignment_expression(expr.left) | conditional_expression(expr) ; assignment_operator ::= '=' #!ignore !'=' | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|="; unary_operator ::= '&' #!ignore !'&' | '*' | '+' #!ignore !'+' | '-' #!ignore !'-' | '~' | '!'; //---------------------------------------------------------------------------- // S T A T E M E N T S //---------------------------------------------------------------------------- compound_statement(theStatement : node) ::= '{' #continue => insert theStatement.type = "{}"; [statement(theStatement)]* '}' ; statement(theStatement : node) ::= #pushItem(theStatement) [ #readIdentifier:sKeyword statement(theStatement#back) | compound_statement(theStatement#back) => ref theStatement#back.parent = theStatement; | declaration_statement(theStatement#back) | expression_statement(theStatement#back) ] ; declaration_statement(theStatement : node) ::= => local declQualifiers; [ declarator_qualifier:sQual => insert declQualifiers[sQual]; ]* => local typeSpec; type_specifier(typeSpec) identifier:sAttribute #continue => insert theStatement.type = "decl"; => insert theStatement.name = sAttribute; => setall theStatement.qualifiers = declQualifiers; => setall theStatement.type_specifier = typeSpec; [ '(' #continue [ => local expr; expression<"">(expr) [ ',' #continue expression<"">(expr) ]* ]? ')' | '=' #continue expression<"">(expr) ]? ';' ; statement(theStatement : node) ::= ':' #continue => insert theStatement.type = "label"; => insert theStatement.label = sKeyword; statement(theStatement.block) ; statement<"case">(theStatement : node) ::= #continue => insert theStatement.type = "case"; constant_expression(theStatement.case) ':' statement(theStatement.block) ; statement<"default">(theStatement : node) ::= #continue => insert theStatement.type = "default"; ':' statement(theStatement.block) ; expression_statement(theStatement : node) ::= [ expression<"">(theStatement.expr) => insert theStatement.type = "expr"; ]? ';' ; statement<"if">(theStatement : node) ::= #continue => insert theStatement.type = "if"; '(' expression<"">(theStatement.condition) ')' statement(theStatement.then) [#readIdentifier:"else" #continue statement(theStatement.else)]? ; statement<"switch">(theStatement : node) ::= #continue => insert theStatement.type = "switch"; '(' expression<"">(theStatement.condition) ')' statement(theStatement.block) ; statement<"while">(theStatement : node) ::= #continue => insert theStatement.type = "while"; '(' expression<"">(theStatement.condition) ')' statement(theStatement.block) ; statement<"do">(theStatement : node) ::= #continue => insert theStatement.type = "do"; statement(theStatement.block) "while" '(' expression<"">(theStatement.condition) ')' ';' ; statement<"for">(theStatement : node) ::= #continue => insert theStatement.type = "for"; '(' [ #insert(theStatement.init_declaration) declaration_statement(theStatement.init_declaration) | expression<"">(theStatement.init) ';' ] expression<"">(theStatement.condition) ';' expression<"">(theStatement.increment) ')' statement(theStatement.block) ; statement<"goto">(theStatement : node) ::= #continue => insert theStatement.type = "goto"; identifier:theStatement.label ';' ; statement<"continue">(theStatement : node) ::= #continue => insert theStatement.type = "continue"; ';'; statement<"return">(theStatement : node) ::= #continue => insert theStatement.type = "return"; [expression<"">(theStatement.expr)]? ';' ; //--------------------------------------------------------------------------------- access_mode<"class"> : value ::= #readIdentifier:{"public", "protected", "private"}:access_mode #continue ':'; access_mode<"interface"> : value ::= #readIdentifier:{"public", "protected"}:access_mode #continue ':'; identifier:value ::= #readIdentifier:sId #check(!(sId in { //##markup##"keywords" //##script## //local keywords; //parseAsBNF({ // keywords ::= // #ignore(C++) // [ // ->[ // '"' // #!ignore // #readIdentifier:sText // '"' // => insert this[sText]; // | // #readCString // ] // ]*; //}, keywords, "opalin_grammar.cwp"); //foreach i in keywords { // if !i.first() {@, @} // @"@i.key()@"@ //} //@ //@ //##script## //##begin##"keywords" "class", "interface", "constructor", "destructor", "abstract", "virtual", "final", "static", "weak", "void", "char", "short", "int", "long", "float", "double", "signed", "unsigned", "base", "object", "throws", "in", "inout", "out", "getter", "setter", "CodeWorker", "public", "protected", "private" //##end##"keywords" })) ;