tags:

views:

77

answers:

6

Am implementing a lexical scanner. How can i implement sets of characters? most of the character sets will be in range form i.e A-Z, h-L e.t.c. And i have to check if a character, ch is a member of a character set. Which efficient data structure can i use in Java other than arrays and Bit Set?

A: 

You could make a Set of Character objects and check with the contains method.

Alberto Zaccagni
+2  A: 

Have you considered using a scanner generator like JFlex?
You specify the language you want to scan and JFlex produces java code for you.

Marcel Benthin
+2  A: 

Use a HashSet together with the "wrapper class" for char: java.lang.Character:

Set<Character> s = new HashSet<Character>();
s.add('a');
s.add('b');

etc.

oxbow_lakes
+1  A: 

Apache Commons Lang includes the CharRange class, which efficiently represents contiguous ranges of characters without resorting to loops, iterators and sets.

skaffman
A: 

Have you looked at ANTLR?

TrueWill
A: 

You could use HashSet directly, or you could create a wrapper class something like the following to allow you to instantiate the sets more succinctly:

public class MyCharSet extends Set<Character> {
    /**
     * @param ranges an N x 2 array representing inclusive character ranges.
     */
    public MyCharSet(char[][] ranges) {
        super(intuitSize(ranges));
        for (char[] range : ranges) {
            for (char ch = range[0]; ch <= range[1]; ch++) {
                this.add(ch);
            }
        }
    }

    private static int intuitSize(char[][]ranges) {
        if (ranges.length == 0) {
            return 0;
        }
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        for (char[] range : ranges) {
            if (range.length != 2 || range[0] > range[1]) {
                throw new IllegalArgumentException("bad range");
            }
            min = Math.min(ranges[0], min);
            max = Math.max(ranges[1], max);
        }
        return max - min;
    }
}
Stephen C