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 }