Scarlet Line home page Scarlet Line - SOFTWARE DESIGN & DEVELOPMENT

[Home]->[Documentation]->[Syntac Universal Parser]->[Programming Languages]->[C++]->[Grammar]

Expand All
Collapse All
Contents

C++ Grammar Locate in Contents

/*
C++ syntax abstracted from:
ISO/IEC 14882 Second Edition 2003-10-15
Annex A (informative) - Grammar summary
*/
%encoding binary
%entrypoint translation-unit preprocessing-file

// A.2 Lexical conventions [gram.lex]
	hex-quad:
			hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit

	universal-character-name:
			"\\u" hex-quad
			"\\U" hex-quad hex-quad

	preprocessing-token:
			header-name
		|	identifier
		|	pp-number
		|	character-literal
		|	string-literal
		|	preprocessing-op-or-punc
//		|	// each non-white-space character that cannot be one of the above

	token:
			identifier
		|	keyword
		|	literal
		|	operator
		|	punctuator

	header-name:
			'<' h-char-sequence '>'
		|	'"' q-char-sequence '"'

	h-char-sequence:
			h-char
		|	h-char-sequence h-char

	h-char:
			'[^\n>]' // any member of the source character set except the new-line character and >

	q-char-sequence:
			q-char
		|	q-char-sequence q-char

	q-char:
			'[^\n"]' // any member of the source character set except the new-line character and "

	pp-number:
			digit
		|	"." digit
		|	pp-number digit
		|	pp-number nondigit
		|	pp-number "e" sign
		|	pp-number "E" sign
		|	pp-number "."

	identifier:
			nondigit
		|	identifier nondigit
		|	identifier digit

	nondigit:
			universal-character-name
		|	'[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]'

	digit:
			'[0123456789]'

	preprocessing-op-or-punc:
			"{" | "}" | "[" | "]" | "#" | "##" | "(" | ")"

		|	"<:" | ":>" | "<%" | "%>" | "%:" | "%:%:" | ";" | ":" | "..."

		|	"new" | "delete" | "?" | "::" | "." | ".*"

		|	"+" | "-" | "*" | "/" | "%" | "^" | "&" | "|" | "~"

		|	"!" | "=" | "<" | ">" | "+=" | "-=" | "*=" | "/=" | "%="

		|	"^=" | "&=" | "|=" | "<<" | ">>" | ">>=" | "<<=" | "==" | "!="

		|	"<=" | ">=" | "&&" | "||" | "++" | "--" | "," | "->*" | "->"

		|	"and" | "and_eq" | "bitand" | "bitor" | "compl" | "not" | "not_eq"

		|	"or" | "or_eq" | "xor" | "xor_eq"

	literal:
			integer-literal
		|	character-literal
		|	floating-literal
		|	string-literal
		|	boolean-literal

	integer-literal:
			decimal-literal integer-suffix?
		|	octal-literal integer-suffix?
		|	hexadecimal-literal integer-suffix?
	
	decimal-literal:
			nonzero-digit
		|	decimal-literal digit
	
	octal-literal:
			"0"

		|	octal-literal octal-digit

	hexadecimal-literal:
			'0[xX]' hexadecimal-digit
		|	hexadecimal-literal hexadecimal-digit

	nonzero-digit:
			'[123456789]'

	octal-digit:
			'[01234567]'

	hexadecimal-digit:
			'[0123456789abcdefABCDEF]'

	integer-suffix:
			unsigned-suffix long-suffix?
		|	long-suffix unsigned-suffix?
	
	unsigned-suffix:
			'[uU]'

	long-suffix:
			'[lL]'

	character-literal:
			"'" c-char-sequence "'"
		|	"L'" c-char-sequence "'"

	c-char-sequence:
			c-char
		|	c-char-sequence c-char

	c-char:
			'[^\'\\\n]' // any member of the source character set except the single-quote ', backslash \, or new-line character
		|	escape-sequence
		|	universal-character-name

	escape-sequence:
			simple-escape-sequence
		|	octal-escape-sequence
		|	hexadecimal-escape-sequence

	simple-escape-sequence:
			"\\'" |	'\\"' |	"\\?" |	"\\\\"

		|	"\\a" |	"\\b" |	"\\f" |	"\\n" |	"\\r" |	"\\t" | "\\v"

	octal-escape-sequence:
			"\\" octal-digit
		|	"\\" octal-digit octal-digit
		|	"\\" octal-digit octal-digit octal-digit

	hexadecimal-escape-sequence:
			"\\x" hexadecimal-digit
		|	hexadecimal-escape-sequence hexadecimal-digit

	floating-literal:
			fractional-constant exponent-part? floating-suffix?
		|	digit-sequence exponent-part floating-suffix?

	fractional-constant:
			digit-sequence? "." digit-sequence
		|	digit-sequence "."

	exponent-part:
			'[eE]' sign? digit-sequence

	sign:
			'[+\-]'

	digit-sequence:
			digit
		|	digit-sequence digit

	floating-suffix:
			'[flFL]'

	string-literal:
			'"' s-char-sequence? '"'
		|	'L"' s-char-sequence? '"'

	s-char-sequence:
			s-char
		|	s-char-sequence s-char

	s-char:
			'[^"\\\n]' // any member of the source character set except the double-quote ", backslash \, or new-line character
		|	escape-sequence
		|	universal-character-name

	boolean-literal:
			"false"
		|	"true"

