001    /*
002     * Created on Sep 15, 2003 by Ravi Mohan
003     *  
004     */
005    package aima.logic.propositional.parsing;
006    
007    import java.util.ArrayList;
008    import java.util.List;
009    
010    import aima.logic.common.LogicTokenTypes;
011    import aima.logic.common.ParseTreeNode;
012    import aima.logic.common.Parser;
013    import aima.logic.common.Token;
014    import aima.logic.propositional.parsing.ast.AtomicSentence;
015    import aima.logic.propositional.parsing.ast.BinarySentence;
016    import aima.logic.propositional.parsing.ast.FalseSentence;
017    import aima.logic.propositional.parsing.ast.MultiSentence;
018    import aima.logic.propositional.parsing.ast.Sentence;
019    import aima.logic.propositional.parsing.ast.Symbol;
020    import aima.logic.propositional.parsing.ast.TrueSentence;
021    import aima.logic.propositional.parsing.ast.UnarySentence;
022    
023    /**
024     * @author Ravi Mohan
025     * 
026     */
027    
028    public class PEParser extends Parser {
029    
030            public PEParser() {
031                    lookAheadBuffer = new Token[lookAhead];
032            }
033    
034            @Override
035            public ParseTreeNode parse(String inputString) {
036                    lexer = new PELexer(inputString);
037                    fillLookAheadBuffer();
038                    return parseSentence();
039            }
040    
041            private TrueSentence parseTrue() {
042    
043                    consume();
044                    return new TrueSentence();
045    
046            }
047    
048            private FalseSentence parseFalse() {
049                    consume();
050                    return new FalseSentence();
051    
052            }
053    
054            private Symbol parseSymbol() {
055                    String sym = lookAhead(1).getText();
056                    consume();
057                    return new Symbol(sym);
058            }
059    
060            private AtomicSentence parseAtomicSentence() {
061                    Token t = lookAhead(1);
062                    if (t.getType() == LogicTokenTypes.TRUE) {
063                            return parseTrue();
064                    } else if (t.getType() == LogicTokenTypes.FALSE) {
065                            return parseFalse();
066                    } else if (t.getType() == LogicTokenTypes.SYMBOL) {
067                            return parseSymbol();
068                    } else {
069                            throw new RuntimeException(
070                                            "Error in parseAtomicSentence with Token " + lookAhead(1));
071                    }
072            }
073    
074            private UnarySentence parseNotSentence() {
075                    match("NOT");
076                    Sentence sen = parseSentence();
077                    return new UnarySentence(sen);
078            }
079    
080            private MultiSentence parseMultiSentence() {
081                    consume();
082                    String connector = lookAhead(1).getText();
083                    consume();
084                    List<Sentence> sentences = new ArrayList<Sentence>();
085                    while (lookAhead(1).getType() != LogicTokenTypes.RPAREN) {
086                            Sentence sen = parseSentence();
087                            // consume();
088                            sentences.add(sen);
089                    }
090                    match(")");
091                    return new MultiSentence(connector, sentences);
092            }
093    
094            private Sentence parseSentence() {
095                    if (detectAtomicSentence()) {
096                            return parseAtomicSentence();
097                    } else if (detectBracket()) {
098                            return parseBracketedSentence();
099                    } else if (detectNOT()) {
100                            return parseNotSentence();
101                    } else {
102    
103                            throw new RuntimeException("Parser Error Token = " + lookAhead(1));
104                    }
105            }
106    
107            private boolean detectNOT() {
108                    return (lookAhead(1).getType() == LogicTokenTypes.CONNECTOR)
109                                    && (lookAhead(1).getText().equals("NOT"));
110            }
111    
112            private Sentence parseBracketedSentence() {
113    
114                    if (detectMultiOperator()) {
115                            return parseMultiSentence();
116                    } else {
117                            match("(");
118                            Sentence one = parseSentence();
119                            if (lookAhead(1).getType() == LogicTokenTypes.RPAREN) {
120                                    match(")");
121                                    return one;
122                            } else if ((lookAhead(1).getType() == LogicTokenTypes.CONNECTOR)
123                                            && (!(lookAhead(1).getText().equals("Not")))) {
124                                    String connector = lookAhead(1).getText();
125                                    consume(); // connector
126                                    Sentence two = parseSentence();
127                                    match(")");
128                                    return new BinarySentence(connector, one, two);
129                            }
130    
131                    }
132                    throw new RuntimeException(
133                                    " Runtime Exception at Bracketed Expression with token "
134                                                    + lookAhead(1));
135            }
136    
137            private boolean detectMultiOperator() {
138                    return (lookAhead(1).getType() == LogicTokenTypes.LPAREN)
139                                    && ((lookAhead(2).getText().equals("AND")) || (lookAhead(2)
140                                                    .getText().equals("OR")));
141            }
142    
143            private boolean detectBracket() {
144                    return lookAhead(1).getType() == LogicTokenTypes.LPAREN;
145            }
146    
147            private boolean detectAtomicSentence() {
148                    int type = lookAhead(1).getType();
149                    return (type == LogicTokenTypes.TRUE)
150                                    || (type == LogicTokenTypes.FALSE)
151                                    || (type == LogicTokenTypes.SYMBOL);
152            }
153    }