-
-
Save grondilu/1d6bb278dcdc8a4cbcfd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# References ISO/IEC 9899:1990 "Information technology - Programming Language C" (C89 for short) | |
grammar C::StdC89Lexer; | |
#rule TOP { | |
# ^ <c-token>+ $ | |
#} | |
# SS 6.4 | |
proto token c-token {*} | |
token c-token:sym<keyword> { <keyword> } | |
token c-token:sym<identifier> { <ident> } | |
token c-token:sym<constant> { <constant> } | |
token c-token:sym<string-literal> { <string-literal> } | |
token c-token:sym<punct> { <punct> } | |
proto token preprocessing-token {*} | |
token preprocessing-token:sym<header-name> { <header-name> } | |
token preprocessing-token:sym<identifier> { <ident> } | |
token preprocessing-token:sym<pp-number> { <pp-number> } | |
token preprocessing-token:sym<character-constant> { <character-constant> } | |
token preprocessing-token:sym<string-literal> { <string-literal> } | |
token preprocessing-token:sym<punct> { <punct> } | |
token preprocessing-token:sym<none-of-above> { <!> } | |
# SS 6.4.1 | |
proto token keyword {*} | |
token keyword:sym<auto> { <sym> } | |
token keyword:sym<break> { <sym> } | |
token keyword:sym<case> { <sym> } | |
token keyword:sym<char> { <sym> } | |
token keyword:sym<const> { <sym> } | |
token keyword:sym<continue> { <sym> } | |
token keyword:sym<default> { <sym> } | |
token keyword:sym<do> { <sym> } | |
token keyword:sym<double> { <sym> } | |
token keyword:sym<else> { <sym> } | |
token keyword:sym<enum> { <sym> } | |
token keyword:sym<extern> { <sym> } | |
token keyword:sym<float> { <sym> } | |
token keyword:sym<for> { <sym> } | |
token keyword:sym<goto> { <sym> } | |
token keyword:sym<if> { <sym> } | |
token keyword:sym<inline> { <sym> } | |
token keyword:sym<int> { <sym> } | |
token keyword:sym<long> { <sym> } | |
token keyword:sym<register> { <sym> } | |
token keyword:sym<restrict> { <sym> } | |
token keyword:sym<return> { <sym> } | |
token keyword:sym<short> { <sym> } | |
token keyword:sym<signed> { <sym> } | |
token keyword:sym<sizeof> { <sym> } | |
token keyword:sym<static> { <sym> } | |
token keyword:sym<struct> { <sym> } | |
token keyword:sym<switch> { <sym> } | |
token keyword:sym<typedef> { <sym> } | |
token keyword:sym<union> { <sym> } | |
token keyword:sym<unsigned> { <sym> } | |
token keyword:sym<void> { <sym> } | |
token keyword:sym<volatile> { <sym> } | |
token keyword:sym<while> { <sym> } | |
token keyword:sym<_Alignas> { <sym> || 'alignas' } # C11 | |
token keyword:sym<_Alignof> { <sym> || 'alignof' } # C11 | |
token keyword:sym<_Atomic> { <sym> || 'atomic' } # C11 | |
token keyword:sym<_Bool> { <sym> || 'bool' } # C99 | |
token keyword:sym<_Complex> { <sym> || 'complex' } # C99 | |
token keyword:sym<_Generic> { <sym> || 'generic' } # C11 | |
token keyword:sym<_Imaginary> { <sym> || 'imaginary' } # C99 | |
token keyword:sym<_Noreturn> { <sym> || 'noreturn' } # C11 | |
token keyword:sym<_Static_assert> { <sym> || 'static_assert' } # C11 | |
token keyword:sym<_Thread_local> { <sym> || 'thread_local' } # C11 | |
# SS 6.4.2.1 | |
# identifier | |
token ident { <ident-alpha> <ident-alnum>* } | |
# identifier-nondigit | |
proto token ident-first {*} | |
token ident-first:sym<_> { <sym> } | |
token ident-first:sym<alpha> { <.alpha> } | |
token ident-first:sym<unichar> { <.universal-character-name> } | |
# identifier-nondigit | digit | |
proto token ident-rest {*} | |
token ident-rest:sym<alpha> { <.ident-first> } | |
token ident-rest:sym<digit> { <.digit> } | |
# digit is built-in in Perl6 | |
# token digit { <[0..9]> } | |
# SS 6.4.3 | |
proto token universal-character-name {*} | |
token universal-character-name:sym<u> { '\\u' <hex-quad> } | |
token universal-character-name:sym<U> { '\\U' <hex-quad> <hex-quad> } | |
token hex-quad { <.xdigit> ** 4 } | |
proto token constant {*} | |
token constant:sym<integer> { <integer-constant> } | |
token constant:sym<floating> { <floating-constant> } | |
token constant:sym<enumeration> { <enumeration-constant> } | |
token constant:sym<character> { <character-constant> } | |
# SS 6.4.4.1 | |
proto token integer-constant {*} | |
token integer-constant:radix(8) { <octal-constant> <integer-suffix>* } | |
token integer-constant:radix(10) { <decimal-constant> <integer-suffix>* } | |
token integer-constant:radix(16) { <hexadecimal-constant> <integer-suffix>* } | |
token octal-constant { '0' <octal-digit>* } | |
token decimal-constant { <.nonzero-digit> <.digit>* } | |
token hexadecimal-constant { <hexadecimal-prefix> <.xdigit>* } | |
token hexadecimal-prefix { '0' <[xX]> } | |
token nonzero-digit { <[1..9]> } | |
token octal-digit { <[0..7]> } | |
# xdigit is built-in in Perl6 | |
# token xdigit { <+digit+[a..f]+[A..F]> } | |
proto token integer-suffix {*} | |
token integer-suffix:sym<L> { <[lL]> } | |
token integer-suffix:sym<LL> { < ll LL > } | |
token integer-suffix:sym<U> { <[uU]> } | |
# SS 6.4.4.2 | |
proto token floating-constant {*} | |
token floating-constant:radix(10) { <decimal-floating-constant> } | |
token floating-constant:radix(16) { <hexadecimal-floating-constant> } | |
proto token decimal-floating-constant {*} | |
token decimal-floating-constant:sym<9.9> { | |
<fractional-constant> <exponent-part>? <floating-suffix>? | |
} | |
token decimal-floating-constant:sym<9e9> { | |
<digit-sequence> <exponent-part> <floating-suffix>? | |
} | |
proto token hexadecimal-floating-constant {*} | |
token hexadecimal-floating-constant:sym<F.F> { | |
<hexadecimal-prefix> | |
<hexadecimal-fractional-constant> | |
<binary-exponent-part> | |
<floating-suffix>? | |
} | |
token hexadecimal-floating-constant:sym<FpF> { | |
<hexadecimal-prefix> | |
<hexadecimal-digit-sequence> | |
<binary-exponent-part> | |
<floating-suffix>? | |
} | |
proto token fractional-constant {*} | |
token fractional-constant:sym<9.9> { | |
<digit-sequence>? '.' <digit-sequence> | |
} | |
token fractional-constant:sym<9.> { | |
<digit-sequence> '.' | |
} | |
token exponent-part { <[eE]> <sign>? <digit-sequence> } | |
token sign { <[+-]> } | |
token digit-sequence { <.digit>+ } | |
proto token hexadecimal-fractional-constant {*} | |
token hexadecimal-fractional-constant:sym<F.F> { | |
<hexadecimal-digit-sequence>? '.' <hexadecimal-digit-sequence> | |
} | |
token hexadecimal-fractional-constant:sym<F.> { | |
<hexadecimal-digit-sequence> '.' | |
} | |
token binary-exponent-part { <[pP]> <sign>? <digit-sequence> } | |
token hexadecimal-digit-sequence { <.xdigit>+ } | |
proto token floating-suffix {*} | |
token floating-suffix:sym<F> { <[fF]> } | |
token floating-suffix:sym<L> { <[lL]> } | |
# SS 6.4.4.3 | |
token enumeration-constant { <ident> } | |
# SS 6.4.4.4 | |
proto token character-constant {*} | |
token character-constant:sym<quote> { "'" <c-char-sequence>? "'" } | |
token character-constant:sym<L> { <sym> "'" <c-char-sequence>? "'" } # C99 wchar_t | |
token character-constant:sym<u> { <sym> "'" <c-char-sequence>? "'" } # C11 char16_t | |
token character-constant:sym<U> { <sym> "'" <c-char-sequence>? "'" } # C11 char32_t | |
token c-char-sequence { <c-char>+ } | |
proto token c-char {*} | |
token c-char:sym<any> { <-[\'\\\n]> } | |
token c-char:sym<escape> { <escape-sequence> } | |
proto token escape-sequence {*} | |
# ... TODO ... | |
proto token simple-escape-sequence {*} | |
proto token octal-escape-sequence {*} | |
proto token hexadecimal-escape-sequence {*} | |
# SS 6.4.5 | |
proto token string-literal {*} | |
token string-literal:sym<quote> { '"' <s-char-sequence>? '"' } | |
token string-literal:sym<L> { <sym> '"' <s-char-sequence>? '"' } # C99 wchar_t * | |
token string-literal:sym<u8> { <sym> '"' <s-char-sequence>? '"' } # C11 UTF-8 | |
token string-literal:sym<u> { <sym> '"' <s-char-sequence>? '"' } # C11 UTF-16 char16_t * | |
token string-literal:sym<U> { <sym> '"' <s-char-sequence>? '"' } # C11 UTF-32 char32_t * | |
token s-char-sequence { <s-char>+ } | |
proto token s-char {*} | |
token s-char:sym<any> { <-[\"\\\n]> } | |
token s-char:sym<escape> { <escape-sequence> } | |
# punctuator | |
proto token punct {*} | |
token punct:sym<pp(> { '(' } # TODO: check for <ws> | |
token punct:sym<(> { <sym> } | |
token punct:sym<)> { <sym> } | |
token punct:sym<[> { <sym> | '<:' } | |
token punct:sym<]> { <sym> | ':>' } | |
token punct:sym<{> { <sym> | '<%' } | |
token punct:sym<}> { <sym> | '%>' } | |
token punct:sym<.> { <sym> } | |
token punct:sym«->» { <sym> } | |
token punct:sym<++> { <sym> } | |
token punct:sym<--> { <sym> } | |
token punct:sym<&> { <sym> } | |
token punct:sym<*> { <sym> } | |
token punct:sym<+> { <sym> } | |
token punct:sym<-> { <sym> } | |
token punct:sym<~> { <sym> } | |
token punct:sym<!> { <sym> } | |
token punct:sym</> { <sym> } | |
token punct:sym<%> { <sym> } | |
token punct:sym«<<» { <sym> } | |
token punct:sym«>>» { <sym> } | |
token punct:sym«<» { <sym> } | |
token punct:sym«>» { <sym> } | |
token punct:sym«<=» { <sym> } | |
token punct:sym«>=» { <sym> } | |
token punct:sym<==> { <sym> } | |
token punct:sym<!=> { <sym> } | |
token punct:sym<^> { <sym> } | |
token punct:sym<|> { <sym> } | |
token punct:sym<&&> { <sym> } | |
token punct:sym<||> { <sym> } | |
token punct:sym<?> { <sym> } | |
token punct:sym<:> { <sym> } | |
token punct:sym<;> { <sym> } | |
token punct:sym<...> { <sym> } | |
token punct:sym<=> { <sym> } | |
token punct:sym<*=> { <sym> } | |
token punct:sym</=> { <sym> } | |
token punct:sym<%=> { <sym> } | |
token punct:sym<+=> { <sym> } | |
token punct:sym<-=> { <sym> } | |
token punct:sym«<<=» { <sym> } | |
token punct:sym«>>=» { <sym> } | |
token punct:sym<&=> { <sym> } | |
token punct:sym<^=> { <sym> } | |
token punct:sym<|=> { <sym> } | |
token punct:sym<,> { <sym> } | |
token punct:sym<#> { <sym> | '%:' } | |
token punct:sym<##> { <sym> | '%:%:' } | |
# SS 6.4.7 | |
proto token header-name {*} | |
token header-name:sym<angle> { <.punct:sym«<»> <h-char-sequence> <.punct:sym«>»> } | |
token header-name:sym<quote> { <.punct:sym<">> <q-char-sequence> <.punct:sym<">> } | |
proto token h-char-sequence {*} | |
token h-char { <-[\n\>]> } | |
proto token q-char-sequence {*} | |
token q-char { <-[\n\"]> } | |
token pp-number { | |
<.pp-number-first> | |
<.pp-number-rest>* | |
} | |
proto token pp-number-first {*} | |
token pp-number-first:sym<9> { <digit> } | |
token pp-number-first:sym<.9> { '.' <digit> } | |
proto token pp-number-rest {*} | |
token pp-number-rest:sym<9> { <digit> } | |
token pp-number-rest:sym<A> { <ident-first> } | |
token pp-number-rest:sym<E> { <[eE]> <sign> } | |
token pp-number-rest:sym<P> { <[pP]> <sign> } | |
token pp-number-rest:sym<,> { '.' } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use C::StdC89Lexer; | |
grammar C::StdC89Parser is C::StdC89Lexer; | |
#rule TOP { ^ <punct:sym<[>>'a' <punct:sym<]>> $ } | |
#rule TOP { ^ 'f' <punct:sym<pp(>> 'x' <punct:sym<)>> $ } | |
rule TOP { ^ <expression> $ } | |
# SS 6.5.1 | |
proto rule primary-expression {*} | |
rule primary-expression:sym<identifier> { <ident> } | |
rule primary-expression:sym<constant> { <constant> } | |
rule primary-expression:sym<string-literal> { <string-literal> } | |
rule primary-expression:sym<expression> { | |
<.punct:sym<(>> <expression> <.punct:sym<)>> | |
} | |
rule primary-expression:sym<generic-selection> { <generic-selection> } # C11 | |
rule generic-selection { | |
<keyword:sym<_Generic>> | |
<.punct:sym<(>> | |
(<assignment-expression> ',' <generic-assoc-list>) | |
<.punct:sym<)>> | |
} | |
rule generic-assoc-list { | |
<generic-association> (',' <generic-association>)* | |
} | |
proto rule generic-association {*} | |
rule generic-association:sym<typename> { | |
<type-name> <.punct:sym<:>> <assignment-expression> | |
} | |
rule generic-association:sym<default> { | |
<keyword:sym<default>> <.punct:sym<:>> <assignment-expression> | |
} | |
rule postfix-expression { | |
<postfix-expression-first> | |
<postfix-expression-rest>* | |
} | |
proto rule postfix-expression-first {*} | |
rule postfix-expression-first:sym<primary> { <primary-expression> } | |
rule postfix-expression-first:sym<initializer> { | |
<.punct:sym<(>> <type-name> <.punct:sym<)>> | |
<.punct:sym<{>> (<initializer-list> ','?) <.punct:sym<}>> | |
} | |
proto rule postfix-expression-rest {*} | |
rule postfix-expression-rest:sym<[ ]> { | |
# <.punct:sym<[>> ~ <.punct:sym<]>> <expression> | |
<.punct:sym<[>> <expression> <.punct:sym<]>> | |
} | |
rule postfix-expression-rest:sym<( )> { | |
# <.punct:sym<(>> ~ <.punct:sym<)>> <argument-expression-list>? | |
<.punct:sym<(>> <argument-expression-list>? <.punct:sym<)>> | |
} | |
rule postfix-expression-rest:sym<.> { <sym> <ident> } | |
rule postfix-expression-rest:sym«->» { <sym> <ident> } | |
rule postfix-expression-rest:sym<++> { <sym> } | |
rule postfix-expression-rest:sym<--> { <sym> } | |
rule argument-expression-list { <assignment-expression> (',' <assignment-expression>)* } | |
proto rule unary-expression {*} | |
rule unary-expression:sym<postfix> { <postfix-expression> } | |
rule unary-expression:sym<++> { <sym> <unary-expression> } | |
rule unary-expression:sym<--> { <sym> <unary-expression> } | |
rule unary-expression:sym<unary-cast> { <unary-operator> <cast-expression> } | |
rule unary-expression:sym<size-of-expr> { <keyword:sym<sizeof>> <unary-expression> } | |
rule unary-expression:sym<size-of-type> { <keyword:sym<sizeof>> <cast-operator> } | |
rule unary-expression:sym<align-of-type> { <keyword:sym<_Alignof>> <cast-operator> } | |
proto rule unary-operator {*} | |
rule unary-operator:sym<&> { <.punct:sym<&>> } | |
rule unary-operator:sym<*> { <.punct:sym<*>> } | |
rule unary-operator:sym<+> { <.punct:sym<+>> } | |
rule unary-operator:sym<-> { <.punct:sym<->> } | |
rule unary-operator:sym<~> { <.punct:sym<~>> } | |
rule unary-operator:sym<!> { <.punct:sym<!>> } | |
rule cast-expression { <cast-operator>* <unary-expression> } | |
rule cast-operator { <.punct:sym<(>> <type-name> <.punct:sym<)>> } | |
#rule cast-operator { <.punct:sym<(>> ~ <.punct:sym<)>> <type-name> } | |
rule multiplicative-expression { | |
<cast-expression> (<multiplicative-operator> <cast-expression>)* | |
} | |
proto rule multiplicative-operator {*} | |
rule multiplicative-operator:sym<*> { <.punct:sym<*>> } | |
rule multiplicative-operator:sym</> { <.punct:sym</>> } | |
rule multiplicative-operator:sym<%> { <.punct:sym<%>> } | |
rule additive-expression { | |
<multiplicative-expression> (<additive-operator> <multiplicative-expression>)* | |
} | |
proto rule additive-operator {*} | |
rule additive-operator:sym<+> { <.punct:sym<+>> } | |
rule additive-operator:sym<-> { <.punct:sym<->> } | |
rule shift-expression { | |
<additive-expression> (<shift-operator> <additive-expression>)* | |
} | |
proto rule shift-operator {*} | |
rule shift-operator:sym«<<» { <.punct:sym«<<»> } | |
rule shift-operator:sym«>>» { <.punct:sym«>>»> } | |
rule relational-expression { | |
<shift-expression> (<relational-operator> <shift-expression>)* | |
} | |
proto rule relational-operator {*} | |
rule relational-operator:sym«<» { <.punct:sym«<»> } | |
rule relational-operator:sym«>» { <.punct:sym«>»> } | |
rule relational-operator:sym«<=» { <.punct:sym«<=»> } | |
rule relational-operator:sym«>=» { <.punct:sym«>=»> } | |
rule equality-expression { | |
<relational-expression> (<equality-operator> <relational-expression>)* | |
} | |
proto rule equality-operator {*} | |
rule equality-operator:sym<==> { <.punct:sym<==>> } | |
rule equality-operator:sym<!=> { <.punct:sym<!=>> } | |
rule and-expression { | |
<equality-expression> (<and-operator> <equality-expression>)* | |
} | |
proto rule and-operator {*} | |
rule and-operator:sym<&> { <.punct:sym<&>> } | |
rule exclusive-or-expression { | |
<and-expression> (<exclusive-or-operator> <and-expression>)* | |
} | |
proto rule exclusive-or-operator {*} | |
rule exclusive-or-operator:sym<^> { <.punct:sym<^>> } | |
rule inclusive-or-expression { | |
<exclusive-or-expression> (<inclusive-or-operator> <exclusive-or-expression>)* | |
} | |
proto rule inclusive-or-operator {*} | |
rule inclusive-or-operator:sym<|> { <.punct:sym<|>> } | |
rule logical-and-expression { | |
<inclusive-or-expression> (<logical-and-operator> <inclusive-or-expression>)* | |
} | |
proto rule logical-and-operator {*} | |
rule logical-and-operator:sym<&&> { <.punct:sym<&&>> } | |
rule logical-or-expression { | |
<logical-and-expression> (<logical-or-operator> <logical-and-expression>)* | |
} | |
proto rule logical-or-operator {*} | |
rule logical-or-operator:sym<||> { <.punct:sym<||>> } | |
rule conditional-expression { | |
<logical-or-expression> (<.punct:sym<?>> <expression> <.punct:sym<:>> <conditional-expression>)? | |
} | |
rule assignment-expression { | |
(<unary-expression> <assignment-operator>)* <conditional-expression> | |
} | |
proto rule assignment-operator {*} | |
rule assignment-operator:sym<=> { <.punct:sym<=>> } | |
rule assignment-operator:sym<*=> { <.punct:sym<*=>> } | |
rule assignment-operator:sym</=> { <.punct:sym</=>> } | |
rule assignment-operator:sym<%=> { <.punct:sym<%=>> } | |
rule assignment-operator:sym<+=> { <.punct:sym<+=>> } | |
rule assignment-operator:sym<-=> { <.punct:sym<-=>> } | |
rule assignment-operator:sym«<<=» { <.punct:sym«<<=»> } | |
rule assignment-operator:sym«>>=» { <.punct:sym«>>=»> } | |
rule assignment-operator:sym<&=> { <.punct:sym<&=>> } | |
rule assignment-operator:sym<^=> { <.punct:sym<^=>> } | |
rule assignment-operator:sym<|=> { <.punct:sym<|=>> } | |
rule expression { | |
<assignment-expression> (',' <assignment-expression>)* | |
} | |
rule constant-expression { <conditional-expression> } | |
proto rule declaration {*} | |
rule declaration:sym<declaration> { | |
<declaration-specifier>+ <init-declarator-list>? <.punct:sym<;>> | |
} | |
rule declaration:sym<static_assert> { | |
<static_assert-declaration> | |
} | |
proto rule declaration-specifier {*} | |
rule declaration-specifier:sym<storage-class> { <storage-class-specifier> } | |
rule declaration-specifier:sym<type-specifier> { <type-specifier> } | |
rule declaration-specifier:sym<type-qualifier> { <type-qualifier> } | |
rule declaration-specifier:sym<function> { <function-specifier> } | |
rule declaration-specifier:sym<alignment> { <alignment-specifier> } | |
rule init-declarator-list { <init-declarator> (',' <init-declarator>)* } | |
proto rule init-declarator { <declarator> ('=' <initializer>)? } | |
proto rule storage-class-specifier {*} | |
rule storage-class-specifier:sym<typedef> { <.keyword:sym<typedef>> } | |
rule storage-class-specifier:sym<extern> { <.keyword:sym<extern>> } | |
rule storage-class-specifier:sym<static> { <.keyword:sym<static>> } | |
rule storage-class-specifier:sym<_Thread_local> { <.keyword:sym<_Thread_local>> } | |
rule storage-class-specifier:sym<auto> { <.keyword:sym<auto>> } | |
rule storage-class-specifier:sym<register> { <.keyword:sym<register>> } | |
proto rule type-specifier {*} | |
rule type-specifier:sym<void> { <.keyword:sym<void>> } | |
rule type-specifier:sym<char> { <.keyword:sym<char>> } | |
rule type-specifier:sym<short> { <.keyword:sym<short>> } | |
rule type-specifier:sym<int> { <.keyword:sym<int>> } | |
rule type-specifier:sym<long> { <.keyword:sym<long>> } | |
rule type-specifier:sym<float> { <.keyword:sym<float>> } | |
rule type-specifier:sym<double> { <.keyword:sym<double>> } | |
rule type-specifier:sym<signed> { <.keyword:sym<signed>> } | |
rule type-specifier:sym<unsigned> { <.keyword:sym<unsigned>> } | |
rule type-specifier:sym<_Bool> { <.keyword:sym<_Bool>> } | |
rule type-specifier:sym<_Complex> { <.keyword:sym<_Complex>> } | |
rule type-specifier:sym<atomic-type> { <atomic-type-specifier> } | |
rule type-specifier:sym<struct-or-union> { <struct-or-union-specifier> } | |
rule type-specifier:sym<enum-specifier> { <enum-specifier> } | |
rule type-specifier:sym<typedef-name> { <typedef-name> } | |
proto rule struct-or-union-specifier {*} | |
rule struct-or-union-specifier:sym<spec> { | |
<struct-or-union> <ident> | |
} | |
rule struct-or-union-specifier:sym<decl> { | |
<struct-or-union> <ident>? | |
# <.punct:sym<{>> ~ <.punct:sym<}>> <struct-declaration-list> | |
<.punct:sym<{>> <struct-declaration-list> <.punct:sym<}>> | |
} | |
proto rule struct-or-union {*} | |
rule struct-or-union:sym<struct> { <.keyword:sym<struct>> } | |
rule struct-or-union:sym<union> { <.keyword:sym<union>> } | |
rule struct-declaration-list { <struct-declaration>* } | |
proto rule struct-declaration {*} | |
rule struct-declaration:sym<struct> { | |
<specifier-qualifier-list> <struct-declarator-list>? <.punct:sym<;>> | |
} | |
rule struct-declaration:sym<static_assert> { | |
<static_assert-declaration> | |
} | |
rule specifier-qualifier-list { <specifier-qualifier>+ } | |
proto rule specifier-qualifier {*} | |
rule specifier-qualifier:sym<type-specifier> { <type-specifier> } | |
rule specifier-qualifier:sym<type-qualifier> { <type-qualifier> } | |
rule struct-declarator-list { <struct-declarator> (',' <struct-declarator>)* } | |
proto rule struct-declarator {*} | |
rule struct-declarator:sym<declarator> { <declarator> } | |
rule struct-declarator:sym<bit-declarator> { <declarator>? <.punct:sym<:>> <constant-expression> } | |
proto rule enum-specifier {*} | |
rule enum-specifier:sym<decl> { | |
<.keyword:sym<enum>> <ident>? | |
<.punct:sym<{>> (<enumerator-list> ','?) <.punct:sym<}>> | |
# <.punct:sym<{>> ~ <.punct:sym<}>> (<enumerator-list> ','?) | |
} | |
rule enum-specifier:sym<spec> { | |
<.keyword:sym<enum>> <ident> | |
} | |
rule enumerator-list { <enumerator> (',' <enumerator>)* } | |
rule enumerator { | |
<enumeration-constant> (<.punct:sym<=>> <constant-expression>)? | |
} | |
proto rule atomic-type-specifier {*} # C11 | |
rule atomic-type-specifier:sym<atomic> { | |
<.keyword:sym<_Atomic>> | |
<.punct:sym<(>> <type-name> <.punct:sym<)>> | |
# <.punct:sym<(>> ~ <.punct:sym<)>> <type-name> | |
} | |
proto rule type-qualifier {*} | |
rule type-qualifier:sym<const> { <.keyword:sym<const>> } | |
rule type-qualifier:sym<restrict> { <.keyword:sym<restrict>> } | |
rule type-qualifier:sym<volatile> { <.keyword:sym<volatile>> } | |
rule type-qualifier:sym<_Atomic> { <.keyword:sym<_Atomic>> } | |
proto rule function-specifier {*} | |
rule function-specifier:sym<inline> { <.keyword:sym<inline>> } | |
rule function-specifier:sym<_Noreturn> { <.keyword:sym<_Noreturn>> } | |
proto rule alignment-specifier {*} | |
rule alignment-specifier:sym<type-name> { | |
<.keyword:sym<_Alignas>> | |
<.punct:sym<(>> <type-name> <.punct:sym<)>> | |
# <.punct:sym<(>> ~ <.punct:sym<)>> <type-name> | |
} | |
rule alignment-specifier:sym<constant> { | |
<.keyword:sym<_Alignas>> | |
<.punct:sym<(>> <constant-expression> <.punct:sym<)>> | |
# <.punct:sym<(>> ~ <.punct:sym<)>> <constant-expression> | |
} | |
proto rule declarator {*} | |
rule declarator:sym<direct> { | |
<pointer>* <direct-declarator> | |
} | |
rule direct-declarator { | |
<direct-declarator-first> <direct-declarator-rest>* | |
} | |
proto rule direct-declarator-first {*} | |
rule direct-declarator-first:sym<identifier> { <ident> } | |
rule direct-declarator-first:sym<declarator> { | |
<.punct:sym<(>> <declarator> <.punct:sym<)>> | |
# <.punct:sym<(>> ~ <.punct:sym<)>> <declarator> | |
} | |
proto rule direct-declarator-rest {*} | |
rule direct-declarator-rest:sym<assignment-expression> { | |
# <.punct:sym<[>> ~ <.punct:sym<]>> | |
<.punct:sym<[>> | |
(<type-qualifier-list>? | |
<assignment-expression>?) | |
<.punct:sym<]>> | |
} | |
rule direct-declarator-rest:sym<p-static-type-qualifier> { | |
# <.punct:sym<[>> ~ <.punct:sym<]>> | |
<.punct:sym<[>> | |
(<.keyword:sym<static>> | |
<type-qualifier-list>? | |
<assignment-expression>) | |
<.punct:sym<]>> | |
} | |
rule direct-declarator-rest:sym<p-type-qualifier-static> { | |
# <.punct:sym<[>> ~ <.punct:sym<]>> | |
<.punct:sym<[>> | |
(<type-qualifier-list> | |
<.keyword:sym<static>> | |
<assignment-expression>) | |
<.punct:sym<]>> | |
} | |
rule direct-declarator-rest:sym<b-type-qualifier-list> { | |
# <.punct:sym<[>> ~ <.punct:sym<]>> (<type-qualifier-list>? '*') | |
<.punct:sym<[>> (<type-qualifier-list>? '*') <.punct:sym<]>> | |
} | |
rule direct-declarator-rest:sym<p-parameter-type-list> { | |
# <.punct:sym<(>> ~ <.punct:sym<)>> <parameter-type-list> | |
<.punct:sym<(>> <parameter-type-list> <.punct:sym<)>> | |
} | |
rule direct-declarator-rest:sym<p-identifier-list> { | |
# <.punct:sym<(>> ~ <.punct:sym<)>> <identifier-list>? | |
<.punct:sym<(>> <identifier-list>? <.punct:sym<)>> | |
} | |
proto rule pointer {*} | |
rule pointer:sym<pointer> { <.punct:sym<*>> <type-qualifier-list>? } | |
rule type-qualifier-list { <type-qualifier>+ } | |
proto rule parameter-type-list {*} | |
rule parameter-type-list:sym<end> { <parameter-list> } | |
rule parameter-type-list:sym<...> { <parameter-list> ',' <.punct:sym<...>> } | |
rule parameter-list { | |
<parameter-declaration> (',' <parameter-declaration>)* | |
} | |
proto rule parameter-declaration {*} | |
rule parameter-declaration:sym<declarator> { <declaration-specifiers> <declarator> } | |
rule parameter-declaration:sym<abstract> { <declaration-specifiers> <abstract-declarator>? } | |
rule identifier-list { <ident> (',' <ident>)* } | |
# SS 6.7.7 | |
rule type-name { <specifier-qualifier-list> <abstract-declarator>? } | |
proto rule abstract-declarator {*} | |
rule abstract-declarator:sym<pointer> { <pointer> } | |
rule abstract-declarator:sym<direct-abstract> { | |
<pointer>? <direct-abstract-declarator> | |
} | |
proto rule direct-abstract-declarator { | |
<direct-abstract-declarator-first>? | |
<direct-abstract-declarator-rest>* | |
} | |
proto rule direct-abstract-declarator-first {*} | |
rule direct-abstract-declarator-first:sym<abstract> { | |
# <.punct:sym<(>> ~ <.punct:sym<)>> <abstract-declarator> | |
<.punct:sym<(>> <abstract-declarator> <.punct:sym<)>> | |
} | |
proto rule direct-abstract-declarator-rest {*} | |
rule direct-abstract-declarator-rest:sym<b-type-qualifier> { | |
# <.punct:sym<[>> ~ <.punct:sym<]>> | |
<.punct:sym<[>> | |
(<type-qualifier-list>? | |
<assignment-expression>?) | |
<.punct:sym<]>> | |
} | |
rule direct-abstract-declarator-rest:sym<b-static-type-qualifier> { | |
# <.punct:sym<[>> ~ <.punct:sym<]>> | |
<.punct:sym<[>> | |
(<.keyword:sym<static>> | |
<type-qualifier-list>? | |
<assignment-expression>) | |
<.punct:sym<]>> | |
} | |
rule direct-abstract-declarator-rest:sym<b-type-qualifier-static> { | |
# <.punct:sym<[>> ~ <.punct:sym<]>> | |
<.punct:sym<[>> | |
(<type-qualifier-list> | |
<.keyword:sym<static>> | |
<assignment-expression>) | |
<.punct:sym<]>> | |
} | |
rule direct-abstract-declarator-rest:sym<b-*> { | |
# <.punct:sym<[>> ~ <.punct:sym<]>> <.punct:sym<*>> | |
<.punct:sym<[>> <.punct:sym<*>> <.punct:sym<]>> | |
} | |
rule direct-abstract-declarator-rest:sym<p-parameter-type-list> { | |
# <.punct:sym<(>> ~ <.punct:sym<)>> <parameter-type-list>? | |
<.punct:sym<(>> <parameter-type-list>? <.punct:sym<)>> | |
} | |
# SS 6.7.8 | |
rule typedef-name { <ident> } | |
proto rule initializer {*} | |
rule initializer:sym<assignment> { <assignment-expression> } | |
rule initializer:sym<initializer-list> { | |
# <.punct:sym<{>> ~ <.punct:sym<}>> (<initializer-list> ','?) | |
<.punct:sym<{>> (<initializer-list> ','?) <.punct:sym<}>> | |
} | |
rule initializer-list { | |
<designation-initializer> (',' <designation-initializer>)* | |
} | |
rule designation-initializer { | |
<designation>? <initializer> | |
} | |
rule designation { <designator-list> <.punct:sym<=>> } | |
rule designator-list { <designator>+ } | |
proto rule designator {*} | |
rule designator:sym<.> { <.punct:sym<.>> <ident> } | |
rule designator:sym<[ ]> { | |
# <.punct:sym<[>> ~ <.punct:sym<]>> <constant-expression> | |
<.punct:sym<[>> <constant-expression> <.punct:sym<]>> | |
} | |
rule static_assert-declaration { # C11 | |
<.keyword:sym<_Static_assert>> | |
# <.punct:sym<(>> ~ <.punct:sym<)>> | |
<.punct:sym<(>> | |
(<constant-expression> | |
',' | |
<string-literal>) | |
<.punct:sym<)>> | |
<.punct:sym<;>> | |
} | |
proto rule statement {*} | |
rule statement:sym<labeled> { <labeled-statement> } | |
rule statement:sym<compound> { <compound-statement> } | |
rule statement:sym<expression> { <expression-statement> } | |
rule statement:sym<selection> { <selection-statement> } | |
rule statement:sym<iteration> { <iteration-statement> } | |
rule statement:sym<jump> { <jump-statement> } | |
proto rule labeled-statement {*} | |
rule labeled-statement:sym<identifier> { <ident> <.punct:sym<:>> <statement> } | |
rule labeled-statement:sym<case> { <.keyword:sym<case>> <constant-expression> <.punct:sym<:>> <statement> } | |
rule labeled-statement:sym<default> { <.keyword:sym<default>> <.punct:sym<:>> <statement> } | |
rule compound-statement { | |
# <.punct:sym<{>> ~ <.punct:sym<}>> <block-item-list>? | |
<.punct:sym<{>> <block-item-list>? <.punct:sym<}>> | |
} | |
proto rule block-item-list { <block-item>+ } | |
proto rule block-item {*} | |
rule block-item:sym<declaration> { <declaration> } | |
rule block-item:sym<statement> { <statement> } | |
rule expression-statement { <expression>? <.punct:sym<;>> } | |
proto rule selection-statement {*} | |
rule selection-statement:sym<if> { | |
<.keyword:sym<if>> | |
# <.punct:sym<(>> ~ <.punct:sym<)>> | |
<.punct:sym<(>> | |
<expression> | |
<.punct:sym<)>> | |
<then_statement=statement> | |
(<.keyword:sym<else>> <else_statement=statement>)? | |
} | |
rule selection-statement:sym<switch> { | |
<.keyword:sym<switch>> | |
# <.punct:sym<(>> ~ <.punct:sym<)>> | |
<.punct:sym<(>> | |
<expression> | |
<.punct:sym<)>> | |
<statement> | |
} | |
proto rule iteration-statement {*} | |
rule iteration-statement:sym<while> { | |
<.keyword:sym<while>> | |
# <.punct:sym<(>> ~ <.punct:sym<)>> | |
<.punct:sym<(>> | |
<expression> | |
<.punct:sym<)>> | |
<statement> | |
} | |
rule iteration-statement:sym<do_while> { | |
<.keyword:sym<do>> | |
<statement> | |
<.keyword:sym<while>> | |
# <.punct:sym<(>> ~ <.punct:sym<)>> | |
<.punct:sym<(>> | |
<expression> | |
<.punct:sym<)>> | |
<.punct:sym<;>> | |
} | |
rule iteration-statement:sym<for> { | |
<.keyword:sym<for>> | |
# <.punct:sym<(>> ~ <.punct:sym<)>> | |
<.punct:sym<(>> | |
(<expression>? <.punct:sym<;>> | |
<expression>? <.punct:sym<;>> | |
<expression>?) | |
<.punct:sym<)>> | |
<statement> | |
} | |
rule iteration-statement:sym<for_decl> { | |
<.keyword:sym<for>> | |
# <.punct:sym<(>> ~ <.punct:sym<)>> | |
<.punct:sym<(>> | |
(<declaration> | |
<expression>? <.punct:sym<;>> | |
<expression>?) | |
<.punct:sym<)>> | |
<statement> | |
} | |
proto rule jump-statement {*} | |
rule jump-statement:sym<goto> { | |
<.keyword:sym<goto>> <ident> <.punct:sym<;>> | |
} | |
rule jump-statement:sym<continue> { | |
<.keyword:sym<continue>> <.punct:sym<;>> | |
} | |
rule jump-statement:sym<break> { | |
<.keyword:sym<break>> <.punct:sym<;>> | |
} | |
rule jump-statement:sym<return> { | |
<.keyword:sym<return>> <expression>? <.punct:sym<;>> | |
} | |
# SS 6.9 | |
rule translation-unit { | |
<external-declaration>+ | |
} | |
proto rule external-declaration {*} | |
rule external-declaration:sym<function-definition> { <function-definition> } | |
rule external-declaration:sym<declaration> { <declaration> } | |
rule function-definition { | |
<declaration-specifiers> <declarator> | |
<declaration-list>? <compound-statement> | |
} | |
rule declaration-list { <declaration>+ } | |
# SS 6.10 nonstandard extensions | |
rule preprocessing-file { <group(text-line)>? } | |
rule group($text) { <group-part($text)>+ } | |
proto rule group-part($text) {*} | |
rule group-part:sym<if-section> { <if-section> } | |
rule group-part:sym<control-line> { <control-line> } | |
rule group-part:sym<text-line> { <text-line> } | |
rule group-part:sym<non-directive> { <.punct:sym<#>> <non-directive> } | |
proto rule if-section($text) { | |
<if-group($text)> <elif-groups($text)>? <else-group($text)>? <endif-line($text)> | |
} | |
proto rule if-group($text) {*} | |
proto rule elif-groups($text) {*} | |
proto rule elif-group($text) {*} | |
proto rule else-group($text) {*} | |
proto rule endif-line($text) {*} | |
proto rule control-line($text) {*} | |
rule text-line { <pp-tokens>? <new-line> } | |
rule non-directive { <pp-tokens>? <new-line> } | |
proto rule replacement-list {*} | |
proto rule pp-tokens {*} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment