ScalewingedAcidicorn
ScalewingedAcidicorn

Reputation: 549

How to resolve Xtext variables' names and keywords statically?

I have a grammar describing an assembler dialect. In code section programmer can refer to registers from a certain list and to defined variables. Also I have a rule matching both [reg0++413] and [myVariable++413]:

BinaryBiasInsideFetchOperation:
    '[' 
    v = (Register|[IntegerVariableDeclaration]) ( gbo = GetBiasOperation val = (Register|IntValue|HexValue) )?
    ']'
;

But when I try to compile it, Xtext throws a warning:

Decision can match input such as "'[' '++' 'reg0' ']'" using multiple alternatives: 2, 3. As a result, alternative(s) 3 were disabled for that input

Spliting the rules I've noticed, that

BinaryBiasInsideFetchOperation:
    '[' 
        v = Register ( gbo = GetBiasOperation val = (Register|IntValue|HexValue) )?
    ']'
;

BinaryBiasInsideFetchOperation:
    '[' 
    v = [IntegerVariableDeclaration] ( gbo = GetBiasOperation val = (Register|IntValue|HexValue) )?
    ']'
;

work well separately, but not at the same time. When I try to compile both of them, XText writes a number of errors saying that registers from list could be processed ambiguously. So:

1) Am I right, that part of rule v = (Register|[IntegerVariableDeclaration]) matches any IntegerVariable name including empty, but rule v = [IntegerVariableDeclaration] matches only nonempty names?

2) Is it correct that when I try to compile separate rules together Xtext thinks that [IntegerVariableDeclaration] can concur with Register?

3) How to resolve this ambiguity?

edit: definitors

Register: 
    areg = ('reg0' | 'reg1' | 'reg2' | 'reg3' | 'reg4' | 'reg5' | 'reg6' | 'reg7' )
;

IntegerVariableDeclaration:
    section = SectionServiceWord? name=ID ':' type = IntegerType ('[' size = IntValue ']')? ( value = IntegerVariableDefinition )? ';'
;

ID is a standart terminal which parses a single word, a.k.a identifier

Upvotes: 0

Views: 342

Answers (2)

ScalewingedAcidicorn
ScalewingedAcidicorn

Reputation: 549

In addition to Fabien's answer, I'd like to add that an omnimatching rule like

AnyId:
    name = ID
;

instead of

 (Register|[IntegerVariableDeclaration])

solves the problem. One need to dynamically check if AnyId.name is a Regiser, Variable or something else like Constant.

Upvotes: 0

Fabien Fleureau
Fabien Fleureau

Reputation: 693

  1. No, (Register|[IntegerVariableDeclaration]) can't match Empty. Actually, [IntegerVariableDeclaration] is the same than [IntegerVariableDeclaration|ID], it is matching ID rule.

  2. Yes, i think you can't split your rules.

  3. I can't reproduce your problem (i need full grammar), but, in order to solve your problem you should look at this article about xtext grammar debugging:

    • Compile grammar in debug mode by adding the following line into your workflow.mwe2
      fragment = org.eclipse.xtext.generator.parser.antlr.DebugAntlrGeneratorFragment {}

    • Open generated antrl debug grammar with AntlrWorks and check the diagram.

Upvotes: 1

Related Questions