KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > tests > jfun > parsec > coloring > JavaFormatter


1 /*
2  * Created on Dec 6, 2004
3  *
4  * Author Ben Yu
5  */

6 package tests.jfun.parsec.coloring;
7 import java.util.HashMap JavaDoc;
8
9 import jfun.parsec.Tokenizer;
10 import jfun.parsec.pattern.Pattern;
11 import jfun.parsec.pattern.Patterns;
12 import jfun.parsec.DefaultPositionMap;
13 import jfun.parsec.Lexers;
14 import jfun.parsec.Scanners;
15 import jfun.parsec.Parser;
16 import jfun.parsec.Parsers;
17 /**
18  * @author Ben Yu
19  *
20  * Dec 6, 2004
21  */

22 final class JavaFormatter {
23   private final String JavaDoc[] keywords = {
24       "if","else","this","private","static","public",
25       "protected","final","interface","class","abstract",
26       "extends","implements",
27       "import", "package", "for","while","do",
28       "switch","case","break","continue",
29       "return","default","super","new",
30       "try","catch","finally","throw","throws","const"};
31   private final char[] ops = {'+','-','*','/','%',
32       '|','&','>','<','=',';',',','.','?',':','!','^','(',')','[',']',
33       '{','}','~','@','#','\\','`'};
34   private final char[] delimiters = {'+','-','*','/','%',
35       '|','&','>','<','=',';',',','.','?',':','!','^','(',')','[',']',
36       '{','}','~',' ', '\t', '\r','\n','`','\\','@','#'};
37   private final String JavaDoc[] natives = {"int","long","char","short","boolean"};
38   private final String JavaDoc[] stds = {"String","Integer","Long","Short","Character","Boolean","finalize"};
39   private static HashMap JavaDoc toMap(String JavaDoc[] words){
40     final HashMap JavaDoc ret = new HashMap JavaDoc();
41     for(int i=0; i<words.length; i++){
42       ret.put(words[i], words[i]);
43     }
44     return ret;
45   }
46   private final HashMap JavaDoc keywords_map = toMap(keywords);
47   private final HashMap JavaDoc natives_map = toMap(natives);
48   private final HashMap JavaDoc stds_map = toMap(stds);
49
50   private static final Object JavaDoc nil_token = new Object JavaDoc();
51   private Tokenizer getOpTokenizer(final CodeStream stream){
52     return new Tokenizer(){
53       public Object JavaDoc toToken(final CharSequence JavaDoc cs, final int from, final int len){
54         stream.addOperator(cs, from, len);
55         return nil_token;
56       }
57     };
58   }
59   private Tokenizer getCommentTokenizer(final CodeStream stream){
60     return new Tokenizer(){
61       public Object JavaDoc toToken(final CharSequence JavaDoc cs, final int from, final int len){
62         stream.addComment(cs, from, len);
63         return nil_token;
64       }
65     };
66   }
67   private Tokenizer getWhitespaceTokenizer(final CodeStream stream){
68     return new Tokenizer(){
69       public Object JavaDoc toToken(final CharSequence JavaDoc cs, final int from, final int len){
70         stream.addWhitespace(cs, from, len);
71         return nil_token;
72       }
73     };
74   }
75   private Tokenizer getStringTokenizer(final CodeStream stream){
76     return new Tokenizer(){
77       public Object JavaDoc toToken(final CharSequence JavaDoc cs, final int from, final int len){
78         stream.addStringLiteral(cs, from, len);
79         return nil_token;
80       }
81     };
82   }
83   private Tokenizer getCharTokenizer(final CodeStream stream){
84     return new Tokenizer(){
85       public Object JavaDoc toToken(final CharSequence JavaDoc cs, final int from, final int len){
86         stream.addCharLiteral(cs, from, len);
87         return nil_token;
88       }
89     };
90   }
91   private Tokenizer getNumTokenizer(final CodeStream stream){
92     return new Tokenizer(){
93       public Object JavaDoc toToken(final CharSequence JavaDoc cs, final int from, final int len){
94         stream.addNumberLiteral(cs, from, len);
95         return nil_token;
96       }
97     };
98   }
99   private Tokenizer getWordTokenizer(final CodeStream stream){
100     return new Tokenizer(){
101       public Object JavaDoc toToken(final CharSequence JavaDoc cs, final int from, final int len){
102         final String JavaDoc str = cs.subSequence(from, from+len).toString();
103         if(keywords_map.containsKey(str)){
104           stream.addKeyword(cs, from, len);
105         }
106         else if(natives_map.containsKey(str)){
107           stream.addNativeWord(cs, from, len);
108         }
109         else if(stds_map.containsKey(str)){
110           stream.addStandardWord(cs, from, len);
111         }
112         else stream.addRegular(cs, from, len);
113         return nil_token;
114       }
115     };
116   }
117
118   
119   private Parser getLexer(final CodeStream stream){
120     final Parser isInteger = Scanners.isPattern(
121         Patterns.or(
122           Patterns.isHexInteger(),
123           Patterns.isOctInteger(),
124           Patterns.isDecInteger()
125         ).seq(Patterns.among(new char[]{'l','L'}).optional()),
126         "integer literal"
127     );
128     final Parser isDecimal = Scanners.isPattern(Patterns.isDecimal(), "decimal");
129     final Pattern word_char = Patterns.notAmong(delimiters);
130     final Parser numLiteral = Parsers.longer(isDecimal, isInteger)
131       .seq(Scanners.isPattern(Patterns.isExponential().optional()
132           .seq(word_char.not()), "number literal"
133           )
134       );
135     final Parser word_lexer = Lexers.lexer(Scanners.isPattern(word_char.many1(), "word"),
136         getWordTokenizer(stream));
137     final Parser op_lexer = Lexers.lexer(Scanners.among(ops).many1(),
138         getOpTokenizer(stream));
139     final Parser comment_lexer = Lexers.lexer(Parsers.sum(Scanners.javaBlockComment(), Scanners.javaLineComment()),
140       getCommentTokenizer(stream));
141     final Parser str_lexer = Lexers.lexer(Scanners.isQuotedString(),
142         getStringTokenizer(stream));
143     Pattern any_chr = Patterns.hasAtLeast(1);
144     Pattern single_quote = Patterns.isChar('\'');
145     Pattern ptn_chr =
146       /*single_quote.seq(
147         Patterns.or(Patterns.isChar('\\').seq(any_chr), any_chr)
148       ).seq(single_quote);*/

149     Patterns.regex("'((\\.)|.)'");
150     final Parser char_lexer =
151       Lexers.lexer(Scanners.isPattern(ptn_chr,
152           "character literal"),
153         getCharTokenizer(stream));
154     final Parser num_lexer = Lexers.lexer(numLiteral,
155         getNumTokenizer(stream));
156     final Parser space_lexer = Lexers.lexer(Scanners.isWhitespaces(),
157       getWhitespaceTokenizer(stream));
158     return Parsers.sum(new Parser[]{
159         space_lexer, comment_lexer,
160         op_lexer,
161         str_lexer, char_lexer,
162         num_lexer, word_lexer
163     }).many();
164   }
165   public void format(final CharSequence JavaDoc src,
166       final CodeStream stream){
167     final Parser lx = getLexer(stream);
168     Parsers.runParser(src, lx,
169         new DefaultPositionMap(src, 1, 1), "java formatter");
170   }
171 }
172
Popular Tags