| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- COMPILER C
- (* An attempt to describe a small subset of C *)
- CHARACTERS
- letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" .
- digit = "0123456789" .
- hexdigit = digit + "ABCDEFabcdef" .
- tab = CHR(9) .
- lf = CHR(10) .
- eol = CHR(13) .
- files = letter + digit + ":\." .
- chars = CHR(32) .. CHR(255) - "'" .
- strings = CHR(32) .. CHR(255) - '"'.
- macros = ANY - eol .
- COMMENTS FROM "/*" TO "*/"
- IGNORE
- tab + eol + lf
- TOKENS
- identifier = ( "_" | letter) { "_" | letter | digit } .
- number = digit { digit } [ "." { digit }] [ "U" | "u" | "L" | "l" ] .
- hexnumber = "0" ( "x" | "X" ) hexdigit { hexdigit } [ "U" | "u" | "L" | "l" ] .
- string = '"' { strings } '"' .
- char = "'" [ "\" ] chars "'" .
- library = "<" files { files } ">" .
- PRAGMAS
- PreProcessor = "#" {macros} .
- PRODUCTIONS
- C = { Definition } EOF .
- (* Variable and Type Definitions *)
- Definition = [ StorageClass ] Type { "*" } identifier
- ( FunctionDefinition | VarList ";" ) .
- StorageClass = "auto" | "extern" | "register" | "static" .
- Type = "short" [ "int" ]
- | "long" [ "int" | "float" ]
- | "unsigned" [ "char" | "int" | "long" ]
- | "char" | "int" | "float" | "double" | "void" .
- VarList = ArraySize { "," { "*" } identifier ArraySize } .
- ArraySize = { "[" [ ConstExpression ] "]" } .
- (* Function Definitions *)
- FunctionDefinition = FunctionHeader ( ";" | FunctionBody ) .
- FunctionHeader = "(" [ FormalParamList ] ")" .
- FunctionBody = CompoundStatement .
- FormalParamList = FormalParameter { "," FormalParameter } .
- FormalParameter = Type { "*" } [ identifier ] ArraySize .
- (* Statements *)
- Statement = { Label }
- ( AssignmentExpression | BreakStatement
- | CompoundStatement | ContinueStatement
- | DoStatement | ForStatement
- | IfStatement | NullStatement
- | ReturnStatement | SwitchStatement
- | WhileStatement ) .
- Label = "case" ConstExpression ":" | "default" ":" .
- (* There is no requirement that a switch statement be followed by a compound
- statement. Actually labels may be even more general *)
- AssignmentExpression = Expression ";" .
- BreakStatement = "break" ";" .
- CompoundStatement = "{" { LocalDeclaration } { Statement } "}" .
- ContinueStatement = "continue" ";" .
- DoStatement = "do" Statement "while" "(" Expression ")" ";" .
- ForStatement = "for" "(" [ Expression ] ";" [ Expression ] ";" [ Expression ] ")" Statement .
- IfStatement = "if" "(" Expression ")" Statement [ "else" Statement ] .
- NullStatement = ";" .
- ReturnStatement = "return" [ Expression ] ";" .
- (* Expression usually in parentheses *)
- SwitchStatement = "switch" "(" Expression ")" Statement .
- WhileStatement = "while" "(" Expression ")" Statement .
- (* LocalDeclarations *)
- LocalDeclaration = [ StorageClass ] Type { "*" } identifier
- ( FunctionHeader | VarList ) ";" .
- (* Expressions, based on Kernighan and Ritchie: "The C Programming Language".
- There does not seem to be a way to make this work in an LL(1) fashion,
- but this generates a "working" parser *)
- ConstExpression = Expression .
- Expression = Conditional { AssignmentOperator Expression }.
- Conditional = LogORExp .
- LogORExp = LogANDExp { "||" LogANDExp } .
- LogANDExp = InclORExp { "&&" InclORExp }.
- InclORExp = ExclORExp { "|" ExclORExp } .
- ExclORExp = ANDExp { "^" ANDExp } .
- ANDExp = EqualExp { "&" EqualExp } .
- EqualExp = RelationExp { ( "==" | "!=" ) RelationExp } .
- RelationExp = ShiftExp { ( "<" | ">" | "<=" | ">=" ) ShiftExp }.
- ShiftExp = AddExp { ( "<<" | ">>" ) AddExp } .
- AddExp = MultExp { ( "+" | "-" ) MultExp } .
- MultExp = CastExp { ( "*" | "/" | "%" ) CastExp } .
- CastExp = UnaryExp .
- (* we should really add
- | "(" identifier ")" CastExp .
- but this breaks it badly *)
- UnaryExp = PostFixExp
- | ( "++" | "--" ) UnaryExp
- | UnaryOperator CastExp .
- (* we should really add
- | "sizeof" ( UnaryExp | "(" Type ")" ) .
- but this breaks it badly *)
- PostFixExp = Primary
- { "[" Expression "]"
- | FunctionCall
- | "." identifier
- | "->" identifier
- | "++"
- | "--"
- } .
- Primary = identifier | string | char | number | "(" Expression ")" .
- FunctionCall = "(" [ ActualParameters ] ")" .
- ActualParameters = Expression { "," Expression } .
- AssignmentOperator = "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "&="
- | "^=" | "|=" | "<<=" | ">>=" .
- UnaryOperator = "+" | "-" | "*" | "!" | "&" | "~" .
- END C.
|