// A.3 Basic concepts [gram.basic]
	translation-unit:
			declaration-seq?

// A.4 Expressions [gram.expr]
	primary-expression:
			literal
		|	"this"

		|	"(" expression ")"
		|	id-expression
	
	id-expression:
			unqualified-id
		|	qualified-id

	unqualified-id:
			identifier
		|	operator-function-id
		|	conversion-function-id
		|	"~" class-name
		|	template-id

	qualified-id:
			"::"? nested-name-specifier "template"? unqualified-id
		|	"::" identifier
		|	"::" operator-function-id
		|	"::" template-id

	nested-name-specifier:
			class-or-namespace-name "::" nested-name-specifier?
		|	class-or-namespace-name "::" "template" nested-name-specifier

	class-or-namespace-name:
			class-name
		|	namespace-name

	postfix-expression:
			primary-expression
		|	postfix-expression "[" expression "]"

		|	postfix-expression "(" expression-list? ")"
		|	simple-type-specifier "(" expression-list? ")"
		|	"typename" "::"? nested-name-specifier identifier "(" expression-list? ")"

		|	"typename" "::"? nested-name-specifier "template"? template-id "(" expression-list? ")"
		|	postfix-expression "." "template"? id-expression
		|	postfix-expression "->" "template"? id-expression
		|	postfix-expression "." pseudo-destructor-name
		|	postfix-expression "->" pseudo-destructor-name
		|	postfix-expression "++"

		|	postfix-expression "--"
		|	"dynamic_cast" "<" type-id ">" "(" expression ")"
		|	"static_cast" "<" type-id ">" "(" expression ")"

		|	"reinterpret_cast" "<" type-id ">" "(" expression ")"
		|	"const_cast" "<" type-id ">" "(" expression ")"

		|	"typeid" "(" expression ")"
		|	"typeid" "(" type-id ")"

	expression-list:
			assignment-expression
		|	expression-list "," assignment-expression

	pseudo-destructor-name:
			"::"? nested-name-specifier? type-name "::" "~" type-name
		|	"::"? nested-name-specifier "template" template-id "::" "~" type-name
		|	"::"? nested-name-specifier? "~" type-name

	unary-expression:
			postfix-expression
		|	"++" cast-expression
		|	"--" cast-expression
		|	unary-operator cast-expression
		|	"sizeof" unary-expression
		|	"sizeof" "(" type-id ")"

		|	new-expression
		|	delete-expression

	unary-operator:
			"*" | "&" | "+" | "-" | "!" | "~"

	new-expression:
			"::"? "new" new-placement? new-type-id new-initializer?
		|	"::"? "new" new-placement? "(" type-id ")" new-initializer?
	
	new-placement:
			"(" expression-list ")"

	new-type-id:
			type-specifier-seq new-declarator?

	new-declarator:
			ptr-operator new-declarator?
		|	direct-new-declarator

	direct-new-declarator:
			"[" expression "]"
		|	direct-new-declarator "[" constant-expression "]"

	new-initializer:
			"(" expression-list? ")"

	delete-expression:
			"::"? "delete" cast-expression
		|	"::"? "delete" "[" "]" cast-expression

	cast-expression:
			unary-expression
		|	"(" type-id ")" cast-expression

	pm-expression:
			cast-expression
		|	pm-expression ".*" cast-expression
		|	pm-expression "->*" cast-expression

	multiplicative-expression:
			pm-expression
		|	multiplicative-expression "*" pm-expression
		|	multiplicative-expression "/" pm-expression
		|	multiplicative-expression "%" pm-expression

	additive-expression:
			multiplicative-expression
		|	additive-expression "+" multiplicative-expression
		|	additive-expression "-" multiplicative-expression

	shift-expression:
			additive-expression
		|	shift-expression "<<" additive-expression
		|	shift-expression ">>" additive-expression

	relational-expression:
			shift-expression
		|	relational-expression "<" shift-expression
		|	relational-expression ">" shift-expression
		|	relational-expression "<=" shift-expression
		|	relational-expression ">=" shift-expression

	equality-expression:
			relational-expression
		|	equality-expression "==" relational-expression
		|	equality-expression "!=" relational-expression

	and-expression:
			equality-expression
		|	and-expression "&" equality-expression

	exclusive-or-expression:
			and-expression
		|	exclusive-or-expression "^" and-expression

	inclusive-or-expression:
			exclusive-or-expression
		|	inclusive-or-expression "|" exclusive-or-expression

	logical-and-expression:
			inclusive-or-expression
		|	logical-and-expression "&&" inclusive-or-expression

	logical-or-expression:
			logical-and-expression
		|	logical-or-expression "||" logical-and-expression

	conditional-expression:
			logical-or-expression
		|	logical-or-expression "?" expression ":" assignment-expression

	assignment-expression:
			conditional-expression
		|	logical-or-expression assignment-operator assignment-expression
		|	throw-expression

	assignment-operator:
			"=" | "*=" | "/=" | "%=" | "+=" | "-=" | ">>=" | "<<=" | "&=" | "^=" | "|="

	expression:
			assignment-expression
		|	expression "," assignment-expression

	constant-expression:
			conditional-expression

