Scarlet Line home page Scarlet Line - SOFTWARE DESIGN & DEVELOPMENT

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

Expand All
Collapse All
Contents

C Pre-Processor Grammar Locate in Contents

/*
C pre-processor syntax abstracted from:
WG14/N1124 Committee Draft (c) May 6, 2005 ISO/IEC 9899:TC2
Annex A (informative) - Language syntax summary
*/
%encoding binary
%entrypoint preprocessing-file
// A.1 Lexical grammar
// A.1.1 Lexical elements

	(6.4) preprocessing-token:
			header-name
		|	identifier
		|	pp-number
		|	character-constant
		|	string-literal
		|	punctuator
//		|	// each non-white-space character that cannot be one of the above

// A.1.3 Identifiers

	(6.4.2.1) identifier:
			identifier-nondigit
		|	identifier identifier-nondigit
		|	identifier digit

	(6.4.2.1) identifier-nondigit:
			nondigit
		|	universal-character-name
//		|	other implementation-defined characters

	(6.4.2.1) nondigit:
			'[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]'

	(6.4.2.1) digit:
			'[0123456789]'

// A.1.4 Universal character names

	(6.4.3) universal-character-name:
			"\\u" hex-quad
		|	"\\U" hex-quad hex-quad

	(6.4.3) hex-quad:
			hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit

// A.1.5 Constants

	(6.4.4) constant:
			integer-constant
		|	floating-constant
		|	enumeration-constant
		|	character-constant

	(6.4.4.1) integer-constant:
			decimal-constant integer-suffix?
		|	octal-constant integer-suffix?
		|	hexadecimal-constant integer-suffix?

	(6.4.4.1) decimal-constant:
			nonzero-digit
		|	decimal-constant digit

	(6.4.4.1) octal-constant:
			"0"
		|	octal-constant octal-digit

	(6.4.4.1) hexadecimal-constant:
			hexadecimal-prefix hexadecimal-digit
		|	hexadecimal-constant hexadecimal-digit

	(6.4.4.1) hexadecimal-prefix:
			'0[xX]'

	(6.4.4.1) nonzero-digit:
			'[123456789]'

	(6.4.4.1) octal-digit:
			'[01234567]'

	(6.4.4.1) hexadecimal-digit:
			'[0123456789abcdefABCDEF]'

	(6.4.4.1) integer-suffix:
			unsigned-suffix long-suffix?
		|	unsigned-suffix long-long-suffix
		|	long-suffix unsigned-suffix?
		|	long-long-suffix unsigned-suffix?

	(6.4.4.1) unsigned-suffix:
			'[uU]'

	(6.4.4.1) long-suffix:
			'[lL]'

	(6.4.4.1) long-long-suffix:
			"ll" | "LL"

	(6.4.4.2) floating-constant:
			decimal-floating-constant
		|	hexadecimal-floating-constant

	(6.4.4.2) decimal-floating-constant:
			fractional-constant exponent-part? floating-suffix?
		|	digit-sequence exponent-part floating-suffix?

	(6.4.4.2) hexadecimal-floating-constant:
			hexadecimal-prefix hexadecimal-fractional-constant
		|	binary-exponent-part floating-suffix?
		|	hexadecimal-prefix hexadecimal-digit-sequence
		|	binary-exponent-part floating-suffix?

	(6.4.4.2) fractional-constant:
			digit-sequence? "." digit-sequence
		|	digit-sequence "."

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

	(6.4.4.2) sign:
			'[+\-]'

	(6.4.4.2) digit-sequence:
			digit
		|	digit-sequence digit

	(6.4.4.2) hexadecimal-fractional-constant:
			hexadecimal-digit-sequence? "."
		|	hexadecimal-digit-sequence
		|	hexadecimal-digit-sequence "."

	(6.4.4.2) binary-exponent-part:
			'[pP]' sign? digit-sequence

	(6.4.4.2) hexadecimal-digit-sequence:
			hexadecimal-digit
		|	hexadecimal-digit-sequence hexadecimal-digit

	(6.4.4.2) floating-suffix:
			'[flFL]'

	(6.4.4.3) enumeration-constant:
			identifier

	(6.4.4.4) character-constant:
			"'" c-char-sequence "'"
		|	"L'" c-char-sequence "'"

	(6.4.4.4) c-char-sequence:
			c-char
		|	c-char-sequence c-char

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

	(6.4.4.4) escape-sequence:
			simple-escape-sequence
		|	octal-escape-sequence
		|	hexadecimal-escape-sequence
		|	universal-character-name

	(6.4.4.4) simple-escape-sequence:
			"\\'" |	'\\"' |	"\\?" |	"\\\\"

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

	(6.4.4.4) octal-escape-sequence:
			"\\" octal-digit
		|	"\\" octal-digit octal-digit
		|	"\\" octal-digit octal-digit octal-digit

	(6.4.4.4) hexadecimal-escape-sequence:
			"\\x" hexadecimal-digit
		|	hexadecimal-escape-sequence hexadecimal-digit

