Skip to main content

module lang::c90::\syntax::C

rascal-0.40.16

Usage

import lang::c90::\syntax::C;

syntax Statement

syntax Statement 
= "{" Declaration* Statement* "}"
| Identifier ":" Statement
| "case" Expression ":" Statement
| "default" ":" Statement
| ";"
| Expression ";"
| "if" "(" Expression ")" Statement
| "if" "(" Expression ")" Statement "else" Statement
| "switch" "(" Expression ")" Statement
| "while" "(" Expression ")" Statement
| "do" Statement "while" "(" Expression ")" ";"
| "for" "(" Expression? ";" Expression? ";" Expression? ")" Statement
| "goto" Identifier ";"
| "continue" ";"
| "break" ";"
| "return" ";"
| "return" Expression ";"
;

syntax Expression

syntax Expression 
= variable: Identifier
| @category="Constant" HexadecimalConstant
| @category="Constant" IntegerConstant
| @category="Constant" CharacterConstant
| @category="Constant" FloatingPointConstant
| @category="Constant" StringConstant
| Expression "[" Expression "]"
| Expression "(" {NonCommaExpression ","}* ")"
| "sizeof" "(" TypeName ")"
| bracket \bracket: "(" Expression ")"
| Expression "." Identifier
| Expression "-\>" Identifier
| Expression "++"
| Expression "--"
> [+] !<< "++" Expression
| [\-] !<< "--" Expression
| "&" Expression
| "*" Expression
| "+" Expression
| "-" Expression
| "~" Expression
| "!" Expression
| sizeOfExpression: "sizeof" Expression exp // May be ambiguous with "sizeof(TypeName)".
| "(" TypeName ")" Expression
> left ( multiplicationExpression: Expression lexp "*" Expression rexp // May be ambiguous with "TypeName *Declarator".
| Expression "/" Expression
| Expression "%" Expression
)
> left ( Expression "+" Expression
| Expression "-" Expression
)
> left ( Expression "\<\<" Expression
| Expression "\>\>" Expression
)
> left ( Expression "\<" Expression
| Expression "\>" Expression
| Expression "\<=" Expression
| Expression "\>=" Expression
)
> left ( Expression "==" Expression
| Expression "!=" Expression
)
> left Expression "&" Expression
> left Expression "^" Expression
> left Expression "|" Expression
> left Expression "&&" Expression
> left Expression "||" Expression
> right Expression "?" Expression ":" Expression
> right ( Expression "=" Expression
| Expression "*=" Expression
| Expression "/=" Expression
| Expression "%=" Expression
| Expression "+=" Expression
| Expression "-=" Expression
| Expression "\<\<=" Expression
| Expression "\>\>=" Expression
| Expression "&=" Expression
| Expression "^=" Expression
| Expression "
| =" Expression
)
> left commaExpression: Expression "," Expression
;

syntax NonCommaExpression

syntax NonCommaExpression = nonCommaExpression: Expression expr;

syntax Identifier

lexical Identifier = ([a-zA-Z_] [a-zA-Z0-9_]* !>> [a-zA-Z0-9_]) \ Keyword;

syntax AnonymousIdentifier

syntax AnonymousIdentifier = ;

syntax Keyword

keyword Keyword 
= "auto"
| "break"
| "case"
| "char"
| "const"
| "continue"
| "default"
| "do"
| "double"
| "else"
| "enum"
| "extern"
| "float"
| "for"
| "goto"
| "if"
| "int"
| "long"
| "register"
| "return"
| "short"
| "signed"
| "sizeof"
| "static"
| "struct"
| "switch"
| "typedef"
| "union"
| "unsigned"
| "void"
| "volatile"
| "while"
;

syntax Declaration

syntax Declaration 
= declarationWithInitDecls: Specifier+ specs {InitDeclarator ","}+ initDeclarators ";"
| declarationWithoutInitDecls: Specifier+ specs ";" // Avoid.
;

syntax GlobalDeclaration

syntax GlobalDeclaration 
= globalDeclarationWithInitDecls: Specifier* specs0 {InitDeclarator ","}+ initDeclarators ";"
| globalDeclarationWithoutInitDecls: Specifier+ specs1 ";" // Avoid.
;

syntax InitDeclarator

syntax InitDeclarator 
= Declarator decl
| Declarator decl "=" Initializer
;

syntax Specifier

syntax Specifier 
= storageClass: StorageClass
| typeSpecifier: TypeSpecifier
| typeQualifier: TypeQualifier
;

syntax StorageClass

syntax StorageClass 
= typeDef: "typedef"
| "extern"
| "static"
| "auto"
| "register"
;

syntax TypeSpecifier

syntax TypeSpecifier 
= identifier: Identifier
| \void: "void"
| char: "char"
| short: "short"
| \int: "int"
| long: "long"
| \float: "float"
| \double: "double"
| "signed"
| "unsigned"
| struct: "struct" Identifier
| structDecl: "struct" Identifier "{" StructDeclaration* "}"
| structAnonDecl: "struct" "{" StructDeclaration* "}"
| union: "union" Identifier
| unionDecl: "union" Identifier "{" StructDeclaration* "}"
| unionAnonDecl: "union" "{" StructDeclaration* "}"
| enum: "enum" Identifier
| enumDecl: "enum" Identifier "{" {Enumerator ","}+ "}"
| enumAnonDecl: "enum" "{" {Enumerator ","}+ "}"
;

