My initial thought is that you possibly don't want to use a GrammerMatcher for this task.
The ConfigurableParser breaks parsing into three steps:
tokenising - creating a set of tokens representing the input
filtering - mainly to remove comments and whitespace
parsing - using grammatical rules to assemble the node tree
The default implementation bundles these together as a single methods:
parse(java.io.Reader stream),
but each stage can be performed separately. There are methods
public List<Token> scan(Reader stream) throws ParseException - does the tokenizing
public Iterator<Token> filter(List<Token> input) throws ParseException - does the filtering and produces an interator
public Node parse(Iterator<Token> it) throws ParseException - assemples the node tree
If you want to implement your own syntax checker you could to this at the filtering stage, either by sub-classing or by calling the methods separately. There you have access the full List of Tokens and do not need to be constrained by just peeking the next one or two tokens.
Another thing you could try is to make sure Jep.setImplicitMul(boolean) is set to false. This would mean its impossible to not have an operator between two numbers/variables. So "5 x" would raise an exception. This means apart from a single number or variable its impossible for an input not to contain an operator.
The general contract of a GrammarMatchers is: can the next few tokens be assembled to form the type of node I am trying to construct. If so return the Node if not return null. On rare occasions should they throw an exception when the input is known to be wrong say when a round bracket matches a square bracket. They are not really intended for checking the whole input.
Often things are much easier to check once the input has been parsed and the node tree assembled.
A more complex route might be to change the type of iterator used. Only having a two token lookahead is quite restrictive but serves the purpose for most maths expressions. It should be possible to create an itterator which any particular number of steps of lookahead, and one which could rewind if parsing a complex subexpression failed. To do this it would involve changing the way the ShuntingYard class is called. There is method ShuntingYard.html.setIterator(Lookahead2Iterator) which sets the iterator used. To use this you would have to create your own subclass of Lookahead2Iterator implement its all its methods like next(), nextnext() and consume() and add your own methods maybe something like Token lookahead(int n).
To use the ShuntingYard with this you would need to do subclass ConfigurableParser and change the parse method to something like
public Node parse(Iterator<Token> it) throws ParseException {
GrammarParser sy = gpf.newInstance(this);
MyItterator myitt = new MyItterator(it);
sy.setIterator(myitt);
Node node = sy.parseSubExpression();
if( myitt.peakNext() != null) throw new ParseException();
if( node == null ) throw new ParseException();
return node;
}
I might make it easier to change the iterator in the next release which will be coming soon.
Hope thats of some help. It might help to give an example of the kind of input you are trying to parse to really get a feel for the best method for your problem.
Richard