Appendix A - A Grammar for Kenya
The grammar for Kenya for use with SableCC looks like:
Package minijava;
Helpers
letter = ['A'..'Z'] | ['a'..'z'];
digit = ['0'..'9'];
cr = 13;
lf = 10;
point = '.';
not_cr_lf = [[32..127] - [cr + lf]];
space = ' ';
Tokens
boolean = 'boolean';
char = 'char';
int = 'int';
real = 'real';
string = 'string';
void = 'void';
klass = 'class';
const = 'const';
print = 'print';
println = 'println';
if = 'if';
else = 'else';
while = 'while';
return = 'return';
switch = 'switch';
case = 'case';
break = 'break';
default = 'default';
for = 'for';
to = 'to';
step = 'step';
decreasing = 'decreasing';
call = 'call';
true = 'true';
false = 'false';
and = 'and';
or = 'or';
xor = 'xor';
not = 'not';
readint = 'readInt()';
readreal = 'readReal()';
readstring = 'readString()';
identifier = letter (letter | digit)*;
stringliteral = '"' [not_cr_lf - '"']* '"';
l_parenthese = '(';
r_parenthese = ')';
l_brace = '{';
r_brace = '}';
l_bracket = '[';
r_bracket = ']';
semicolon = ';';
colon = ':';
comma = ',';
dot = point;
plus = '+';
minus = '-';
times = '*';
divide = '/';
power = '^';
mod = '%';
less = '<';
lessequal = '<=';
greater = '>';
greaterequal = '>=';
equal = '==';
notequal = '!=';
assign = '=';
intnumber = digit+ ;
fpnumber = digit+ point digit+;
new_line = cr | lf | cr lf;
blank = space*;
comment = '//' (letter | digit | space )* ( cr | lf | cr lf );
Ignored Tokens
blank , new_line , comment;
Productions
statements =
{list} statement statements |
{empty} ;
statement =
{dec} declaration |
{functioncall} function_application semicolon |
{assignment} field_access assign expression semicolon |
{if} if l_parenthese bool_expression r_parenthese [block1]:block else? [block2]:block? |
{while} while l_parenthese bool_expression r_parenthese block |
{return} return expression? semicolon |
{switch} switch l_parenthese expression r_parenthese switch_block |
{for} for decreasing? name assign [exp1]:expression to [exp2]:expression step? [exp3]:expression? block |
{break} break semicolon |
{print_str} print expression semicolon |
{println_str} println expression semicolon;
block = l_brace statements r_brace;
function_application = call name l_parenthese actual_param_list r_parenthese;
actual_param_list = {list} actual_param_list comma expression |
{exp} expression |
{empty};
switch_block = l_brace possible_case* r_brace;
possible_case = switch_label block;
switch_label =
{case} case expression colon |
{default} default colon;
declaration =
{class_dec} klass identifier l_brace declaration* r_brace |
{func_dec} type identifier l_parenthese formal_param_list? r_parenthese block |
{const_dec} const type identifier initialiser? semicolon |
{var_dec} type type_param? identifier array_access* initialiser? semicolon;
formal_param_list = type_name comma_type_name*;
type_name = type identifier;
comma_type_name = comma type_name;
initialiser = assign expression;
booleanliteral =
{true} true |
{false} false;
/********************
Types
********************/
type =
{basic_type}
basic_type |
{reference_type}
reference_type;
basic_type =
{char}
char |
{int}
int |
{real}
real |
{string}
string |
{boolean}
boolean |
{void}
void;
reference_type =
{class_type}
class_type;
/********************
Variable Declarations
********************/
type_param = less type_param_list greater;
type_param_list = type comma_type*;
comma_type = comma type;
/********************
Expressions
********************/
expression =
{boolexp} bool_expression;
math_expression =
{term} term |
{plus} math_expression plus term |
{minus} math_expression minus term ;
term =
{factor} factor |
{mult} term times factor |
{div} term divide factor |
{mod} term mod factor |
{power} term power factor;
factor =
{function} function_application |
{number} number |
{stringliteral} stringliteral |
{readint} readint |
{readreal} readreal |
{readstring} readstring |
{fieldaccess} field_access |
{expression} l_parenthese bool_expression r_parenthese;
number = {i} intnumber |
{f} fpnumber;
bool_expression =
{term} bool_term |
{mathexp} math_expression |
{or} bool_expression or bool_term;
bool_term =
{factor} bool_factor |
{and} bool_term and bool_factor;
bool_factor =
{literal} booleanliteral |
{compare} [lhs]:math_expression comp_operator [rhs]:math_expression |
{negate} not l_parenthese bool_expression r_parenthese;
/********************
Names
********************/
field_access =
{array} name array_access+ |
{scalar} name;
name =
{simple_name}
simple_name |
{qualified_name}
qualified_name;
simple_name =
identifier;
qualified_name =
field_access dot identifier;
array_access = l_bracket math_expression r_bracket;