lojix/logic/src/main/com/thesett/aima/logic/fol/isoprologparser/PrologParser.java
public List<Term> terms(List<Term> terms) throws SourceCodeException
    {
        Term term;

        Token nextToken = tokenSource.peek();

        switch (nextToken.kind)
        {
        case FUNCTOR:
            term = functor();
            break;

        case LSQPAREN:
            term = listFunctor();
            break;

        case VAR:
            term = variable();
            break;

        case INTEGER_LITERAL:
            term = intLiteral();
            break;

        case FLOATING_POINT_LITERAL:
            term = doubleLiteral();
            break;

        case STRING_LITERAL:
            term = stringLiteral();
            break;

        case ATOM:
            term = atom();
            break;

        case LPAREN:
            consumeToken(LPAREN);

            term = term();

            // Mark the term as bracketed to ensure that this is its final parsed form. In particular the
            // #arglist method will not break it up if it contains commas.
            term.setBracketed(true);

            consumeToken(RPAREN);
            break;

        default:
            throw new SourceCodeException("Was expecting one of " + BEGIN_TERM_TOKENS + " but got " +
                tokenImage[nextToken.kind] + ".", null, null, null,
                new SourceCodePositionImpl(nextToken.beginLine, nextToken.beginColumn, nextToken.endLine,
                    nextToken.endColumn));
        }

        terms.add(term);

        switch (tokenSource.peek().kind)
        {
        case LPAREN:
        case LSQPAREN:
        case INTEGER_LITERAL:
        case FLOATING_POINT_LITERAL:
        case STRING_LITERAL:
        case VAR:
        case FUNCTOR:
        case ATOM:
            terms(terms);
            break;

        default:
        }

        return terms;
    }
public List<Term> terms(List<Term> terms) throws SourceCodeException
    {
        Term term;

        Token nextToken = tokenSource.peek();

        switch (nextToken.kind)
        {
        case FUNCTOR:
            term = functor();
            break;

        case LSQPAREN:
            term = listFunctor();
            break;

        case VAR:
            term = variable();
            break;

        case INTEGER_LITERAL:
            term = intLiteral();
            break;

        case FLOATING_POINT_LITERAL:
            term = doubleLiteral();
            break;

        case STRING_LITERAL:
            term = stringLiteral();
            break;

        case ATOM:
            term = atom();
            break;

        case LPAREN:
            consumeToken(LPAREN);

            term = term();

            // Mark the term as bracketed to ensure that this is its final parsed form. In particular the
            // #arglist method will not break it up if it contains commas.
            term.setBracketed(true);

            consumeToken(RPAREN);
            break;

        default:
            throw new SourceCodeException("Was expecting one of " + BEGIN_TERM_TOKENS + " but got " +
                tokenImage[nextToken.kind] + ".", null, null, null,
                new SourceCodePositionImpl(nextToken.beginLine, nextToken.beginColumn, nextToken.endLine,
                    nextToken.endColumn));
        }

        terms.add(term);

        switch (tokenSource.peek().kind)
        {
        case LPAREN:
        case LSQPAREN:
        case INTEGER_LITERAL:
        case FLOATING_POINT_LITERAL:
        case STRING_LITERAL:
        case VAR:
        case FUNCTOR:
        case ATOM:
            terms(terms);
            break;

        default:
        }

        return terms;
    }
Recursively parses terms, which may be functors, atoms, variables, literals or operators, into a flat list in the
order in which they are encountered.

@param  terms A list of terms to accumulate in.

@return The list of terms encountered in order.

@throws SourceCodeException If the sequence of tokens does not form a valid syntactical construction as a list of
first order logic terms.