Syntax of the language, a slightly reduced version of C expr18 -> identifier | string | integer | float | "NULL" | "(" expression ")" expr17 -> expr18 | expr17 "(" expressionlist ")" | expr17 "[" expression "]" | expr17 ( "." | "->" ) identifier expr15 -> expr17 | ( "!" | "+" | "-" | "&" | "*" ) expr15 expr13 -> expr15 | expr13 ( "*" | "/" | "%" ) expr15 expr12 -> expr13 | expr12 ( "+" | "-" ) expr13 expr10 -> expr12 | expr10 ( "<" | ">" | "<=" | ">=" ) expr12 expr9 -> expr10 | expr9 ( "==" | "!=" ) expr10 expr5 -> expr9 | expr5 "&&" expr9 expr4 -> expr5 | expr4 "||" expr5 expr2 -> expr4 | expr4 ( "=" | "+=" | "-=" | "*=" | "/=" | "%=" ) expr2 expression -> expr2 expressionlist -> expression ( "," expression ) * returnstatement -> "return" ";" | "return" expression ";" whilestatement -> "while" expression statement ifstatement -> "if" expression statement | "if" expression statement "else" statement expressionstatement -> expression ";" block -> "{" declarationlist statementlist "}" statement -> returnstatement | whilestatement | ifstatement | expressionstatement | block statementlist -> statement * type -> simpletype | structtype simpletype -> "int" | "float" | "char" | "void" structtype -> "struct" { identifier } { "{" declarationlist "}" } declareparam -> type declareitem declareparamlist -> { declareparam ( "," declareparam ) * } declareitemfunction -> declareitemsimple | declareitemfunction "(" declareparamlist ")" { block } declareitemarray -> declareitemfunction | declareitemarray "[" { integer } "]" declareitemptr -> declareitemarray | "*" declareitemptr declareitem -> declareitemptr declareitemlist -> declareitem ( "," declareitem )* declaration -> type declareitemlist ";" declarationlist -> declaration * program -> declarationlist Introduced syntax used by the compiler for things it inserts; they never appear in real programs. C’s normal representation of types and declarations is very peculiar; things go much more smoothly if the compiler plays with the tree a bit, to improve the representation. Most of the introduced syntax is to provide a representation for the improved declarations and types; the user never sees any of this unless the compiler decides to output its syntax tree (perhaps when reporting an error). badthing -> "" a badthing appears in the tree where syntax errors were found fixedsimpletype -> "int" | "float" | "char" | "void" fixedptrtype -> "ptr" "(" fixedtype ")" fixedarraytype -> "arr" "[" { integer } "]" "(" fixedtype ")" fixedfield -> identifier ":" fixedtype ";" fixedfieldlist -> fixedfield * fixedstructtype -> "struct" { "$$"identifier } { "{" fixedfieldlist "}" } fixedparam -> identifier ":" fixedtype fixedparamlist -> fixedparam ( "," fixedparam )* fixedfunctiontype -> "fn" "(" ( "void" | fixedparamlist ) "->" fixedtype ")" fixedtype -> fixedfunctiontype | fixedarraytype | fixedptrtype | fixedstructtype | fixedsimpletype the preceeding fixed...type items are used to represent the types of all things consistently fixedstructdef -> "define" identifier "=" fixedstructtype ";" fixedfunctiondef -> "define" identifier ":" fixedfunctiontype { block } ";" fixeddeclaration -> "declare" identifier ":" fixedtype ";" the preceeding three items replace all declarations throughout a program coercion -> "coerce" "[" fixedtype "->" fixedtype "]" "(" expression ")" coercion is a new kind of expression that represents type changes