[net.sources] Grammar for SmallC

geof@imagen.UUCP (02/17/87)

The following is a grammar for the language accepted by
the SmallC compiler.  The names used for nonterminals in the
grammar are compatible with the names used for procedures in
the smallc compiler, so the grammer presents a useful method
of documenting the compiler.  There are also some surprises,
such as a lack of C-compatibility in the ?: operator.

The notation is somewhat informal, and close to the usual
extended BNF:
	[x] => 0 or 1 occurances of x
	[x]* => 0 or more occurances of x
	[x]+ => 1 or more occurances of x
This "looping/option" syntax is used instead of the normal
recursive BNF style where the compiler code has that form.

The grammar is divided to indicate file boundaries.  Apologies
for any mistakes.  We spent three hours deriving this, and figured
it would save others the trouble.

- Geof Cooper
  IMAGEN
--------------------------------------------------------------
# FILE MAIN.C

parse  ::= "extern" dodclsEXTERN
        |  "static" dodclsSTATIC
        |  dodclsPUBLIC
        |  "#asm" doasm
        |  "#include" doinclude
        |  "#define" dodefine
        |  "#undef" doundef
        |  newfunc

dodcls ::= char declglb
        |  int  declglb
        |  declglb

# FILE FUNCTION.C

newfunc::= symname ( symname [, symname]* )
           _newfunc statementYES
_newfunc::= [register] char/int getarg ns

getarg  ::= [*] symname [ "[]" ] [, [*] symname [ "[]" ]]*

# FILE STMT.C

statementYES ::= { compound

statementNO  ::= stst
              |  { compound

stdecl     ::= "register" doldclsDEFAULT
            |  "auto"     doldclsDEFAUTO
            |  "static"   doldclsLSTATIC
            |  doldclsAUTO

stst       ::= "if" doif
            |  "while" dowhile
            |  "switch" doswitch
            |  "do" dodo
            |  "for" dofor
            |  "return" doreturn
            |  "break" dobreak
            |  "continue" docont
            |  "case" docase
            |  "default" dodefault
            |  "#asm" doasm
            |  expression

compound   ::= [ stdecl ns ]* [ stst ns ]* }


# FILE EXPR.C

expression ::= heir1 [, heir1]*

heir1  ::= heir1a
        |  heir1a = heir1
        |  heir1a -= heir1
        |  heir1a += heir1
        |  heir1a *= heir1
        |  heir1a /= heir1
        |  heir1a %= heir1
        |  heir1a >>= heir1
        |  heir1a <<= heir1
        |  heir1a ^= heir1
        |  heir1a |= heir1

heir1a ::= heir1b
        |  heir1b [? heir1b : heir1b]+

heir1b ::= heir1c
        |  heir1c [|| heir1c]+

heir1c ::= heir2
        |  heir2 [&& heir2]+

heir2  ::= heir3
        |  heir3 ["|" heir3]+

heir3  ::= heir4
        |  heir4 [^ heir4]+

heir4  ::= heir5
        |  heir5 [& heir5]+

heir5  ::= heir6
        |  heir6 [== heir6]
        |  heir6 [!= heir6]

heir6  ::= heir7
        |  heir7 [<= heir7]+
        |  heir7 [>= heir7]+
        |  heir7 [<  heir7]+
        |  heir7 [>  heir7]+

heir7  ::= heir8
        |  heir8 [>> heir8]+
        |  heir8 [<< heir8]+

heir8  ::= heir9
        |  heir9 [+ heir9]+
        |  heir9 [- heir9]+

heir9  ::= heir10
        |  heir10 [* heir10]+
        |  heir10 [/ heir10]+
        |  heir10 [% heir10]+

heir10 ::= ++ heir10
        |  -- heir10
        |  -  heir10
        |  ~  heir10
        |  !  heir10
        |  *  heir10
        |  &  heir10
        |  heir11 ++
        |  heir11 --
        |  heir11

heir11 ::= primary
        |  primary ( expression ) 
        |  primary [ expression ]

# FILE PRIMARY.C

primary::= ( heir1 )
        |  "sizeof" ( "int" )
        |  "sizeof" ( "char" )
        |  "sizeof" ( symname )
        |  symname[GLOBAL/LOCAL]
        |  constant

constant::= number
         |  pstr
         |  qstr

number ::= [+] _number | [-] _number
_number::= 0x DIGITS | 0X DIGITS | 0 DIGITS | DIGITS

pstr   ::= ' [char]* '

qstr   ::= " [char]* "

char   ::= [^\] | \\ | \ spechar

spechar::= n | t | r | f | b | 0
-- 
{decwrl,sun,saber}!imagen!geof