Files
lecture-compilers/stups.grammar

97 lines
4.4 KiB
Plaintext

// NTERM, TERM are reserved
// Some Grammar-Symbols have to be named this way:
// assignment, declaration (for TypeTable creation)
// IDENTIFIER, NOT, ADD, SUB (for TypeChecking)
// expr, par_expr, assignment (for TypeChecking)
// Nonterminals:
NTERM: val type
NTERM: op unary arith_op logic_op compare_op
NTERM: S class_cnt block_cnt
NTERM: statement stmt print
NTERM: declaration assignment
NTERM: par_expr expr expr_2 expr_f
NTERM: loop cond cond_else single_or_braced
// Token:
TERM: CLASS PUBLIC STATIC
TERM: STRING_TYPE INTEGER_TYPE BOOLEAN_TYPE VOID_TYPE
TERM: WHILE IF ELSE
TERM: PRINTLN
TERM: ADD MUL SUB DIV MOD
TERM: AND OR NOT
TERM: LESS LESS_EQUAL GREATER GREATER_EQUAL EQUAL NOT_EQUAL
TERM: ASSIGN
TERM: L_BRACE R_BRACE L_BRACKET R_BRACKET L_PAREN R_PAREN SEMICOLON COMMA DOT
TERM: INTEGER_LIT STRING_LIT BOOLEAN_LIT
TERM: IDENTIFIER IDENTIFIER_MAIN
// Actions: promote - Information "hochreichen": Ersetzt Node mit Child, wenn es nur ein Child gibt
// - val[promote] :: --val--INTEGER_LIT: 5 => --INTEGER_LIT: 5
// delifempty - Kann Node löschen, wenn dieser keinen Inhalt hat, normalerweise bei eps
// - block_cnt[delifempty] :: --block_cnt => --
// delchild= - Entfernt bestimmte Child-Nodes eines Parents
// - cond[delchild=IF] :: --cond--IF => --cond
// - assignment[delchild=ASSIGN] :: --assignment--ASSIGN => --assignment
// valtoval= - Verschiebt eine Child-Value in die Parent-Value und entfernt das Child
// - assignment[valtoval=IDENTIFIER] :: --assignment--IDENTIFIER: a => --assignment: a
// nametoval= - Verschiebt einen Child-Name in die Parent-Value und entfernt das Child
// - expr_2[nametoval=ADD] :: --expr_2--ADD => --expr_2: ADD
// renameto= - Führt Umbenennung eines Nodes durch
// - expr_2[renameto=expr] :: --expr_2: ADD => --expr: ADD
// General -----------------------------------------------------------------------------------------
val[promote] -> INTEGER_LIT | STRING_LIT | BOOLEAN_LIT | IDENTIFIER
type[promote] -> INTEGER_TYPE | STRING_TYPE | BOOLEAN_TYPE
// OP-List: ADD,SUB,MUL,DIV,MOD,AND,OR,NOT,LESS,LESS_EQUAL,GREATER,GREATER_EQUAL,EQUAL,NOT_EQUAL
op[promote] -> arith_op | logic_op | compare_op
unary[promote] -> ADD | SUB | NOT
arith_op[promote] -> ADD | SUB | MUL | DIV | MOD
logic_op[promote] -> AND | OR | NOT
compare_op[promote] -> LESS | LESS_EQUAL | GREATER | GREATER_EQUAL | EQUAL | NOT_EQUAL
// -------------------------------------------------------------------------------------------------
// START -> class IDENTIFIER { class_cnt }
S[renameto=CLASS delchild=CLASS,R_BRACE,L_BRACE] -> CLASS IDENTIFIER L_BRACE class_cnt R_BRACE | eps
// class_cnt -> public static void main(String[] args) { block_cnt }
// remove all the stuff that is irrelevant to this simple case
class_cnt[promote delifempty delchild=L_BRACE,R_BRACE,L_PAREN,R_PAREN,L_BRACKET,R_BRACKET,IDENTIFIER,IDENTIFIER_MAIN,STRING_TYPE,VOID_TYPE,STATIC,PUBLIC] -> PUBLIC STATIC VOID_TYPE IDENTIFIER_MAIN L_PAREN STRING_TYPE L_BRACKET R_BRACKET IDENTIFIER R_PAREN L_BRACE block_cnt R_BRACE | eps
// block_ccnt -> stuff in {} | list of statements
block_cnt[promote delifempty] -> statement block_cnt | L_BRACE block_cnt R_BRACE | eps
// statement -> stuff ending with ; | loop | condition
statement[promote delchild=SEMICOLON] -> stmt SEMICOLON | loop | cond
stmt[promote] -> print | declaration | assignment
print[nametoval=PRINTLN] -> PRINTLN par_expr
// declaration -> type IDENTIFIER = expr;
declaration[nametoval=INTEGER_TYPE,BOOLEAN_TYPE,STRING_TYPE] -> type assignment
assignment[delchild=ASSIGN valtoval=IDENTIFIER] -> IDENTIFIER ASSIGN expr
// par_expr -> ( expr )
// dont [promote] par_expr to make parenthesis-precedence easier
par_expr[delchild=L_PAREN,R_PAREN] -> L_PAREN expr R_PAREN
// expr -> expression that returns something | literal
expr[promote nametoval=ADD,SUB,MUL,DIV,MOD,AND,OR,NOT,LESS,LESS_EQUAL,GREATER,GREATER_EQUAL,EQUAL,NOT_EQUAL] -> expr_f expr_2
expr_2[promote delifempty renameto=expr] -> op expr_f expr_2 | eps
expr_f[promote renameto=expr] -> unary expr_f | par_expr | val
// Control-Flow
// Don't [delifempty] single_or_braced to make it easier to get the expression
loop[delchild=WHILE] -> WHILE par_expr single_or_braced
cond[delchild=IF] -> IF par_expr single_or_braced cond_else
cond_else[delifempty delchild=ELSE] -> ELSE single_or_braced | eps
single_or_braced[promote delchild=L_BRACE,R_BRACE] -> L_BRACE block_cnt R_BRACE | stmt SEMICOLON