/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package fasp.parser.parsers;
import fasp.parser.tokenizer.SymbolToken;
import fasp.parser.*;
import fasp.parser.tokenizer.Token;
import fasp.parser.tokenizer.TokenState;
import fasp.datatypes.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import operators.*;
/**
*
* @author Jeroen Janssen <Jeroen.Janssen@vub.ac.be>
*/
public class RuleParser extends AbstractParser<NonGroundRule> {
private static final Map<String,MultiOperator> BODYOPERATORS;
static {
Map<String,MultiOperator> myMap = new HashMap<String,MultiOperator>();
myMap.put("ID", new ID());
myMap.put("TW",new TW());
myMap.put("TM",new TM());
myMap.put("WSUM",new WSUM());
myMap.put("MULTIMAX",new MULTIMAX());
BODYOPERATORS = myMap;
}
public NonGroundRule parse(TokenState st) throws ParseException {
// First: parse the head
boolean constraint;
NonGroundLiteral litHead = null;
LattVal constHead = null;
LiteralParser headParser = new LiteralParser();
LattValParser constParser = new LattValParser();
// Following is needed for proper error line output:
Token headToken = st.lookahead();
if(headParser.tryParse(st)) {
litHead = headParser.getResult();
if(litHead.isNaf())
throw new ParseException(headToken.getLocation(),"non-naf-literal","naf-literal: "+litHead.toString());
constraint = false;
} else if(constParser.tryParse(st)) {
constHead = constParser.getResult();
constraint = true;
} else {
throw new ParseException(st,"literal or lattice constant",st.lookahead().toString());
}
// Next: get the rule type token
Token ruleType = st.getNext();
if(!(ruleType.getType().equals(Token.Type.FUZZYRULE)
|| ruleType.getType().equals(Token.Type.REGRULE)
|| ruleType.getType().equals(Token.Type.CHOICERULE)))
throw new ParseException(st,"rule symbol (:-, :/, or :~)",ruleType.toString());
// Now parse the rule operator
Token bodyOpTok = st.getNext();
if(!bodyOpTok.getType().equals(Token.Type.SYMBOL))
throw new ParseException(bodyOpTok.getLocation(),"body operator",bodyOpTok.toString());
SymbolToken bodyOpSym = (SymbolToken)bodyOpTok;
if(!BODYOPERATORS.containsKey(bodyOpSym.getSymbol()))
throw new ParseException(st,unsupportedBodyOp(),bodyOpSym.getSymbol());
MultiOperator bodyOp = BODYOPERATORS.get(bodyOpSym.getSymbol());
// Parse the rule body
ArrayList<Groundable> body = new BetweenParser<ArrayList<Groundable>,Token,Token>(
new RuleBodyParser(),new TokenParser(Token.Type.OB),new TokenParser(Token.Type.CB)).parse(st);
// Parse the ending dot
new TokenParser(Token.Type.DOT).parse(st);
if(ruleType.getType().equals(Token.Type.FUZZYRULE)) {
if(constraint)
return new NonGroundFuzzyConstraint(constHead,body,bodyOp);
else
return new NonGroundFuzzyRule(litHead,body,bodyOp);
} else if(ruleType.getType().equals(Token.Type.REGRULE)) {
if(constraint)
return new NonGroundRegularConstraint(constHead,body,bodyOp);
else
return new NonGroundRegularRule(litHead,body,bodyOp);
} else
if(!constraint)
return new NonGroundChoiceRule(litHead,body,bodyOp);
else
throw new ParseException(st,"choicerule with literal in the head","choicerule with constant in the head");
}
private static String unsupportedBodyOp() {
StringBuffer buff = new StringBuffer();
buff.append("valid body operator (");
Iterator<String> it = BODYOPERATORS.keySet().iterator();
buff.append(it.next());
while(it.hasNext()) {
buff.append(',');
buff.append(it.next());
}
buff.append(")");
return buff.toString();
}
private class RuleBodyParser extends AbstractParser<ArrayList<Groundable>> {
public ArrayList<Groundable> parse(TokenState st) throws ParseException {
return new SeparatedListParser<Groundable,Token>(new RuleBodyEltParser(),new TokenParser(Token.Type.COMMA)).parse(st);
}
}
private class RuleBodyEltParser extends AbstractParser<Groundable> {
public Groundable parse(TokenState st) throws ParseException {
LiteralParser litP = new LiteralParser();
LattValParser lattP = new LattValParser();
BodyExpParser expP = new BodyExpParser();
if(litP.tryParse(st))
return litP.getResult();
else if(lattP.tryParse(st))
return lattP.getResult();
else if(expP.tryParse(st))
return expP.getResult();
else
throw new ParseException(st,"literal, lattice value or body expression",st.lookahead().toString());
}
}
}