// A.1.6 String literals

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

	(6.4.5) s-char-sequence:
			s-char
		|	s-char-sequence s-char

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

// A.1.7 Punctuators

	(6.4.6) punctuator:
			"[" |	"]" |	"(" |	")" |	"{" |	"}" |	"." |	"->"

		|	"++" |	"--" |	"&" |	"*" |	"+" |	"-" |	"~" |	"!"

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

		|	"?" |	":" |	";" |	"..."
		|	"=" |	"*=" |	"/=" |	"%=" |	"+=" |	"-=" |	"<<=" |	">>=" |	"&=" |	"^=" |	"|="

		|	"," |	"#" |	"##"
		|	"<:" |	":>" |	"<%" |	"%>" |	"%:" |	"%:%:"

// A.1.8 Header names

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

	(6.4.7) h-char-sequence:
			h-char
		|	h-char-sequence h-char

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

	(6.4.7) q-char-sequence:
			q-char
		|	q-char-sequence q-char

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

// A.1.9 Preprocessing numbers

	(6.4.8) pp-number:
			digit
		|	"." digit
		|	pp-number digit
		|	pp-number identifier-nondigit
		|	pp-number "e" sign
		|	pp-number "E" sign
		|	pp-number "p" sign
		|	pp-number "P" sign
		|	pp-number "."

// A.2 Phrase structure grammar
// A.2.1 Expressions

	(6.5.1) primary-expression:
			identifier
		|	constant
		|	string-literal
		|	"(" expression ")"

	(6.5.2) postfix-expression:
			primary-expression
		|	postfix-expression "[" expression "]"
		|	postfix-expression "(" argument-expression-list? ")"

		|	postfix-expression "." identifier
		|	postfix-expression "->" identifier
		|	postfix-expression "++"
		|	postfix-expression "--"
		|	"(" type-name ")" "{" initializer-list "}"

		|	"(" type-name ")" "{" initializer-list "," "}"

	(6.5.2) argument-expression-list:
			assignment-expression
		|	argument-expression-list "," assignment-expression

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

	(6.5.3) unary-operator:
			"&" | "*" | "+" | "-" | "~" | "!"

	(6.5.4) cast-expression:
			unary-expression
		|	"(" type-name ")" cast-expression

	(6.5.5) multiplicative-expression:
			cast-expression
		|	multiplicative-expression "*" cast-expression
		|	multiplicative-expression "/" cast-expression
		|	multiplicative-expression "%" cast-expression

	(6.5.6) additive-expression:
			multiplicative-expression
		|	additive-expression "+" multiplicative-expression
		|	additive-expression "-" multiplicative-expression

	(6.5.7) shift-expression:
			additive-expression
		|	shift-expression "<<" additive-expression
		|	shift-expression ">>" additive-expression

	(6.5.8) relational-expression:
			shift-expression
		|	relational-expression "<" shift-expression
		|	relational-expression ">" shift-expression
		|	relational-expression "<=" shift-expression
		|	relational-expression ">=" shift-expression

	(6.5.9) equality-expression:
			relational-expression
		|	equality-expression "==" relational-expression
		|	equality-expression "!=" relational-expression

	(6.5.10) AND-expression:
			equality-expression
		|	AND-expression "&" equality-expression

	(6.5.11) exclusive-OR-expression:
			AND-expression
		|	exclusive-OR-expression "^" AND-expression

	(6.5.12) inclusive-OR-expression:
			exclusive-OR-expression
		|	inclusive-OR-expression "|" exclusive-OR-expression

	(6.5.13) logical-AND-expression:
			inclusive-OR-expression
		|	logical-AND-expression "&&" inclusive-OR-expression

	(6.5.14) logical-OR-expression:
			logical-AND-expression
		|	logical-OR-expression "||" logical-AND-expression

	(6.5.15) conditional-expression:
			logical-OR-expression
		|	logical-OR-expression "?" expression ":" conditional-expression

	(6.5.16) assignment-expression:
			conditional-expression
		|	unary-expression assignment-operator assignment-expression

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

	(6.5.17) expression:
			assignment-expression
		|	expression "," assignment-expression

	(6.6) constant-expression:
			conditional-expression