// A.5 Statements [gram.stmt.stmt]

	statement:
			labeled-statement
		|	expression-statement
		|	compound-statement
		|	selection-statement
		|	iteration-statement
		|	jump-statement
		|	declaration-statement
		|	try-block

	labeled-statement:
			identifier ":" statement
		|	"case" constant-expression ":" statement
		|	"default" ":" statement

	expression-statement:
			expression? ";"

	compound-statement:
			"{" statement-seq? "}"

	statement-seq:
			statement
		|	statement-seq statement

	selection-statement:
			"if" "(" condition ")" statement
		|	"if" "(" condition ")" statement "else" statement
		|	"switch" "(" condition ")" statement

	condition:
			expression
		|	type-specifier-seq declarator "=" assignment-expression

	iteration-statement:
			"while" "(" condition ")" statement
		|	"do" statement "while" "(" expression ")" ";"

		|	"for" "(" for-init-statement condition? ";" expression? ")" statement

	for-init-statement:
			expression-statement
		|	simple-declaration

	jump-statement:
			"break" ";"

			"continue" ";"
			"return" expression? ";"
			"goto" identifier ";"

	declaration-statement:
			block-declaration

// A.6 Declarations [gram.dcl.dcl]
	declaration-seq:
			declaration
		|	declaration-seq declaration

	declaration:
			block-declaration
		|	function-definition
		|	template-declaration
		|	explicit-instantiation
		|	explicit-specialization
		|	linkage-specification
		|	namespace-definition

	block-declaration:
			simple-declaration
		|	asm-definition
		|	namespace-alias-definition
		|	using-declaration
		|	using-directive

	simple-declaration:
			decl-specifier-seq? init-declarator-list? ";"

	decl-specifier:
			storage-class-specifier
		|	type-specifier
		|	function-specifier
		|	"friend"
		|	"typedef"

	decl-specifier-seq:
			decl-specifier-seq? decl-specifier

	storage-class-specifier:
			"auto"

		|	"register"
		|	"static"
		|	"extern"
		|	"mutable"

	function-specifier:
			"inline"
		|	"virtual"
		|	"explicit"

	typedef-name:
			identifier

	type-specifier:
			simple-type-specifier
		|	class-specifier
		|	enum-specifier
		|	elaborated-type-specifier
		|	cv-qualifier

	simple-type-specifier:
			"::"? nested-name-specifier? type-name
		|	"::"? nested-name-specifier "template" template-id
		|	"char"

		|	"wchar_t"
		|	"bool"
		|	"short"
		|	"int"
		|	"long"

		|	"signed"
		|	"unsigned"
		|	"float"
		|	"double"
		|	"void"

	type-name:
			class-name
		|	enum-name
		|	typedef-name

	elaborated-type-specifier:
			class-key "::"? nested-name-specifier? identifier
		|	class-key "::"? nested-name-specifier? "template"? template-id
		|	"enum" "::"? nested-name-specifier? identifier
		|	"typename" "::"? nested-name-specifier identifier
		|	"typename" "::"? nested-name-specifier "template"? template-id

	enum-name:
			identifier

	enum-specifier:
			"enum" identifier? "{" enumerator-list? "}"

	enumerator-list:
			enumerator-definition
		|	enumerator-list "," enumerator-definition

	enumerator-definition:
			enumerator
		|	enumerator "=" constant-expression

	enumerator:
			identifier

	namespace-name:
			original-namespace-name
		|	namespace-alias

	original-namespace-name:
			identifier

	namespace-definition:
			named-namespace-definition
		|	unnamed-namespace-definition

	named-namespace-definition:
			original-namespace-definition
		|	extension-namespace-definition

	original-namespace-definition:
			"namespace" identifier "{" namespace-body "}"

	extension-namespace-definition:
			"namespace" original-namespace-name "{" namespace-body "}"

	unnamed-namespace-definition:
			"namespace" "{" namespace-body "}"

	namespace-body:
			declaration-seq?

	namespace-alias:
			identifier

	namespace-alias-definition:
			"namespace" identifier "=" qualified-namespace-specifier ";"

	qualified-namespace-specifier:
			"::"? nested-name-specifier? namespace-name

	using-declaration:
			"using" "typename"? "::"? nested-name-specifier unqualified-id ";"

		|	"using" "::" unqualified-id ";"

	using-directive:
			"using" "namespace" "::"? nested-name-specifier? namespace-name ";"

	asm-definition:
			"asm" "(" string-literal ")" ";"

	linkage-specification:
			"extern" string-literal "{" declaration-seq? "}"

		|	"extern" string-literal declaration

