Package dovs.peephole; /******************************************************************* * Helpers * *******************************************************************/ Helpers latin1_input_character = [0..0xff]; ht = 0x09; lf = 0x0a; ff = 0x0c; cr = 0x0d; sp = ' '; line_terminator = lf | cr | cr lf; input_character = [latin1_input_character - [cr + lf]]; not_star = [input_character - '*'] | line_terminator; not_star_not_slash = [input_character - ['*' + '/']] | line_terminator; digit = ['0'..'9']; non_zero_digit = ['1'..'9']; decimal_numeral = '0' | non_zero_digit digit*; latin1_letter = [0x41..0x5a] | [0x61..0x7a] | [0xaa..0xaa] | [0xb5..0xb5] | [0xba..0xba] | [0xc0..0xd6] | [0xd8..0xf6] | [0xf8..0xff]; java_letter = latin1_letter | '$' | '_'; java_letter_or_digit = latin1_letter | digit | '$' | '_'; /******************************************************************* * Tokens * *******************************************************************/ Tokens // Whitespace white_space = (sp | ht | ff | line_terminator)*; traditional_comment = '/*' not_star+ '*'+ (not_star_not_slash not_star* '*'+)* '/'; documentation_comment = '/**' '*'* (not_star_not_slash not_star* '*'+)* '/'; end_of_line_comment = '//' input_character* line_terminator?; // Keywords commute = 'commute'; degree = 'degree'; formals = 'formals'; negate = 'negate'; pattern = 'pattern'; returns = 'returns'; target = 'target'; aeq = 'aeq'; ane = 'ane'; eq = 'eq'; ge = 'ge'; gt = 'gt'; le = 'le'; lt = 'lt'; ne = 'ne'; // Delimiters l_paren = '('; r_paren = ')'; colon = ':'; comma = ','; arrow = '->'; // Boolean op_complement = '!'; op_logical_and = '&&'; op_logical_or = '||'; // Comparison op_lt = '<'; op_gt = '>'; op_eq = '=='; op_lteq = '<='; op_gteq ='>='; op_neq = '!='; op_match = '~'; // Arithmetic op_plus = '+'; op_minus = '-'; op_mul = '*'; op_div = '/'; op_and = '&'; op_or = '|'; op_xor = '^'; op_mod = '%'; // Literals and identifiers integer_literal = decimal_numeral; identifier = java_letter java_letter_or_digit*; /******************************************************************* * Ignored Tokens * *******************************************************************/ Ignored Tokens white_space, traditional_comment, documentation_comment, end_of_line_comment; /******************************************************************* * Productions * *******************************************************************/ Productions goal {-> pattern_collection} = pattern_declaration* {-> New pattern_collection([pattern_declaration.pattern_decl])} ; pattern_declaration {-> pattern_decl} = pattern [name]:identifier variable colon expression arrow integer_literal instruction* {-> New pattern_decl(name, variable.var, expression.exp, integer_literal, [instruction.inst])} ; literal {-> exp} = integer_literal {-> New exp.int_const(Null, integer_literal)} | literal_not_integer {-> literal_not_integer.exp} ; literal_not_integer {-> exp} = op_minus integer_literal {-> New exp.int_const(op_minus, integer_literal)} | condition_literal {-> New exp.cond_const(condition_literal.cond)} ; condition_literal {-> cond} = eq {-> New cond.eq(eq)} | ne {-> New cond.ne(ne)} | lt {-> New cond.lt(lt)} | le {-> New cond.le(le)} | gt {-> New cond.gt(gt)} | ge {-> New cond.ge(ge)} | aeq {-> New cond.aeq(aeq)} | ane {-> New cond.ane(ane)} ; builtin_function {-> builtin} = commute {-> New builtin.commute(commute)} | degree {-> New builtin.degree(degree)} | formals {-> New builtin.formals(formals)} | negate {-> New builtin.negate(negate)} | returns {-> New builtin.returns(returns)} | target {-> New builtin.target(target)} ; primary {-> exp} = literal {-> literal.exp} | variable {-> New exp.var(variable.var)} | l_paren expression r_paren {-> expression.exp} | builtin_function primary {-> New exp.builtin(builtin_function.builtin, primary.exp)} ; primary_not_integer {-> exp} = literal_not_integer {-> literal_not_integer.exp} | variable {-> New exp.var(variable.var)} | l_paren expression r_paren {-> expression.exp} | builtin_function primary {-> New exp.builtin(builtin_function.builtin, primary.exp)} ; unary_expression {-> exp} = primary {-> primary.exp} | unary_expression_common {-> unary_expression_common.exp} ; unary_expression_not_integer {-> exp} = primary_not_integer {-> primary_not_integer.exp} | unary_expression_common {-> unary_expression_common.exp} ; unary_expression_common {-> exp} = op_minus unary_expression_not_integer {-> New exp.unop(New unop.negate(op_minus), unary_expression_not_integer.exp)} | op_complement unary_expression {-> New exp.unop(New unop.complement(op_complement), unary_expression.exp)} ; and_expression {-> exp} = unary_expression {-> unary_expression.exp} | and_expression op_and unary_expression {-> New exp.binop(and_expression.exp, New binop.and(op_and), unary_expression.exp)} ; xor_expression {-> exp} = and_expression {-> and_expression.exp} | xor_expression op_xor and_expression {-> New exp.binop(xor_expression.exp, New binop.xor(op_xor), and_expression.exp)} ; or_expression {-> exp} = xor_expression {-> xor_expression.exp} | or_expression op_or xor_expression {-> New exp.binop(or_expression.exp, New binop.or(op_or), xor_expression.exp)} ; multiplicative_expression {-> exp} = or_expression {-> or_expression.exp} | multiplicative_expression op_mul or_expression {-> New exp.binop(multiplicative_expression.exp, New binop.times(op_mul), or_expression.exp)} | multiplicative_expression op_div or_expression {-> New exp.binop(multiplicative_expression.exp, New binop.divide(op_div), or_expression.exp)} | multiplicative_expression op_mod or_expression {-> New exp.binop(multiplicative_expression.exp, New binop.modulo(op_mod), or_expression.exp)} ; additive_expression {-> exp} = multiplicative_expression {-> multiplicative_expression.exp} | additive_expression op_plus multiplicative_expression {-> New exp.binop(additive_expression.exp, New binop.plus(op_plus), multiplicative_expression.exp)} | additive_expression op_minus multiplicative_expression {-> New exp.binop(additive_expression.exp, New binop.minus(op_minus), multiplicative_expression.exp)} ; relational_expression {-> exp} = additive_expression {-> additive_expression.exp} | relational_expression op_lt additive_expression {-> New exp.binop(relational_expression.exp, New binop.lt(op_lt), additive_expression.exp)} | relational_expression op_gt additive_expression {-> New exp.binop(relational_expression.exp, New binop.gt(op_gt), additive_expression.exp)} | relational_expression op_lteq additive_expression {-> New exp.binop(relational_expression.exp, New binop.le(op_lteq), additive_expression.exp)} | relational_expression op_gteq additive_expression {-> New exp.binop(relational_expression.exp, New binop.ge(op_gteq), additive_expression.exp)} ; equality_expression {-> exp} = relational_expression {-> relational_expression.exp} | equality_expression op_eq relational_expression {-> New exp.binop(equality_expression.exp, New binop.eq(op_eq), relational_expression.exp)} | equality_expression op_neq relational_expression {-> New exp.binop(equality_expression.exp, New binop.ne(op_neq), relational_expression.exp)} ; match_expression {-> exp} = equality_expression {-> equality_expression.exp} | primary op_match instruction_pattern* {-> New exp.match(primary.exp, [instruction_pattern.inst_pat])} ; logical_and_expression {-> exp} = match_expression {-> match_expression.exp} | logical_and_expression op_logical_and match_expression {-> New exp.conjunction(logical_and_expression.exp, match_expression.exp)} ; logical_or_expression {-> exp} = logical_and_expression {-> logical_and_expression.exp} | logical_or_expression op_logical_or logical_and_expression {-> New exp.disjunction(logical_or_expression.exp, logical_and_expression.exp)} ; expression {-> exp} = logical_or_expression {-> logical_or_expression.exp} ; instruction {-> inst} = identifier {-> New inst(New opcode(identifier), [])} | identifier l_paren argument_list r_paren {-> New inst(New opcode(identifier), [argument_list.exp])} | variable colon {-> New inst(New opcode(Null), [New exp.var(variable.var)])} ; instruction_pattern {-> inst_pat} = identifier {-> New inst_pat.instruction(New opcode(identifier), [])} | identifier l_paren parameter_list r_paren {-> New inst_pat.instruction(New opcode(identifier), [parameter_list.var])} | variable colon {-> New inst_pat.label_binder(variable.var)} | op_mul {-> New inst_pat.wildcard()} ; parameter_list {-> var*} = variable {-> [variable.var]} | parameter_list comma variable {-> [parameter_list.var, variable.var]} ; argument_list {-> exp*} = expression {-> [expression.exp]} | argument_list comma expression {-> [argument_list.exp, expression.exp]} ; variable {-> var} = identifier {-> New var(identifier)} ; Abstract Syntax Tree pattern_collection = [patterns]:pattern_decl*; pattern_decl = [name]:identifier [instvar]:var [match]:exp [size]:integer_literal [replacement]:inst* ; var = identifier; opcode = identifier?; inst = opcode [args]:exp*; inst_pat = {instruction} opcode [params]:var* | {label_binder} [label]:var | {wildcard} ; exp = {var} var | {match} [left]:exp [instructions]:inst_pat* | {binop} [left]:exp binop [right]:exp | {unop} unop exp | {builtin} builtin exp | {int_const} [sign]:op_minus? integer_literal | {cond_const} cond | {conjunction} [left]:exp [right]:exp | {disjunction} [left]:exp [right]:exp ; builtin = {commute} [token]:commute | {degree} [token]:degree | {formals} [token]:formals | {negate} [token]:negate | {returns} [token]:returns | {target} [token]:target ; cond = {eq} [token]:eq | {ne} [token]:ne | {lt} [token]:lt | {le} [token]:le | {gt} [token]:gt | {ge} [token]:ge | {aeq} [token]:aeq | {ane} [token]:ane ; binop = {plus} [token]:op_plus | {minus} [token]:op_minus | {times} [token]:op_mul | {divide} [token]:op_div | {modulo} [token]:op_mod | {eq} [token]:op_eq | {ne} [token]:op_neq | {lt} [token]:op_lt | {le} [token]:op_lteq | {gt} [token]:op_gt | {ge} [token]:op_gteq | {and} [token]:op_and | {or} [token]:op_or | {xor} [token]:op_xor ; unop = {negate} [token]:op_minus | {complement} [token]:op_complement ;