I'm having trouble implementing an inner private enum class called: "LineCode" inside a class named Parser.
LineCode: Private Enum class that defines 6 types of general possible line of codes. I use Enum instantiation to send a Regex Pattern and compile it in the constructor, __init__, and then holds the Regex Matcher as a class variable.
Parser: Parses a programming language, irrelevant what language. Parser is using LineCode to identify the lines and proceed accordingly.
Problem: I can't access the enum members of __LineCode from a Static method. I wish to have a Static method inside __LineCode, "matchLineCode(line)" that receives a string from the Parser, it then iterates over the Enum members in the following logic:
- If Match is found: Return the enum
- If no more enums left: Return None
It doesn't seem trivial, I can't access the enum members to do this.
Attempts: I tried iterating over the enums using:
- __LineCode.__members__.values()
- Parser.__lineCode.__members__.values()
Both failed since it can't find __lineCode.
Ideally: LineCode class must be private, and not be visible to any other class importing the Parser. Parser must use the static method that LineCode class provides to return the Enum. I am willing to accept any solution that solves this issue or one that mimics this behavior.
I omitted some of the irrelevant Parser methods to improve readability. Code:
class Parser:
    class __LineCode(Enum):
        STATEMENT = ("^\s*(.*);\s*$")
        CODE_BLOCK = ("^\s*(.*)\s*\{\s*$")
        CODE_BLOCK_END = ("^\s*(.*)\s*\}\s*$")
        COMMENT_LINE = ("^\s*//\s*(.*)$")
        COMMENT_BLOCK = ("^\s*(?:/\*\*)\s*(.*)\s*$")
        COMMENT_BLOCK_END = ("^\s*(.*)\s*(?:\*/)\s*$")
        BLANK_LINE = ("^\s*$")
        def __init__(self, pattern):
            self.__matcher = re.compile(pattern)
        @property
        def matches(self, line):
            return self.__matcher.match(line)
        @property
        def lastMatch(self):
            try:
                return self.__matcher.groups(1)
            except:
                return None
        @staticmethod
        def matchLineCode(line):
            for lineType in **???**:
                if lineType.matches(line):
                    return lineType
            return None
    def __init__(self, source=None):
        self.__hasNext = False
        self.__instream = None
        if source:
            self.__instream = open(source)
    def advance(self):
        self.__hasNext = False
        while not self.__hasNext:
            line = self.__instream.readline()
            if line == "":  # If EOF
                self.__closeFile()
                return
            lineCode = self.__LineCode.matchLineCode(line)
            if lineCode is self.__LineCode.STATEMENT:
                pass
            elif lineCode is self.__LineCode.CODE_BLOCK:
                pass
            elif lineCode is self.__LineCode.CODE_BLOCK_END:
                pass
            elif lineCode is self.__LineCode.COMMENT_LINE:
                pass
            elif lineCode is self.__LineCode.COMMENT_BLOCK:
                pass
            elif lineCode is self.__LineCode.COMMENT_BLOCK:
                pass
            elif lineCode is self.__LineCode.BLANK_LINE:
                pass
            else:
                pass  # TODO Invalid file.
I already implemented it in Java, I want to reconstruct the same thing in Python:
private enum LineCode {
        STATEMENT("^(.*)" + Syntax.EOL + "\\s*$"), // statement line
        CODE_BLOCK("^(.*)" + Syntax.CODE_BLOCK + "\\s*$"), // code block open line
        CODE_BLOCK_END("^\\s*" + Syntax.CODE_BLOCK_END + "\\s*$"), // code block close line
        COMMENT_LINE("^\\s*" + Syntax.COMMENT + "(.*+)$"), // comment line
        BLANK_LINE("\\s*+$"); // blank line
        private final static int CONTENT_GROUP = 1;
        private Pattern pattern;
        private Matcher matcher;
        private LineCode(String regex) {
            pattern = Pattern.compile(regex);
        }
        boolean matches(String line) {
            matcher = pattern.matcher(line);
            return matcher.matches();
        }
        String lastMatch() {
            try {
                return matcher.group(CONTENT_GROUP);
            } catch (IndexOutOfBoundsException e) {
                return matcher.group();
            }
        }
    static LineCode matchLineCode(String line) throws    UnparsableLineException {
        for (LineCode lineType : LineCode.values())
            if (lineType.matches(line)) return lineType;
        throw new UnparsableLineException(line);
    }
Thanks.
 
     
    