// A.7 Declarators [gram.dcl.decl]
	init-declarator-list:
			init-declarator
		|	init-declarator-list "," init-declarator

	init-declarator:
			declarator initializer?

	declarator:
			direct-declarator
		|	ptr-operator declarator

	direct-declarator:
			declarator-id
		|	direct-declarator "(" parameter-declaration-clause ")" cv-qualifier-seq? exception-specification?
		|	direct-declarator "[" constant-expression? "]"

		|	"(" declarator ")"

	ptr-operator:
			"*" cv-qualifier-seq?
		|	"&"
		|	"::"? nested-name-specifier "*" cv-qualifier-seq?

	cv-qualifier-seq:
			cv-qualifier cv-qualifier-seq?

	cv-qualifier:
			"const"

		|	"volatile"

	declarator-id:
			id-expression
		|	"::"? nested-name-specifier? type-name

	type-id:
			type-specifier-seq abstract-declarator?

	type-specifier-seq:
			type-specifier type-specifier-seq?

	abstract-declarator:
			ptr-operator abstract-declarator?
		|	direct-abstract-declarator

	direct-abstract-declarator:
			direct-abstract-declarator?
		|	"(" parameter-declaration-clause ")" cv-qualifier-seq? exception-specification?
		|	direct-abstract-declarator? "[" constant-expression? "]"

		|	"(" abstract-declarator ")"

	parameter-declaration-clause:
			parameter-declaration-list? "..."?
		|	parameter-declaration-list "," "..."

	parameter-declaration-list:
			parameter-declaration
		|	parameter-declaration-list "," parameter-declaration

	parameter-declaration:
			decl-specifier-seq declarator
		|	decl-specifier-seq declarator "=" assignment-expression
		|	decl-specifier-seq abstract-declarator?
		|	decl-specifier-seq abstract-declarator? "=" assignment-expression

	function-definition:
			decl-specifier-seq? declarator ctor-initializer? function-body
		|	decl-specifier-seq? declarator function-try-block

	function-body:
			compound-statement

	initializer:
			"=" initializer-clause
		|	"(" expression-list ")"

	initializer-clause:
			assignment-expression
		|	"{" initializer-list ","? "}"
		|	"{" "}"

	initializer-list:
			initializer-clause
		|	initializer-list "," initializer-clause

