/** * * 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(CppParser) package net.sourceforge.pmd.lang.cpp.ast; import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.ast.TokenMgrError; public final class CppParser { private static String vers = "0.1"; private static String id = "C++ Parser"; private static void msg(String s) { System.out.println(id + " Version " + vers +": " + s); } public static void main(String args[]) { CppParser parser; java.io.InputStream input; int ai = 0; if (ai == (args.length-1)) { msg("Reading from file " + args[ai] + " . . ."); try { input = new java.io.FileInputStream(args[ai]); } catch (java.io.FileNotFoundException e) { msg("File " + args[0] + " not found."); return; } } else if (ai >= args.length) { msg("Reading from standard input . . ."); input = System.in; } else { msg("Usage: java " + id + " [-d] [inputfile]"); return; } try { parser = new CppParser(input); parser.translation_unit(); msg("Program parsed successfully."); } catch (ParseException e) { msg("Encountered errors during parse."); } } /** * A symbol table manager object. Currently only types are recorded for * doing semantic predicates for parsing. */ static SymtabManager sym; /* * Methods used in semantics predicates. */ /** * Reads a fully qualified name (since it is used during lookahead, we * cannot use token. We have to explicitly use getToken). */ static String GetFullyScopedName() throws ParseException { Token t = getToken(1); if (t.kind != ID && t.kind != SCOPE) return null; StringBuilder s = new StringBuilder(); int i; if (t.kind != SCOPE) { s.append(t.getImage()); t = getToken(2); i = 3; } else i = 2; while (t.kind == SCOPE) { s.append(t.getImage()); s.append((t = getToken(i++)).getImage()); t = getToken(i++); } return s.toString(); } /** * This method first tries to read a sequence of tokens of the form * ("::")? ("::" )* * and if it succeeds then asks the symbol table manager if this is * the name of a constructor. */ static boolean IsCtor() throws ParseException { return sym.IsCtor(GetFullyScopedName()); } } PARSER_END(CppParser) 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 [IGNORE_CASE] : { < OCTALINT : "0" (["'", "0"-"7"])* > | < OCTALLONG : "l" > | < UNSIGNED_OCTALINT : "u" > | < UNSIGNED_OCTALLONG : ("ul" | "lu") > | < #DECIMALDIGIT : ["'", "0"-"9"] > | < DECIMALINT : ["1"-"9"] ()* > | < DECIMALLONG : ["u","l"] > | < UNSIGNED_DECIMALINT : "u" > | < UNSIGNED_DECIMALLONG : ("ul" | "lu") > | < HEXADECIMALINT : "0x" ( | ["a"-"f"])+ > | < HEXADECIMALLONG : (["u","l"])? > | < UNSIGNED_HEXADECIMALINT : "u" > | < UNSIGNED_HEXADECIMALLONG : ("ul" | "lu") > | < FLOATONE : (["0"-"9"]()* "." | "." ()+ | ["0"-"9"]()* "." ()+) ("e" (["-","+"])? ()+)? (["f","l"])? > | < FLOATTWO : ["0"-"9"]()* "e" (["-","+"])? ()+ (["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; } 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; } 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; } if (delim.charAt(i) != curChar) { input_stream.backup(1); continue rstringbody; } } // Matching R"...(...)..." // ^ try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return; } if (curChar != '"') { input_stream.backup(1); continue rstringbody; } break; } } // Setting final token image matchedToken.image = input_stream.GetImage(); matchedToken.endLine = input_stream.getEndLine(); matchedToken.endColumn = input_stream.getEndColumn(); } } TOKEN : { < ID : ["$", "a"-"z","A"-"Z", "_"] (["a"-"z","A"-"Z","0"-"9","_","$"])* > } 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) ("=" )? ("," member_declarator(isTypedef) ("=" )?)* } 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())? (LOOKAHEAD("=") "=" )? { 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*/