// A.2.2 Declarations

	(6.7) declaration-specifiers:
			storage-class-specifier declaration-specifiers?
		|	type-specifier declaration-specifiers?
		|	type-qualifier declaration-specifiers?
		|	function-specifier declaration-specifiers?

	(6.7.1) storage-class-specifier:
			"typedef"
		|	"extern"
		|	"static"
		|	"auto"

		|	"register"

	(6.7.2) type-specifier:
			"void"
		|	"char"
		|	"short"

		|	"int"
		|	"long"
		|	"float"
		|	"double"
		|	"signed"

		|	"unsigned"
		|	"_Bool"
		|	"_Complex"
		|	struct-or-union-specifier
		|	enum-specifier
		|	typedef-name

	(6.7.2.1) struct-or-union-specifier:
			struct-or-union identifier? "{" struct-declaration-list "}"

		|	struct-or-union identifier

	(6.7.2.1) struct-or-union:
			"struct"
		|	"union"

	(6.7.2.1) struct-declaration-list:
			struct-declaration
		|	struct-declaration-list struct-declaration

	(6.7.2.1) struct-declaration:
			specifier-qualifier-list struct-declarator-list ";"

	(6.7.2.1) specifier-qualifier-list:
			type-specifier specifier-qualifier-list?
		|	type-qualifier specifier-qualifier-list?

	(6.7.2.1) struct-declarator-list:
			struct-declarator
		|	struct-declarator-list "," struct-declarator

	(6.7.2.1) struct-declarator:
			declarator
		|	declarator? ":" constant-expression

	(6.7.2.2) enum-specifier:
			"enum" identifier? "{" enumerator-list "}"

		|	"enum" identifier? "{" enumerator-list "," "}"
		|	"enum" identifier

	(6.7.2.2) enumerator-list:
			enumerator
		|	enumerator-list "," enumerator

	(6.7.2.2) enumerator:
			enumeration-constant
		|	enumeration-constant "=" constant-expression

	(6.7.3) type-qualifier:
			"const"

		|	"restrict"
		|	"volatile"

	(6.7.4) function-specifier:
			"inline"

	(6.7.5) declarator:
			pointer? direct-declarator

	(6.7.5) direct-declarator:
			identifier
		|	"(" declarator ")"

		|	direct-declarator "[" type-qualifier-list? assignment-expression? "]"
		|	direct-declarator "[" "static" type-qualifier-list? assignment-expression "]"
		|	direct-declarator "[" type-qualifier-list "static" assignment-expression "]"

		|	direct-declarator "[" type-qualifier-list? "*" "]"
		|	direct-declarator "(" parameter-type-list ")"
		|	direct-declarator "(" identifier-list? ")"

	(6.7.5) pointer:
			"*" type-qualifier-list?
		|	"*" type-qualifier-list? pointer

	(6.7.5) type-qualifier-list:
			type-qualifier
		|	type-qualifier-list type-qualifier

	(6.7.5) parameter-type-list:
			parameter-list
		|	parameter-list "," "..."

	(6.7.5) parameter-list:
			parameter-declaration
		|	parameter-list "," parameter-declaration

	(6.7.5) parameter-declaration:
			declaration-specifiers declarator
		|	declaration-specifiers abstract-declarator?

	(6.7.5) identifier-list:
			identifier
		|	identifier-list "," identifier

	(6.7.6) type-name:
			specifier-qualifier-list abstract-declarator?

	(6.7.6) abstract-declarator:
			pointer
		|	pointer? direct-abstract-declarator

	(6.7.6) direct-abstract-declarator:
			"(" abstract-declarator ")"

		|	direct-abstract-declarator? "[" assignment-expression? "]"
		|	direct-abstract-declarator? "[" "*" "]"
		|	direct-abstract-declarator? "(" parameter-type-list? ")"

	(6.7.7) typedef-name:
			identifier

	(6.7.8) initializer:
			assignment-expression
		|	"{" initializer-list "}"
		|	"{" initializer-list "," "}"

	(6.7.8) initializer-list:
			designation? initializer
		|	initializer-list "," designation? initializer

	(6.7.8) designation:
			designator-list "="

	(6.7.8) designator-list:
			designator
		|	designator-list designator

	(6.7.8) designator:
			"[" constant-expression "]"
		|	"." identifier

// A.3 Preprocessing directives

	(6.10) preprocessing-file:
			group?

	(6.10) group:
			group-part
		|	group group-part

	(6.10) group-part:
			if-section
		|	control-line
		|	text-line
		|	"#" non-directive

	(6.10) if-section:
			if-group elif-groups? else-group? endif-line

	(6.10) if-group:
			"#" "if" constant-expression new-line group?
		|	"#" "ifdef" identifier new-line group?
		|	"#" "ifndef" identifier new-line group?

	(6.10) elif-groups:
			elif-group
		|	elif-groups elif-group

	(6.10) elif-group:
			"#" "elif" constant-expression new-line group?

	(6.10) else-group:
			"#" "else" new-line group?

	(6.10) endif-line:
			"#" "endif" new-line

	(6.10) control-line:
			"#" "include" pp-tokens new-line
		|	"#" "define" identifier replacement-list new-line
		|	"#" "define" identifier-lparen identifier-list? ")" replacement-list new-line
		|	"#" "define" identifier-lparen "..." ")" 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

	(6.10) text-line:
			pp-tokens? new-line

	(6.10) non-directive:
			pp-tokens new-line

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

	(6.10) replacement-list:
			pp-tokens?

	(6.10) pp-tokens:
			preprocessing-token
		|	pp-tokens preprocessing-token

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