Only match optional term if term ahead is present

SyntaxEditor for WPF Forum

Posted 9 months ago by Laif Harwood
Version: 17.2.0644
resourceExpression.Production = getResourceQuantityExpression.Optional() + resourceRelationalExpression;

getStatement.Production = @get + resourceExpression.OnErrorContinue();

There are cases where getResourceQuantityExpression and resourceRelationalExpression can match the same text and with getResourceQuantityExpression being optional the goal is to only have it match if there is a resourceRelationalExpression present after it. I have tried adding a CanMatchCallback to getResourceQuantityExpression to look ahead and try and determine if there is a resourceRelationalExpression ahead of it and can get it to work in some cases and others not and may be able to figure out a way to get that to work but it's getting messy so I'm wondering if there is a simpler way to do this?

Here are some examples of valid text:

get (1 identifier)
get 1 identifier
get identifier
get identifier identifier
get (identifier identifier)
get (identifier) (identifier)
get (1 + identifier) (identifier)
get 1 identifier or 1 identifier

I can also post more detailed code if needed. Thanks!

Comments (3)

Posted 9 months ago by Actipro Software Support - Cleveland, OH, USA

Hi Laif,

Our parser is an LL(*) parser, so the can-match callbacks can only do token scanning. If the tokens you are looking at represent potentially complex productions like an expression, that can result in repetition of much of the logic used to define the expression production itself. With the design of the language you are modeling, that is an unfortunate limitation of the LL(*) parser pattern.

Actipro Software Support

Posted 8 months ago by Laif Harwood

Do you have any suggestions on what we can do? Is using the can-match callback and looking ahead our only option?

Posted 8 months ago by Actipro Software Support - Cleveland, OH, USA

Hi Laif,

Yes the LL(*) parser generally is LL(1), meaning look ahead at the next token to determine what term to match.  Using can-match callbacks let you look ahead any number of tokens to determine what term to match, useful in scenarios that a single token isn't enough.  Normally looking ahead 2 or 3 tokens is enough to provide a can-match result.  Can-match callbacks are the only way to determine if a term should start being matched.

Your scenario is using a very ambiguous syntax and if you need to fully evaluate an expression, that will be tedious to program a can-match for.

The only other option is to not use a can-match callback as much and just allow for things like generic expressions to be after a "get" keyword.  Then make a custom tree construction node that examines the collection of matches for the production.  If the matches are valid, build up an AST node to return based on the AST nodes provided in the matches.

You could also use callbacks (like for Success/Error/Complete) on production terms to check things and report parse errors if appropriate.

Actipro Software Support

The latest build of this product (v22.1.3) was released 20 days ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.