001    /*
002     * Created on Sep 18, 2004
003     *
004     */
005    package aima.logic.fol.parsing;
006    
007    import java.util.HashSet;
008    import java.util.Set;
009    
010    import aima.logic.common.Lexer;
011    import aima.logic.common.LogicTokenTypes;
012    import aima.logic.common.Token;
013    import aima.logic.fol.Connectors;
014    import aima.logic.fol.Quantifiers;
015    import aima.logic.fol.domain.FOLDomain;
016    
017    /**
018     * @author Ravi Mohan
019     * 
020     */
021    public class FOLLexer extends Lexer {
022            private FOLDomain domain;
023            private Set<String> connectors,
024                            quantifiers;
025    
026            public FOLLexer(FOLDomain domain) {
027                    this.domain = domain;
028    
029                    connectors = new HashSet<String>();
030                    connectors.add(Connectors.NOT);
031                    connectors.add(Connectors.AND);
032                    connectors.add(Connectors.OR);
033                    connectors.add(Connectors.IMPLIES);
034                    connectors.add(Connectors.BICOND);
035    
036                    quantifiers = new HashSet<String>();
037                    quantifiers.add(Quantifiers.FORALL);
038                    quantifiers.add(Quantifiers.EXISTS);
039            }
040            
041            public FOLDomain getFOLDomain() {
042                    return domain;
043            }
044    
045            @Override
046            public Token nextToken() {
047                    Token result = null;
048                    int tokenType;
049                    String tokenContent;
050    
051                    if (lookAhead(1) == '(') {
052                            consume();
053                            return new Token(LogicTokenTypes.LPAREN, "(");
054    
055                    } else if (lookAhead(1) == ')') {
056                            consume();
057                            return new Token(LogicTokenTypes.RPAREN, ")");
058    
059                    } else if (lookAhead(1) == ',') {
060                            consume();
061                            return new Token(LogicTokenTypes.COMMA, ",");
062    
063                    } else if (identifierDetected()) {
064                            // System.out.println("identifier detected");
065                            return identifier();
066                    } else if (Character.isWhitespace(lookAhead(1))) {
067                            consume();
068                            return nextToken();
069                    } else if (lookAhead(1) == (char) -1) {
070                            return new Token(LogicTokenTypes.EOI, "EOI");
071                    } else {
072                            throw new RuntimeException("Lexing error on character "
073                                            + lookAhead(1));
074                    }
075            }
076    
077            private Token identifier() {
078                    StringBuffer sbuf = new StringBuffer();
079                    while ((Character.isJavaIdentifierPart(lookAhead(1)))
080                                    || partOfConnector()) {
081                            sbuf.append(lookAhead(1));
082                            consume();
083                    }
084                    String readString = new String(sbuf);
085                    // System.out.println(readString);
086                    if (connectors.contains(readString)) {
087                            return new Token(LogicTokenTypes.CONNECTOR, readString);
088                    } else if (quantifiers.contains(readString)) {
089                            return new Token(LogicTokenTypes.QUANTIFIER, readString);
090                    } else if (domain.getPredicates().contains(readString)) {
091                            return new Token(LogicTokenTypes.PREDICATE, readString);
092                    } else if (domain.getFunctions().contains(readString)) {
093                            return new Token(LogicTokenTypes.FUNCTION, readString);
094                    } else if (domain.getConstants().contains(readString)) {
095                            return new Token(LogicTokenTypes.CONSTANT, readString);
096                    } else if (isVariable(readString)) {
097                            return new Token(LogicTokenTypes.VARIABLE, readString);
098                    } else if (readString.equals("=")) {
099                            return new Token(LogicTokenTypes.EQUALS, readString);
100                    } else {
101                            throw new RuntimeException("Lexing error on character "
102                                            + lookAhead(1));
103                    }
104    
105            }
106    
107            private boolean isVariable(String s) {
108                    return (Character.isLowerCase(s.charAt(0)));
109            }
110    
111            private boolean identifierDetected() {
112                    return (Character.isJavaIdentifierStart((char) lookAheadBuffer[0]))
113                                    || partOfConnector();
114            }
115    
116            private boolean partOfConnector() {
117                    return (lookAhead(1) == '=') || (lookAhead(1) == '<')
118                                    || (lookAhead(1) == '>');
119            }
120    
121    }