syntax TypeQualifier

syntax TypeQualifier 
= "const"
| "volatile"
;

syntax StructDeclaration

syntax StructDeclaration 
= structDeclWithDecl: Specifier+ specs {StructDeclarator ","}+ ";" // TODO: Disallow store class specifiers.
| structDeclWithoutDecl: Specifier+ specs ";" // TODO: Disallow store class specifiers. Avoid.
;

syntax StructDeclarator

syntax StructDeclarator 
= Declarator
| Declarator? ":" Expression // Prefer the one where 'Declarator' is filled.
;

syntax Parameters

syntax Parameters 
= {Parameter ","}+ MoreParameters?
| "void"
;

syntax MoreParameters

syntax MoreParameters = "," "...";

syntax Parameter

syntax Parameter = Specifier* Declarator;

syntax PrototypeParameter

syntax PrototypeParameter = Specifier* AbstractDeclarator;

syntax PrototypeParameters

syntax PrototypeParameters 
= {PrototypeParameter ","}+ MoreParameters?
| "void"
;

syntax Initializer

syntax Initializer 
= NonCommaExpression
| "{" {Initializer ","}+ ","? "}"
;

syntax TypeName

syntax TypeName = Specifier+ AbstractDeclarator;

syntax Enumerator

syntax Enumerator 
= Identifier
| Identifier "=" NonCommaExpression
;

syntax AbstractDeclarator

syntax AbstractDeclarator 
= identifier: AnonymousIdentifier
| bracket \bracket: "(" AbstractDeclarator decl ")"
| arrayDeclarator: AbstractDeclarator decl "[" Expression? exp "]"
| functionDeclarator: AbstractDeclarator decl "(" Parameters? params ")"
> pointerDeclarator: "*" TypeQualifier* qualifiers AbstractDeclarator decl
;

syntax PrototypeDeclarator

syntax PrototypeDeclarator 
= identifier: Identifier
| bracket \bracket: "(" AbstractDeclarator abs_decl ")"
| arrayDeclarator: PrototypeDeclarator proto_decl "[" Expression? exp "]"
| functionDeclarator: PrototypeDeclarator proto_decl "(" PrototypeParameters? params ")"
> pointerDeclarator: "*" TypeQualifier* qualifiers PrototypeDeclarator decl
;

syntax Declarator

syntax Declarator 
= identifier: Identifier
| bracket \bracket: "(" Declarator decl ")"
| arrayDeclarator: Declarator decl "[" Expression? exp "]"
| functionDeclarator: Declarator decl "(" Parameters? params ")"
> pointerDeclarator: "*" TypeQualifier* qualifiers Declarator decl
;

syntax IntegerConstant

lexical IntegerConstant = [0-9]+ [uUlL]* !>> [0-9];

syntax HexadecimalConstant

lexical HexadecimalConstant = [0] [xX] [a-fA-F0-9]+ [uUlL]* !>> [a-fA-F0-9];

syntax FloatingPointConstant

lexical FloatingPointConstant 
= [0-9]+ Exponent [fFlL]?
| [0-9]* [.] [0-9]+ !>> [0-9] Exponent? [fFlL]?
| [0-9]+ [.] Exponent? [fFlL]?
;

syntax Exponent

lexical Exponent = [Ee] [+\-]? [0-9]+ !>> [0-9];

syntax CharacterConstant

lexical CharacterConstant = [L]? [\'] CharacterConstantContent+ [\'];

syntax CharacterConstantContent

lexical CharacterConstantContent 
= [\\] ![]
| ![\\\']
;

syntax StringConstant

lexical StringConstant = [L]? [\"] StringConstantContent* [\"];

syntax StringConstantContent

lexical StringConstantContent 
= [\\] ![]
| ![\\\"]
;

syntax FunctionDefinition

syntax FunctionDefinition = defaultFunctionDefinition: Specifier* specs Declarator Declaration* "{" Declaration* Statement* "}";

syntax FunctionPrototype

syntax FunctionPrototype = defaultFunctionPrototype: Specifier* specs PrototypeDeclarator decl ";";

syntax ExternalDeclaration

syntax ExternalDeclaration 
= FunctionDefinition
| FunctionPrototype
| GlobalDeclaration
;

syntax TranslationUnit

start syntax TranslationUnit = ExternalDeclaration+;

syntax Comment

lexical Comment 
= [/][*] MultiLineCommentBodyToken* [*][/]
| "//" ![\n]* [\n]
;

syntax MultiLineCommentBodyToken

lexical MultiLineCommentBodyToken 
= ![*]
| Asterisk
;

syntax Asterisk

lexical Asterisk = [*] !>> [/];

syntax LAYOUTLIST

layout LAYOUTLIST = LAYOUT* !>> [\ \t\n\r];

syntax LAYOUT

lexical LAYOUT 
= whitespace: [\ \t\n\r]
| @category="Comment" comment: Comment
;