Removing ambiguities between assignment and invocation

SyntaxEditor for WPF Forum

Posted 2 years 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 2 years 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 2 years ago by Daisuke Nakada
Avatar

Hi,

Finally, it worked. Thank you!

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

Add Comment

Please log in to a validated account to post comments.