KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fri > patterns > interpreter > parsergenerator > semantics > ReflectSemantic


1 package fri.patterns.interpreter.parsergenerator.semantics;
2
3 import java.lang.reflect.*;
4 import java.util.*;
5 import fri.patterns.interpreter.parsergenerator.syntax.Rule;
6 import fri.patterns.interpreter.parsergenerator.Semantic;
7
8 /**
9     Semantic base class that tries to call methods with the same name as nonterminal
10     on left side of rule. The number of parameters of the method must be the same as
11     the number of symbols on the right side of the rule, all parameters must be of type
12     Object, and the return type must be Object. The method might process the parse
13     results and return an arbitrary Object to be processed by another callback method.
14     The ranges of the currently dispatched rule is available by protected getRanges() method.
15     <p/>
16     Example: Both rules
17     <pre>
18         expression ::= expression "+" term ;
19         expression ::= expression "-" term ;
20     </pre>
21     would be dispatched by
22     <pre>
23         public Object expression(Object expression, Object operator, Object term) {
24             int e = ((Integer) expression).intValue();
25             int t = ((Integer) term).intValue();
26             if (operator.equals("+"))
27                 return new Integer(e + t);
28             else
29             if (operator.equals("-"))
30                 return new Integer(e - t);
31             else
32                 throw new IllegalArgumentException("Unknown operator: "+operator);
33         }
34     </pre>
35     
36     @see fri.patterns.interpreter.parsergenerator.examples.Calculator
37     @author (c) 2000, Fritz Ritzberger
38 */

39
40 public abstract class ReflectSemantic implements Semantic
41 {
42     private List ranges;
43     
44     /**
45         Tries to find a method with same name as left side of rule and number of arguments
46         as much as elements in inputTokens list. All argument types are Object.
47         @param rule the rule that was recognized by the parser.
48         @param inputTokens all semantic call returns from underlying rules, collected according to current rule.
49         @return object to push on parser value-stack.
50     */

51     public Object JavaDoc doSemantic(Rule rule, List inputTokens, List ranges) {
52         this.ranges = ranges;
53         
54         String JavaDoc nonterminal = rule.getNonterminal();
55         
56         Class JavaDoc [] types = new Class JavaDoc [inputTokens.size()];
57         for (int i = 0; i < types.length; i++)
58             types[i] = Object JavaDoc.class;
59         
60         Method m = null;
61         try {
62             m = getClass().getMethod(nonterminal, types);
63         }
64         catch (Exception JavaDoc e) {
65             //System.err.println("WARNING: method not implemented: "+nonterminal+", input is "+inputTokens);
66
return fallback(rule, inputTokens, ranges);
67         }
68         
69         Object JavaDoc [] args = new Object JavaDoc[inputTokens.size()];
70         inputTokens.toArray(args);
71
72         if (m != null) {
73             try {
74                 m.setAccessible(true); // problem with anonymous inner classes
75
Object JavaDoc o = m.invoke(this, args);
76                 return o;
77             }
78             catch (IllegalAccessException JavaDoc e) {
79                 e.printStackTrace();
80             }
81             catch (IllegalArgumentException JavaDoc e) {
82                 e.printStackTrace();
83             }
84             catch (InvocationTargetException e) {
85                 e.printStackTrace();
86                 throw new RuntimeException JavaDoc("ERROR in ReflectSemantic : "+e.getTargetException().toString());
87             }
88         }
89         return null;
90     }
91
92     /**
93         Fallback semantic handler that is called when no method was found by reflection.
94         This method provides a default List aggregation for left recursive rules.
95         @return first list element if input list has only one element,
96                 a List if the passed rule is left recursive,
97                 else the unmodified inputTokens list.
98     */

99     protected Object JavaDoc fallback(Rule rule, List inputTokens, List ranges) {
100         if (inputTokens.size() == 1) // push the one object on parser value stack
101
return inputTokens.get(0);
102             
103         // check for loop rule and add 1..n right symbols to first right symbol (List)
104
if (inputTokens.size() >= 2 && inputTokens.get(0) instanceof List && rule.getNonterminal().equals(rule.getRightSymbol(0))) {
105             List list = (List) inputTokens.get(0);
106             for (int i = 1; i < inputTokens.size(); i++)
107                 list.add(inputTokens.get(i));
108                 
109             return list;
110         }
111         
112         return inputTokens;
113     }
114     
115     
116     /** Returns the current Token.Range list of all input tokens. */
117     protected List getRanges() {
118         return ranges;
119     }
120
121 }
122
Popular Tags