// A.8 Classes [gram.class]
	class-name:
			identifier
		|	template-id

	class-specifier:
			class-head "{" member-specification? "}"

	class-head:
			class-key identifier? base-clause?
		|	class-key nested-name-specifier identifier base-clause?
		|	class-key nested-name-specifier? template-id base-clause?

	class-key:
			"class"
		|	"struct"

		|	"union"

	member-specification:
			member-declaration member-specification?
		|	access-specifier ":" member-specification?

	member-declaration:
			decl-specifier-seq? member-declarator-list? ";"
		|	function-definition ";"?
		|	"::"? nested-name-specifier "template"? unqualified-id ";"

		|	using-declaration
		|	template-declaration

	member-declarator-list:
			member-declarator
		|	member-declarator-list "," member-declarator

	member-declarator:
			declarator pure-specifier?
		|	declarator constant-initializer?
		|	identifier? ":" constant-expression

	pure-specifier:
			"=" "0"

	constant-initializer:
			"=" constant-expression

// A.9 Derived classes [gram.class.derived]
	base-clause:
			":" base-specifier-list

	base-specifier-list:
			base-specifier
		|	base-specifier-list "," base-specifier

	base-specifier:
			"::"? nested-name-specifier? class-name
		|	"virtual" access-specifier? "::"? nested-name-specifier? class-name
		|	access-specifier "virtual"? "::"? nested-name-specifier? class-name

	access-specifier:
			"private"

		|	"protected"
		|	"public"

// A.10 Special member functions [gram.special]
	conversion-function-id:
			"operator" conversion-type-id

	conversion-type-id:
			type-specifier-seq conversion-declarator?

	conversion-declarator:
			ptr-operator conversion-declarator?

	ctor-initializer:
			":" mem-initializer-list

	mem-initializer-list:
			mem-initializer
		|	mem-initializer "," mem-initializer-list

	mem-initializer:
			mem-initializer-id "(" expression-list? ")"

	mem-initializer-id:
			"::"? nested-name-specifier? class-name
		|	identifier

