All Downloads are FREE. Search and download functionalities are using the official Maven repository.

aima.core.logic.propositional.parsing.PLLexer Maven / Gradle / Ivy

package aima.core.logic.propositional.parsing;

import aima.core.logic.common.Lexer;
import aima.core.logic.common.LexerException;
import aima.core.logic.common.LogicTokenTypes;
import aima.core.logic.common.Token;
import aima.core.logic.propositional.parsing.ast.Connective;
import aima.core.logic.propositional.parsing.ast.PropositionSymbol;

/**
 * A concrete implementation of a lexical analyzer for the propositional language.
 * 
 * @author Ciaran O'Reilly
 * @author Ravi Mohan
 * @author Mike Stampone
 */
public class PLLexer extends Lexer {
	
	/**
	 * Default Constructor.
	 */
	public PLLexer() {
	}

	/**
	 * Constructs a propositional expression lexer with the specified character
	 * stream.
	 * 
	 * @param inputString
	 *            a sequence of characters to be converted into a sequence of
	 *            tokens.
	 */
	public PLLexer(String inputString) {
		setInput(inputString);
	}

	/**
	 * Returns the next propositional token from the character stream.
	 * 
	 * @return the next propositional token from the character stream.
	 */
	@Override
	public Token nextToken() {
		int startPosition = getCurrentPositionInInput();
		if (lookAhead(1) == '(') {
			consume();
			return new Token(LogicTokenTypes.LPAREN, "(", startPosition);
		} else if (lookAhead(1) == '[') {
				consume();
				return new Token(LogicTokenTypes.LSQRBRACKET, "[", startPosition);
		} else if (lookAhead(1) == ')') {
			consume();
			return new Token(LogicTokenTypes.RPAREN, ")", startPosition);
		} else if (lookAhead(1) == ']') {
			consume();
			return new Token(LogicTokenTypes.RSQRBRACKET, "]", startPosition);
		} else if (Character.isWhitespace(lookAhead(1))) {
			consume();
			return nextToken();
		} else if (connectiveDetected(lookAhead(1))) {
			return connective();
		} else if (symbolDetected(lookAhead(1))) {
			return symbol();
		} else if (lookAhead(1) == (char) -1) {
			return new Token(LogicTokenTypes.EOI, "EOI", startPosition);
		} else {
			throw new LexerException("Lexing error on character " + lookAhead(1) + " at position " + getCurrentPositionInInput(), getCurrentPositionInInput());
		}
	}

	private boolean connectiveDetected(char leadingChar) {
		return Connective.isConnectiveIdentifierStart(leadingChar);
	}
	
	private boolean symbolDetected(char leadingChar) {
		return PropositionSymbol.isPropositionSymbolIdentifierStart(leadingChar);
	}
	
	private Token connective() {
		int startPosition = getCurrentPositionInInput();
		StringBuffer sbuf = new StringBuffer();
		// Ensure pull out just one connective at a time, the isConnective(...)
		// test ensures we handle chained expressions like the following:
		// ~~P
		while (Connective.isConnectiveIdentifierPart(lookAhead(1)) && !isConnective(sbuf.toString())) {
			sbuf.append(lookAhead(1));
			consume();
		}
		
		String symbol = sbuf.toString();
		if (isConnective(symbol)) {
			return new Token(LogicTokenTypes.CONNECTIVE, sbuf.toString(), startPosition);
		}
		
		throw new LexerException("Lexing error on connective "+symbol + " at position " + getCurrentPositionInInput(), getCurrentPositionInInput());
	}

	private Token symbol() {
		int startPosition = getCurrentPositionInInput();
		StringBuffer sbuf = new StringBuffer();
		while (PropositionSymbol.isPropositionSymbolIdentifierPart(lookAhead(1))) {
			sbuf.append(lookAhead(1));
			consume();
		}
		String symbol = sbuf.toString();
		if (PropositionSymbol.isAlwaysTrueSymbol(symbol)) {
			return new Token(LogicTokenTypes.TRUE, PropositionSymbol.TRUE_SYMBOL, startPosition);
		} else if (PropositionSymbol.isAlwaysFalseSymbol(symbol)) {
			return new Token(LogicTokenTypes.FALSE, PropositionSymbol.FALSE_SYMBOL, startPosition);
		} else if (PropositionSymbol.isPropositionSymbol(symbol)){
			return new Token(LogicTokenTypes.SYMBOL, sbuf.toString(), startPosition);
		}
		
		throw new LexerException("Lexing error on symbol "+symbol+ " at position "+ getCurrentPositionInInput(), getCurrentPositionInInput());
	}

	private boolean isConnective(String aSymbol) {
		return Connective.isConnective(aSymbol);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy