How do syntax predicates work?

The Xtext documentation, such as here: http://www.eclipse.org/Xtext/documentation.html#syntax , just seems to explain syntactic predicates, giving one example of "spoof another problem." My naive interpretation of this would be the following: if you have an ambiguous grammar, use => to select the option you want. However, the results that I get say that it is more complicated than there, is there a better explanation somewhere? To try to understand what was going on, I came up with this simple but ambiguous grammar to experiment with (obviously, I would not do it this way in the real world):

grammar com.euclideanspace.experiment.Mydsl with org.eclipse.xtext.common.Terminals generate mydsl "http://www.euclideanspace.com/experiment/Mydsl" Model: opt=Option; Option: (ID Option1 ID) | (ID Option2 ID) ; Option1: '=='|'+='; Option2: '=='|'-='; 

This gives the following warnings:

 warning(200): ../com.euclideanspace.experiment/src-gen/com/euclideanspace/experiment/parser/antlr/internal/InternalMydsl.g:119:1: Decision can match input such as "RULE_ID '==' RULE_ID" using multiple alternatives: 1, 2 As a result, alternative(s) 2 were disabled for that input warning(200): ../com.euclideanspace.experiment.ui/src-gen/com/euclideanspace/experiment/ui/contentassist/antlr/internal/InternalMydsl.g:176:1: Decision can match input such as "RULE_ID '==' RULE_ID" using multiple alternatives: 1, 2 As a result, alternative(s) 2 were disabled for that input 

The grammar is ambiguous because input such as 'a == b' may match using Option1 or Option2. We can remove this warning by adding a syntax predicate indicated by '=>' before the option we want to select for potentially ambiguous input.

 Option: (ID Option1 ID) | =>(ID Option2 ID) ; 

We could also put a syntactic predicate inside the bracket as follows:

 Option: (ID Option1 ID) | (=>ID Option2 ID) ; 

Both of these posts work, and which is better? I don’t understand how the second case works, choosing one identifier in preference to another, also implies Option2 over Option1. However, if we put a syntactic predicate in front of Option2 (which seems to make sense, since this is the option we want to select), we get the warning below:

 Option: (ID Option1 ID) | (ID =>Option2 ID) ; 

warning (200): ../ com.euclideanspace.experiment / src-gen / com / euclideanspace / experiment / parser / antlr / internal / InternalMydsl.g: 119: 1: The solution can match the input, for example, "RULE_ID" == 'RULE_ID' using several alternatives: 1, 2 As a result, alternative 2 was disabled for this input

So, this is not just a case of placing a syntactic predicate before the selection we want to select. I think I need to understand how the parser scans the grammar so that we know where to cut unnecessary options.

Is there an explanation of syntactic predicates explaining the above problems? How can syntactic predicates be hidden by actions?

Martin

+5
source share
1 answer

Alternatives with a predicate must be listed before an alternative without a predicate. For instance. your rule Option should look something like this:

 Option: ID =>Option2 ID) | ID Option1 ID; 

Note that the token '==' will never be used as part of Option1 in this case, since it will always be Option2. You may want to reorganize your grammar to remove a duplicate branch, which in the first place will save you from using predicates.

+1
source

Source: https://habr.com/ru/post/1200480/


All Articles