// A.11 Overloading [gram.over]
	operator-function-id:
			"operator" operator
		|	"operator" operator "<" template-argument-list? ">"

	operator:
			"new" | "delete" | "new[]" | "delete[]"

		|	"+" | "-" | "*" | "/" | "%" | "^" | "&" | "|" | "~"

		|	"!" | "=" | "<" | ">" | "+=" | "-=" | "*=" | "/=" | "%="

		|	"^=" | "&=" | "|=" | "<<" | ">>" | ">>=" | "<<=" | "==" | "!="

		|	"<=" | ">=" | "&&" | "||" | "++" | "--" | "," | "->*" | "->"

		|	"()" | "[]"

// A.12 Templates [gram.temp]
	template-declaration:
			"export"? "template" "<" template-parameter-list ">" declaration

	template-parameter-list:
			template-parameter
		|	template-parameter-list "," template-parameter

	template-parameter:
			type-parameter
		|	parameter-declaration

	type-parameter:
			"class" identifier?
		|	"class" identifier? "=" type-id
		|	"typename" identifier?
		|	"typename" identifier? "=" type-id
		|	"template" "<" template-parameter-list ">" "class" identifier?
		|	"template" "<" template-parameter-list ">" "class" identifier? "=" id-expression

	template-id:
			template-name "<" template-argument-list? ">"

	template-name:
			identifier

	template-argument-list:
			template-argument
		|	template-argument-list "," template-argument

	template-argument:
			assignment-expression
		|	type-id
		|	id-expression

	explicit-instantiation:
			"template" declaration

	explicit-specialization:
			"template" "<" ">" declaration

// A.13 Exception handling [gram.except]
	try-block:
			"try" compound-statement handler-seq

	function-try-block:
			"try" ctor-initializer? function-body handler-seq

	handler-seq:
			handler handler-seq?

	handler:
			"catch" "(" exception-declaration ")" compound-statement

	exception-declaration:
			type-specifier-seq declarator
		|	type-specifier-seq abstract-declarator
		|	type-specifier-seq
		|	"..."

	throw-expression:
			"throw" assignment-expression?

	exception-specification:
			"throw" "(" type-id-list? ")"

	type-id-list:
			type-id
		|	type-id-list "," type-id

// A.14 Preprocessing directives [gram.cpp]
	preprocessing-file:
			group?

	group:
			group-part
		|	group group-part

	group-part:
			pp-tokens? new-line
		|	if-section
		|	control-line
	
	if-section:
			if-group elif-groups? else-group? endif-line
	
	if-group:
			"#" "if" constant-expression new-line group?
		|	"#" "ifdef" identifier new-line group?
		|	"#" "ifndef" identifier new-line group?

	elif-groups:
			elif-group
		|	elif-groups elif-group

	elif-group:
			"#" "elif" constant-expression new-line group?

	else-group:
			"#" "else" new-line group?

	endif-line:
			"#" "endif" new-line

	control-line:
			"#" "include" pp-tokens new-line
		|	"#" "define" identifier replacement-list new-line
		|	"#" "define" identifier-lparen identifier-list? ")" replacement-list new-line
		|	"#" "undef" identifier new-line
		|	"#" "line" pp-tokens new-line
		|	"#" "error" pp-tokens? new-line
		|	"#" "pragma" pp-tokens? new-line
		|	"#" new-line

%explicit_whitespace
	identifier-lparen:
			identifier "(" // a ( character not immediately preceded by white-space
%implicit_whitespace

	replacement-list:
			pp-tokens?

	identifier-list:
			identifier ( "," identifier )*

	pp-tokens:
			preprocessing-token
		|	pp-tokens preprocessing-token

	new-line:
			'\n' | '/\z' /* the new-line character */ /* or the end of the file, unconsumed */