/** * * Copyright (C) 1996, 1997 Sun Microsystems Inc. * * Use of this file and the system it is part of is constrained by the * file COPYRIGHT in the root directory of this system. You may, however, * make any modifications you wish to this file. * * Author: Sreenivasa Viswanadha * Date: 3/20/97 * * This file contains a Java grammar and actions that implement a front-end. * * * Derived in part from the following work: * * PUBLIC DOMAIN PCCTS-BASED C++ GRAMMAR (cplusplus.g, stat.g, expr.g) * * Authors: Sumana Srinivasan, NeXT Inc.; sumana_srinivasan@next.com * Terence Parr, Parr Research Corporation; parrt@parr-research.com * Russell Quong, Purdue University; quong@ecn.purdue.edu * * VERSION 1.1 * */ options { BUILD_PARSER=false; CACHE_TOKENS=true; UNICODE_INPUT=true; } PARSER_BEGIN(CppParserImpl) package net.sourceforge.pmd.lang.cpp.ast; public final class CppParserImpl { } PARSER_END(CppParserImpl) SKIP: { " " | "\f" | "\t" | "\r\n" | "\n" | "#" : PREPROCESSOR_OUTPUT } SPECIAL_TOKEN: { } MORE: { "/*" : IN_MULTI_LINE_COMMENT } SPECIAL_TOKEN: { : DEFAULT } MORE: { < ~[] > } SPECIAL_TOKEN: { : PREPROCESSOR_OUTPUT } SKIP: { "\n" : DEFAULT } MORE: { "\\\n" | "\\\r\n" | "/*": IN_PREPROCESSOR_OUTPUT_COMMENT | < ~[] > } TOKEN : { < LCURLYBRACE: "{" > | < RCURLYBRACE: "}" > | < LSQUAREBRACKET: "[" > | < RSQUAREBRACKET: "]" > | < LPARENTHESIS: "(" > | < RPARENTHESIS: ")" > | < SCOPE: "::" > | < COLON: ":" > | < SEMICOLON: ";" > | < COMMA: "," > | < QUESTIONMARK: "?" > | < ELLIPSIS: "..." > | < ASSIGNEQUAL: "=" > | < TIMESEQUAL: "*=" > | < DIVIDEEQUAL: "/=" > | < MODEQUAL: "%=" > | < PLUSEQUAL: "+=" > | < MINUSEQUAL: "-=" > | < SHIFTLEFTEQUAL: "<<=" > | < SHIFTRIGHTEQUAL: ">>=" > | < BITWISEANDEQUAL: "&=" > | < BITWISEXOREQUAL: "^=" > | < BITWISEOREQUAL: "|=" > | < OR: "||" > | < AND: "&&" > | < BITWISEOR: "|" > | < BITWISEXOR: "^" > | < AMPERSAND: "&" > | < EQUAL: "==" > | < NOTEQUAL: "!=" > | < LESSTHAN: "<" > | < GREATERTHAN: ">" > | < LESSTHANOREQUALTO: "<=" > | < GREATERTHANOREQUALTO: ">=" > | < SHIFTLEFT: "<<" > | < SHIFTRIGHT: ">>" > | < PLUS: "+" > | < MINUS: "-" > | < STAR: "*" > | < DIVIDE: "/" > | < MOD: "%" > | < PLUSPLUS: "++" > | < MINUSMINUS: "--" > | < TILDE: "~" > | < NOT: "!" > | < DOT: "." > | < POINTERTO: "->" > | < DOTSTAR: ".*" > | < ARROWSTAR: "->*" > | < AUTO: "auto" > | < BREAK: "break" > | < CASE: "case" > | < CATCH: "catch" > | < CHAR: "char" > | < CONST: "const" > | < CONTINUE: "continue" > | < _DEFAULT: "default" > | < DELETE: "delete" > | < DO: "do" > | < DOUBLE: "double" > | < ELSE: "else" > | < ENUM: "enum" > | < EXTERN: "extern" > | < FLOAT: "float" > | < FOR: "for" > | < FRIEND: "friend" > | < GOTO: "goto" > | < IF: "if" > | < INLINE: "inline" > | < INT: "int" > | < LONG: "long" > | < NEW: "new" > | < PRIVATE: "private" > | < PROTECTED: "protected" > | < PUBLIC: "public" > | < REDECLARED: "redeclared" > | < REGISTER: "register" > | < RETURN: "return" > | < SHORT: "short" > | < SIGNED: "signed" > | < SIZEOF: "sizeof" > | < STATIC: "static" > | < STRUCT: "struct" > | < CLASS : "class" > | < SWITCH: "switch" > | < TEMPLATE: "template" > | < THIS: "this" > | < TRY: "try" > | < TYPEDEF: "typedef" > | < UNION: "union" > | < UNSIGNED: "unsigned" > | < VIRTUAL: "virtual" > | < VOID: "void" > | < VOLATILE: "volatile" > | < WHILE: "while" > | < OPERATOR: "operator" > | < TRUETOK: "true" > | < FALSETOK: "false" > | < THROW: "throw" > | < AT: "@" > | < FINALLY: "finally" > } TOKEN: { < #BINARYDIGIT: ["0"-"1"] > | < #OCTALDIGIT: ["0"-"7"] > | < #DECIMALDIGIT: ["0"-"9"] > | < #HEXDIGIT: ["a"-"f", "A"-"F", "0"-"9"] > | < #INT_SUFFIX: ["u", "U", "l", "L"] | "uL" | "Ul" | "UL" | "ul" | "lu" | "Lu" | "lU" | "LU" > | < ZERO: "0" > | < BINARY_INT_LITERAL: "0" ["b", "B"] ("'" | )+ ()? > | < OCTAL_INT_LITERAL: "0" ("'" | )+ ()? > | < DECIMAL_INT_LITERAL: ["1"-"9"] ("'" | )* ()? > | < HEXADECIMAL_INT_LITERAL: "0" ["x", "X"] ("'" | )+ ()? > // like DECIMALINT but may start with 0 | < #INT_IN_FLOAT: ["0"-"9"] ("'" | )* > | < #EXP_PART: ["e", "E"] (["-","+"])? > | < FLOAT_LITERAL : ("." ( ()?)? | ) (["f", "l", "F", "L"])? > } TOKEN : { < #CHRPREF : > | < CHARACTER : "'" ( ( ~["'","\\","\r","\n"] ) | ( "\\" ( ~["\n","\r"] ) ) )+ "'" > | < #STRPREF : ("L" | "u" | "U" | "u8")? > | < STRING : "\"" ( ( ~["\"","\\","\r","\n"] ) | ( "\\" ( ~["\n","\r"] | "\n" | "\r\n" ) ) )* "\"" > } // Raw C++11 string literal support // https://en.cppreference.com/w/cpp/language/string_literal TOKEN : { < RSTRING : "R\"" > { StringBuilder sb = new StringBuilder(16); // delim ------+ // vvv // Matching R"...(...)..." // ^ for (;;) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return matchedToken; } if (curChar == '(') break; sb.append(curChar); } final String delim = sb.toString(); rstringbody: // Matching R"...(...)..." // ^ for (;;) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return matchedToken; } if (curChar == ')') { // delim --------------+ // vvv // Matching R"...(...)..." // ^^^ for (int i = 0; i < delim.length(); i++) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return matchedToken; } if (delim.charAt(i) != curChar) { input_stream.backup(1); continue rstringbody; } } // Matching R"...(...)..." // ^ try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return matchedToken; } if (curChar != '"') { input_stream.backup(1); continue rstringbody; } break; } } matchedToken = matchedToken.replaceImage(input_stream); } } TOKEN : { // https://en.cppreference.com/w/cpp/language/identifiers#Unicode_characters_in_identifiers < ID : ()* > | < #UNICODE_ESCAPE: "\\" ( "u" | "U" ) > | < #HEXDIGIT_4: > | < #ID_CHAR: | [ "a"-"z", "A"-"Z", "0"-"9", "_", "$", "\u00a8", "\u00aa", "\u00ad", "\u00af", "\u00b2"-"\u00b5", "\u00b7"-"\u00ba", "\u00b7"-"\u00ba", "\u00bc"-"\u00be", "\u00c0"-"\u00d6", "\u00d8"-"\u00f6", "\u00f8"-"\u167f", "\u1681"-"\u180d", "\u180f"-"\u1fff", "\u200b"-"\u200d", "\u202a"-"\u202e", "\u203f"-"\u2040", "\u2054", "\u2060"-"\u218f", "\u2460"-"\u24ff", "\u2776"-"\u2793", "\u2c00"-"\u2dff", "\u2e80"-"\u2fff", "\u3004"-"\u3007", "\u3021"-"\u302f", "\u3031"-"\ud7ff", "\uf900"-"\ufd3d", "\ufd40"-"\ufdcf", "\ufdf0"-"\ufe44", "\ufe47"-"\ufffd" // the standard also allows code points in planes 1 through e, // but javacc doesn't support supplementary characters ] > // this production is the same as the above, // with some ranges subtracted | < #ID_START_CHAR: | [ "a"-"z", "A"-"Z", "_", "$", "\u00a8", "\u00aa", "\u00ad", "\u00af", "\u00b2"-"\u00b5", "\u00b7"-"\u00ba", "\u00b7"-"\u00ba", "\u00bc"-"\u00be", "\u00c0"-"\u00d6", "\u00d8"-"\u00f6", // subtracted u+0300-u+036f from u+00f8-u+167f "\u00f8"-"\u02ff", "\u0370"-"\u167f", "\u1681"-"\u180d", // subtracted u+1dc0-u+1dff from u+180f-u+1fff "\u180f"-"\u1dbf", "\u1e00"-"\u1fff", "\u200b"-"\u200d", "\u202a"-"\u202e", "\u203f"-"\u2040", "\u2054", // subtracted u+20d0-u+20ff from u+2060-u+218f "\u2060"-"\u20cf", "\u2100"-"\u218f", "\u2460"-"\u24ff", "\u2776"-"\u2793", "\u2c00"-"\u2dff", "\u2e80"-"\u2fff", "\u3004"-"\u3007", "\u3021"-"\u302f", "\u3031"-"\ud7ff", "\uf900"-"\ufd3d", "\ufd40"-"\ufdcf", // subtracted u+fe20-u+fe2f from u+fdf0-u+fe44 "\ufdf0"-"\ufe1f", "\ufe30"-"\ufe44", "\ufe47"-"\ufffd" ] > } void translation_unit() : {} { { sym.OpenScope(null, false); } ( LOOKAHEAD(2) external_declaration() )* { sym.CloseScope(); } } void external_declaration() : { boolean isTypedef = false; } { LOOKAHEAD(("typedef" | template_head())? class_head() "{") ( template_head() )? declaration() | LOOKAHEAD("enum" ()? "{") enum_specifier() (init_declarator_list(false))? ";" | LOOKAHEAD ((template_head())? dtor_ctor_decl_spec() dtor_declarator() "{") dtor_definition() | LOOKAHEAD(dtor_ctor_decl_spec() ctor_declarator_lookahead()) ctor_definition() | LOOKAHEAD((declaration_specifiers())? function_declarator_lookahead()) function_definition() | LOOKAHEAD((scope_override())? "operator") conversion_function_decl_or_def() | template_head() ( LOOKAHEAD(dtor_ctor_decl_spec() ctor_declarator_lookahead()) ctor_definition() | LOOKAHEAD((declaration_specifiers())? function_declarator_lookahead()) function_definition() | isTypedef = declaration_specifiers() (init_declarator_list(isTypedef))? ";" ) | declaration() | ";" } void function_definition() : { Scope sc = null; boolean isTypedef; } { LOOKAHEAD(3) isTypedef = declaration_specifiers() sc = function_declarator(isTypedef) func_decl_def(sc) | sc = function_declarator(false) func_decl_def(sc) } void func_decl_def(Scope sc) : { boolean closeReqd = false; } { { if (closeReqd = (sc != null && sc != sym.GetCurScope())) sym.OpenScope(sc); } ( ";" | compound_statement() ) { if (closeReqd) sym.CloseScope(); } } void linkage_specification() : {} { "extern" ( "{" ( external_declaration() )* "}" ( LOOKAHEAD(";") ";")? | declaration() ) } void declaration() : { boolean isTypedef = false; } { LOOKAHEAD(2) isTypedef = declaration_specifiers() (init_declarator_list(isTypedef))? ";" | linkage_specification() } /** * Very temporary. Just returns true if it sees a typedef. Finally, we will * need a structure that stores all the attributes. */ boolean type_modifiers() : { boolean isTypedef = false; } { ( isTypedef = storage_class_specifier() | type_qualifier() | "inline" | "virtual" | "friend" ) { return isTypedef; } } /** * Very temporary. Just returns true if it sees a typedef. Finally, we will * need a structure that stores all the attributes. */ boolean declaration_specifiers() : { Token t; boolean isTypedef = false, tmp; } { ( ( LOOKAHEAD(type_modifiers()) tmp = type_modifiers() { isTypedef |= tmp; } )+ [ LOOKAHEAD(2) ( LOOKAHEAD(builtin_type_specifier()) builtin_type_specifier() ( LOOKAHEAD(2) ( LOOKAHEAD(builtin_type_specifier()) builtin_type_specifier() | LOOKAHEAD(type_modifiers()) tmp = type_modifiers() ) { isTypedef |= tmp; } )* | ( class_specifier() | enum_specifier() | qualified_type() ) (LOOKAHEAD(2) tmp = type_modifiers() { isTypedef |= tmp;} )* ) ] | LOOKAHEAD(builtin_type_specifier()) builtin_type_specifier() ( LOOKAHEAD(2) ( LOOKAHEAD(builtin_type_specifier()) builtin_type_specifier() | tmp = type_modifiers() { isTypedef |= tmp; } ) )* | ( class_specifier() | enum_specifier() | qualified_type() ) (LOOKAHEAD(2) tmp = type_modifiers() { isTypedef |= tmp; } )* ) { return isTypedef; } } /* void type_specifier() : {} { simple_type_specifier() | class_specifier() | enum_specifier() } */ void simple_type_specifier() : {} { ( builtin_type_specifier() | qualified_type() ) } void scope_override_lookahead() : {} { "::" | ("<" template_argument_list() ">")? "::" } String scope_override() : { String name = ""; Token t; } { ( ("::") { name += "::"; } ( LOOKAHEAD(2) t = ("<" template_argument_list() ">")? "::" { name += t.getImage() + "::"; } )* | ( LOOKAHEAD(2) t = ("<" template_argument_list() ">")? "::" { name += t.getImage() + "::"; } )+ ) { return name; } } String qualified_id() : { String name = ""; Token t; } { [ LOOKAHEAD(scope_override_lookahead()) name = scope_override() ] ( t = [ "<" template_argument_list() ">" ] { return name + t.getImage(); } | "operator" optor() { return "operator"; } ) } void ptr_to_member() : {} { scope_override() "*" } void qualified_type() : {} { LOOKAHEAD({ sym.IsFullyScopedTypeName(GetFullyScopedName()) } ) qualified_id() } void type_qualifier() : {} { "const" | "volatile" } /** * Very temporary. Just returns true if it sees a typedef. Finally, we will * need a structure that stores all the attributes. */ boolean storage_class_specifier() : {} { ( "auto" | "register" | "static" | "extern" ) { return false; } | "typedef" { return true; } } void builtin_type_specifier() : {} { "void" | "char" | "short" | "int" | "long" | "float" | "double" | "signed" | "unsigned" } void init_declarator_list(boolean isTypedef) : {} { init_declarator(isTypedef) ("," init_declarator(isTypedef))* } void init_declarator(boolean isTypedef) : { String name; } { name = declarator() { if (isTypedef) sym.PutTypeName(name); } ( "=" initializer() | "(" expression_list() ")" )? } void class_head() : {} { ("struct" | "union" | "class") ( (base_clause(null))?)? } void class_specifier() : { ClassScope sc = null; Token t; } { ("struct" | "union" | "class" ) ( "{" { sym.OpenScope(null, false); } (member_declaration())* "}" { sym.CloseScope(); } | LOOKAHEAD(2) t = { sc = (ClassScope)sym.OpenScope(t.getImage(), true); } (base_clause(sc))? "{" (member_declaration())* "}" { sym.CloseScope(); } | t= (LOOKAHEAD(2) "<" template_argument_list() ">")? { sym.PutTypeName(t.getImage()); } ) } void base_clause(ClassScope scope) : {} { ":" base_specifier(scope) ( "," base_specifier(scope) )* } void base_specifier(ClassScope scope) : { Token t; } { ("virtual" (access_specifier())? | access_specifier() ("virtual")?)? (LOOKAHEAD(scope_override_lookahead()) scope_override())? t = ("<" template_argument_list() ">")? { scope.AddSuper(sym.GetScope(t.getImage())); } } void access_specifier() : {} { "public" | "protected" | "private" } void member_declaration() : { boolean isTypedef = false; } { LOOKAHEAD(("typedef")? class_head() "{") declaration() | LOOKAHEAD("enum" ()? "{") enum_specifier() ( member_declarator_list(false) )? ";" | LOOKAHEAD( "operator" ) conversion_function_decl_or_def() | LOOKAHEAD(dtor_ctor_decl_spec() dtor_declarator() "{") dtor_definition() | LOOKAHEAD(("inline"| "virtual")* "~") dtor_ctor_decl_spec() simple_dtor_declarator() ";" | LOOKAHEAD(dtor_ctor_decl_spec() ctor_declarator_lookahead()) ctor_definition() | LOOKAHEAD(dtor_ctor_decl_spec() ctor_declarator_lookahead() ";") (dtor_ctor_decl_spec() ctor_declarator() ";") | LOOKAHEAD((declaration_specifiers())? function_declarator_lookahead()) function_definition() | LOOKAHEAD(declaration_specifiers()) isTypedef = declaration_specifiers() (member_declarator_list(isTypedef))? ";" | LOOKAHEAD() function_declarator(false) ";" | LOOKAHEAD(3) qualified_id() ";" | access_specifier() ":" | ";" } void member_declarator_list(boolean isTypedef) : {} { member_declarator(isTypedef) ("=" assignment_expression())? ("," member_declarator(isTypedef) ("=" assignment_expression())?)* } void member_declarator(boolean isTypedef) : { String name; } { name = declarator() { if (isTypedef) sym.PutTypeName(name); } } void conversion_function_decl_or_def() : { Scope sc = null; String name = null; } { [ LOOKAHEAD(scope_override_lookahead()) name = scope_override() ] "operator" declaration_specifiers() ("*" | "&")? "(" (parameter_list())? ")" (LOOKAHEAD(2) type_qualifier())? (exception_spec())? func_decl_def(null) // Temporary (fix the null) } void enum_specifier() : { Token t; } { "enum" ( "{" enumerator_list() "}" | t= (LOOKAHEAD(2) "{" enumerator_list() "}")? { sym.PutTypeName(t.getImage()); } ) } void enumerator_list() : {} { enumerator() ("," enumerator())* } void enumerator() : {} { ("=" constant_expression())? } void ptr_operator() : {} { "&" cv_qualifier_seq() | "*" cv_qualifier_seq() | ptr_to_member() cv_qualifier_seq() } void cv_qualifier_seq() : {} { [ LOOKAHEAD(2) ( "const" [ LOOKAHEAD(2) "volatile" ] | "volatile" [ LOOKAHEAD(2) "const" ] ) ] } String declarator() : { String name; } { ( LOOKAHEAD(ptr_operator()) ptr_operator() name = declarator() | name = direct_declarator() ) { return name; } } String direct_declarator() : { String name; Token t; } { LOOKAHEAD(2) "~" t = (LOOKAHEAD(2) declarator_suffixes())? { return "~" + t.getImage(); } | "(" name = declarator() ")" (LOOKAHEAD(2) declarator_suffixes())? { return name; } | name = qualified_id() (LOOKAHEAD(2) declarator_suffixes())? { return name; } } void declarator_suffixes() : {} { ("[" (constant_expression())? "]" )+ | "(" (parameter_list())? ")" (LOOKAHEAD(2) type_qualifier())? (exception_spec())? } /** * Used only for lookahead. */ void function_declarator_lookahead() : {} { (LOOKAHEAD(2) ptr_operator() )* qualified_id() "(" } Scope function_declarator(boolean isTypedef) : { Scope sc = null; } { ( LOOKAHEAD(ptr_operator()) ptr_operator() sc = function_declarator(isTypedef) | sc = function_direct_declarator(isTypedef) ) { return sc; } } Scope function_direct_declarator(boolean isTypedef) : { String name; Scope sc = null; boolean closeReqd = false; } { name = qualified_id() { sc = sym.GetScopeOfFullyScopedName(name); if (closeReqd = (sc != null && sc != sym.GetCurScope())) sym.OpenScope(sc); } "(" (parameter_list())? ")" (LOOKAHEAD(2) type_qualifier())? (exception_spec())? ("=" )? { if (closeReqd) sym.CloseScope(); if (isTypedef) sym.PutTypeName(name); return sc; } } void dtor_ctor_decl_spec() : {} { [ "virtual" [ "inline"] | "inline" [ "virtual"] ] } void dtor_definition() : {} { (template_head())? dtor_ctor_decl_spec() dtor_declarator() compound_statement() } void ctor_definition() : { Scope sc = null; boolean closeReqd = false; } { dtor_ctor_decl_spec() sc = ctor_declarator() { if (closeReqd = (sc != null && sc != sym.GetCurScope())) sym.OpenScope(sc); } (exception_spec())? ( ";" | [ ctor_initializer() ] compound_statement() ) { if (closeReqd) sym.CloseScope(); } } void ctor_declarator_lookahead() : {} { LOOKAHEAD( { IsCtor() } ) qualified_id() "(" } Scope ctor_declarator() : { String name; Scope sc = null; boolean closeReqd = false; } { LOOKAHEAD( { IsCtor() } ) name = qualified_id() { sc = sym.GetScopeOfFullyScopedName(name); if (closeReqd = (sc != null && sc != sym.GetCurScope())) sym.OpenScope(sc); } "(" [ LOOKAHEAD(2) parameter_list() ] ")" [ LOOKAHEAD(2) exception_spec() ] { if (closeReqd) sym.CloseScope(); return sc; } } void ctor_initializer() : {} { ":" superclass_init() ("," superclass_init())* } void superclass_init() : {} { qualified_id() "(" (expression_list())? ")" } void dtor_declarator() : {} { (LOOKAHEAD(scope_override_lookahead()) scope_override())? simple_dtor_declarator() } void simple_dtor_declarator() : {} { "~" LOOKAHEAD( { IsCtor() } ) "(" (parameter_list())? ")" } void parameter_list() : {} { parameter_declaration_list() [ LOOKAHEAD(2) [ "," ] "..." ] | "..." } void parameter_declaration_list() : {} { parameter_declaration() (LOOKAHEAD(2) "," parameter_declaration())* } void parameter_declaration() : {} { declaration_specifiers() ( LOOKAHEAD(declarator()) declarator() | abstract_declarator() ) ("=" assignment_expression())? } void initializer() : {} { LOOKAHEAD(3) "{" initializer() ("," initializer())* "}" | assignment_expression() } void type_name() : {} { declaration_specifiers() abstract_declarator() } void abstract_declarator() : {} { [ LOOKAHEAD(2) ( "(" abstract_declarator() ")" (abstract_declarator_suffix())+ | ("[" (constant_expression())? "]")+ | ptr_operator() abstract_declarator() ) ] } void abstract_declarator_suffix() : {} { "[" ( constant_expression() )? "]" | "(" (parameter_list())? ")" } void template_head() : {} { "template" "<" template_parameter_list() ">" } void template_parameter_list() : {} { template_parameter() ("," template_parameter())* } void template_parameter() : { Token t; } { LOOKAHEAD(3) "class" t= { sym.PutTypeName(t.getImage()); } | parameter_declaration() } void template_id() : {} { "<" template_argument_list() ">" } void template_argument_list() : {} { template_argument() ("," template_argument())* } void template_argument() : {} { LOOKAHEAD(3) type_name() | shift_expression() } void statement_list() : {} { (LOOKAHEAD(statement()) statement())+ } void statement() : {} { LOOKAHEAD( declaration() ) declaration() | LOOKAHEAD( expression() ";" ) expression() ";" | compound_statement() | selection_statement() | jump_statement() | ";" | try_block() | throw_statement() | LOOKAHEAD(2) labeled_statement() | iteration_statement() } void labeled_statement() : {} { ":" statement() | "case" constant_expression() ":" statement() | "default" ":" statement() } void compound_statement() : {} { "{" { sym.OpenScope(null, false); } (statement_list())? { sym.CloseScope(); } "}" } void selection_statement() : {} { "if" "(" expression() ")" statement() (LOOKAHEAD(2) "else" statement())? | "switch" "(" expression() ")" statement() } void iteration_statement() : {} { "while" "(" expression() ")" statement() | "do" statement() "while" "(" expression() ")" ";" | "for" "(" (LOOKAHEAD(3) declaration() | expression() ";" | ";") (expression())? ";" (expression())? ")" statement() } void jump_statement() : {} { "goto" ";" | "continue" ";" | "break" ";" | "return" (expression())? ";" } void try_block() : {} { "try" compound_statement() (handler())* } void handler() : {} { "catch" "(" exception_declaration() ")" compound_statement() | "finally" compound_statement() } void exception_declaration() : {} { parameter_declaration_list() | "..." } void throw_statement() : {} { "throw" (assignment_expression())? ";" } void expression() : {} { assignment_expression() ( LOOKAHEAD(2) "," assignment_expression())* } void assignment_expression() : {} { conditional_expression() (("=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" ) assignment_expression() )? } void conditional_expression() : {} { logical_or_expression() ("?" conditional_expression() ":" conditional_expression())? } void constant_expression() : {} { conditional_expression() } void logical_or_expression() : {} { logical_and_expression() ( "||" logical_and_expression())* } void logical_and_expression() : {} { inclusive_or_expression() ( "&&" inclusive_or_expression())* } void inclusive_or_expression() : {} { exclusive_or_expression()( "|" exclusive_or_expression())* } void exclusive_or_expression() : {} { and_expression()( "^" and_expression())* } void and_expression() : {} { equality_expression()( LOOKAHEAD(2) "&" equality_expression())* } void equality_expression() : {} { relational_expression()(( "!=" | "==") relational_expression())* } void relational_expression() : {} { shift_expression() ( LOOKAHEAD(2) ( "<" | ">" | "<=" | ">=" ) shift_expression() )* } void shift_expression() : {} { additive_expression()(( "<<" | ">>") additive_expression())* } void additive_expression() : {} { multiplicative_expression() (LOOKAHEAD(2) ( "+" | "-") multiplicative_expression())* } void multiplicative_expression() : {} { pm_expression() (LOOKAHEAD(2) ( "*" | "/" | "%") pm_expression())* } void pm_expression() : {} { cast_expression() (( ".*" | "->*" ) cast_expression())* } void cast_expression() : {} { LOOKAHEAD( "(" type_name() ")" ) "(" type_name() ")" cast_expression() | unary_expression() } void unary_expression() : {} { "++" unary_expression() | "--" unary_expression() | LOOKAHEAD(3) unary_operator() cast_expression() | "sizeof" ( LOOKAHEAD("(") "(" type_name() ")" | unary_expression() ) | postfix_expression() } void new_expression() : {} { (LOOKAHEAD("::") ("::"))? "new" ( LOOKAHEAD("(" type_name() ")" ) "(" type_name() ")" | (LOOKAHEAD("(" expression_list() ) "(" expression_list() ")")? ( LOOKAHEAD("(" type_name() ")" ) "(" type_name() ")" | LOOKAHEAD(declaration_specifiers()) new_type_id() ) ) (LOOKAHEAD(new_initializer()) new_initializer())? } void new_type_id() : {} { declaration_specifiers() ( LOOKAHEAD(new_declarator()) new_declarator() )? } void new_declarator() : {} { direct_new_declarator() | ptr_operator() cv_qualifier_seq() [ LOOKAHEAD(2) new_declarator() ] } void direct_new_declarator() : {} { (LOOKAHEAD(2) "[" expression() "]" )+ } void new_initializer() : {} { "(" ( expression_list() )? ")" } void delete_expression() : {} { ( "::" )? "delete" ( "[" "]" )? cast_expression() } void unary_operator() : {} { "&" | "*" | "+" | "-" | "~" | "!" } void postfix_expression() : {} { LOOKAHEAD(3) primary_expression() ( LOOKAHEAD(2) ( "[" expression() "]" | "(" ( expression_list() )? ")" | "." id_expression() | "->" id_expression() | "++" | "--" ) )* | simple_type_specifier() "(" ( expression_list() )? ")" } void id_expression() : {} { (LOOKAHEAD(scope_override_lookahead()) scope_override())? ( | "operator" optor() | "~" ) } void primary_expression() : {} { "this" | ( LOOKAHEAD(2) )+ | "(" expression() ")" | LOOKAHEAD( ("::")? "new") new_expression() | LOOKAHEAD( ("::")? "delete") delete_expression() | id_expression() | constant() } void expression_list() : {} { assignment_expression()( "," assignment_expression())* } void constant() : {} { | | | | | | "true" | "false" } void optor() : {} { "new" [ LOOKAHEAD(2) "[" "]" ] | "delete" [ LOOKAHEAD(2) "[" "]" ] | "+" | "-" | "*" | "/" | "%" | "^" | "&" | "|" | "~" | "!" | "=" | "<" | ">" | "+=" | "-=" | "*=" | "/=" | "%=" | "^=" | "&=" | "|=" | "<<" | ">>" | ">>=" | "<<=" | "==" | "!=" | "<=" | ">=" | "&&" | "||" | "++" | "--" | "," | "->*" | "->" | "(" ")" | "[" "]" | declaration_specifiers() (LOOKAHEAD(2) ("*"|"&"))? } void exception_spec() : {} { "throw" "(" exception_list() ")" } void exception_list() : {} { type_name() ( "," type_name())* } /*end*/