Removing ambiguities between assignment and invocation

SyntaxEditor for WPF Forum

Posted 1 year ago by Daisuke Nakada
Version: 17.2.0664
Avatar

Hi,

I'm using the LL(*) Parser Framework and implementing the grammar. But I've been struggling with removing ambiguities.

The following is the simple version of my grammar code.

 statement.Production = assignmentStatement | invocation;
 
 assignmentStatement.Production = variable + @assign + expression + @semicolon;
 
 invocation.Production = variable + @openParen + paramAssignmentList.Optional() + @closeParen + @semicolon;
 
 variable.Production = @identifier | multiElementVariable;

 multiElementVariable.Production = @identifier + (subscriptList | (@dot + @identifier)).OneOrMore();
 
 subscriptList.Production = @openSquareBrace + expression + (@comma + expression).ZeroOrMore() + @closeSquareBrace;
 
 paramAssignmentList.Production = expression + (@comma + expression).ZeroOrMore();

Although I did not show in the above code to keep it concise, I'm using Core (built-in) Tree Construction to build an AST.

I've already created a Can-Match callback for the multiElementVariable:

private bool CanMatchMultiElementVariable(IParserState state) {
    if (state.TokenReader.AreNext(TokenId.Identifier, TokenId.OpenSquareBrace)) {
        return true;
    }
    if (state.TokenReader.AreNext(TokenId.Identifier, TokenId.Dot)) {
        return true;
    }
    return false;
}

 The problem is that an assignmenStatement and invocation both start with a variable so I need to create a Can-Match callback for the assignmentStatement or invocation. But a variable can be complex when it is a multiElementVariable.

When the variable is a multiElementVariable, an assignmentStatement can be like this:
x.y[1].z = 1;

And an invocation can be like this:
x.y[1].z();

I tried some approaches to create an appropriate Can-Match callback but nothing could solve the problem.
I'd appreciate it if you could give me advice.

Comments (2)

Posted 1 year ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

Yes that scenario can be tricky due to the ambiguity. What we would probably do with something like that is have something like this:

statement.Production = statementWithVariable;
statementWithVariable = variable + (assignmentStatement | invocation);
assignmentStatement.Production = @assign + expression + @semicolon;
invocation.Production = @openParen + paramAssignmentList.Optional() + @closeParen + @semicolon;

Basically put the common item in a new production so it always gets parsed. Then switch to the others but don't have 'variable' in them.

If they both produce some common base AST node class that has a Variable property on it, then you can use AstFrom<YourNodeClassWithVariable>.SetProperty(n => n.Variable, ...).

I hope that helps!


Actipro Software Support

Posted 1 year ago by Daisuke Nakada
Avatar

Hi,

Finally, it worked. Thank you!

The latest build of this product (v2019.1 build 0681) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.