1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
grammar Expr; options { backtrack=true; } @header { import java.util.HashMap; import java.lang.reflect.Method; } @members { /** Map variable name to Integer object holding value */ HashMap memory = new HashMap(); class PublicFunctions { public Integer square(Integer x) { return x*x; } public Integer addfive(Integer x) { return x+5; } public Integer add(Integer...arguments) { Integer sum = new Integer(0); for (Integer x : arguments) { sum+= x; } return sum; } } public Integer dispatchMethod(Method m, Object obj, ArrayList<Integer> args) throws Exception { Object result; Class[] params = m.getParameterTypes(); if (params.length > 0 && params[params.length-1].isArray()) { // function expects last argument to be an array. Object[] arguments = new Object[params.length]; int i=0; // could be buggy.. for (i=0; i<params.length-1; i++) { arguments[i] = args.get(i); } arguments[i] = args.subList(i, args.size()).toArray(new Integer[0]); //System.out.println("calling with array:" + arguments[i]); result = m.invoke(obj, arguments); } else { // normal function call. result = m.invoke(obj, args.toArray()); } System.out.println("method: "+m.getName() + " " + args + " -> " + (Integer)result); return (Integer)result; } public Integer dispatchFnToObject(Object obj, String fn, ArrayList<Integer> args) { for (Method m : obj.getClass().getDeclaredMethods()) { if ( m.getName().compareTo(fn) == 0 ) { try { Integer result = dispatchMethod(m, obj, args); if (result!=null) { return result; } } catch (Exception e) { System.err.println("Error when calling " + m.getName() + "\nError: " + e); // just continue... } } else { //System.out.println("got method: " + m.toString()); } } System.err.println("Could not find method " + fn + ". returning null."); return null; } public int dispatchFn(String fn, ArrayList<Integer> args) { return this.dispatchFnToObject( new PublicFunctions(), fn, args).intValue(); } } prog: stat+ ; stat: expr NEWLINE {System.out.println($expr.value);} | ID '=' expr NEWLINE {memory.put($ID.text, new Integer($expr.value));} | NEWLINE ; funcall returns [int value] @init { ArrayList<Integer> args = new ArrayList<Integer>(); } : fn=ID '(' (fexpr=expr { args.add( new Integer($fexpr.value)); } // is there a better way to do this? (',' aexpr=expr { args.add( new Integer($aexpr.value)); } )* // is there a better way to do this? )? ')' { //System.out.println("got fn:" + $fn.text + " with args:"+ args ); $value = this.dispatchFn( (String) $fn.text, args); }; expr returns [int value] : e=multExpr {$value = $e.value;} ( '+' e=multExpr {$value += $e.value;} | '-' e=multExpr {$value -= $e.value;} )* ; multExpr returns [int value] : e=atom {$value = $e.value;} ('*' e=atom {$value *= $e.value;})* ; atom returns [int value] : INT {$value = Integer.parseInt($INT.text);} | funcall {$value = $funcall.value; } | ID { Integer v = (Integer)memory.get($ID.text); if ( v!=null ) $value = v.intValue(); else System.err.println("undefined variable "+$ID.text); } | '(' expr ')' {$value = $expr.value;} ; ID : ('a'..'z'|'A'..'Z')+ ; INT : '0'..'9'+ ; NEWLINE:'\r'? '\n' ; WS : (' '|'\t')+ {skip();} ;
Refactorings
No refactoring yet !
shankar
January 6, 2009, January 06, 2009 05:31, permalink
hi could u help me to learn this program.
This is a mix of ANTLR ( http://www.antlr.org/ ) and regular Java.