Skip to content

Instantly share code, notes, and snippets.

@grondilu
Forked from andydude/StdC89Lexer.pm6
Last active August 29, 2015 14:08
Show Gist options
  • Save grondilu/1d6bb278dcdc8a4cbcfd to your computer and use it in GitHub Desktop.
Save grondilu/1d6bb278dcdc8a4cbcfd to your computer and use it in GitHub Desktop.
# 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<,> { '.' }
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