eclipseeclipse-pluginm2eclipsextextxbase

Error highlights in every line when grammar breaks somewhere in Xtext editor


public class FirstExample { // Here in this example we define some properties in our class

WRITE // This WRITE command follows a rule type defined in my grammar
Hello World
private
String firstTitle ;
private
String secondTitle ;
private
Integer firstAmount ;
private
Integer secondAmount ;
SET
firstTitle = "Ramesh"
SET
secondTitle = "Suresh"
SET
firstAmount = 100
SET
secondAmount = 200 

When I change the command 'WRITE' to 'WRITEE' then error highlights in every line. In eclipse java editor when we write a wrong syntax then error shows on that line only. I am searching solution for this issue for past 2 days but not able to find the solution. Kindly help me.I am not able to upload the picture due to some 10 reputation message comes while posting the question..

I am sending the grammar.Kindly check it once.

grammar org.xtext.example.mydsl.MyPoc with org.eclipse.xtext.common.Terminals  hidden (GUESS_COMMENT,WS)

generate myPoc "http://www.xtext.org/example/mydsl/MyPoc"

Domainmodel:
    (elements+=Type)*;

Type:Class;

// This is the starting point of the grammar
 Class:
    (packageList+=packageList)*
    (packageList+=Import)*
    (directives+=Directives) 'class' name=ID ('extends' superType=[Class])? '{'
    (greetings+=Greeting)*
    (features+=Feature)*
    setValues+=SetValues*
    operations+=Operation*
    functionCall+=ArithmeticOperation*
    directives+=Directive*
    allMethod+=AllMethod*
    allMethodInClass+=AllMethodInClass*
    samples+=Samples*
    '}'; 

//Package list consist of all the packages we want to include in our class  
 packageList:
    ('package' name=ID) ('.'?) (classes+=[Class])?;

//Import list consist of all the packages we want to include in our class  
 Import:
    'import' importedNamespace=QualifiedNameWithWildcard;

QualifiedNameWithWildcard:
    'QualifiedName' '.*'?;

Greeting: 
(directives+=Directives)'Hello World'';'
(directives+=Directives)?'bye'?';'
(directives+=Directives)?';'
;

// Features defines the properties of that class 
// In our grammar by default we make the property private
// our grammar takes two types of DataType String or Integer 
// Name of the property given as per rule ID defined in Terminal file
Feature:
    (directives+=Directives)* type=DATA_TYPE name=ID ';';

    // In SetValues we initialize the properties by using SET directive
SetValues:
    (directives+=Directives) name=ID ('='?) (INT | STRING)';';

    //In Operation we define the function,arguments with there Data Type  
Operation:
    'Do' name=ID ('(' types+=DATA_TYPE args+=ID (',' types+=DATA_TYPE
    args+=ID)* ')')?';';

    //In Arithmetic Operation we call the function using $ passing the parameters
ArithmeticOperation:
    (directives+=Directives)? name=ID '=' (directives+=Directives)? ('$')? types+=[Operation] ('(' (args+=ID) ','
    (args+=ID)* ')')?';';

    //In Samples we use Do While loop and inside that loop we use if else block     
Samples:
    name=ID (directives+=Directives) ('!,' STRING)? loopConstruct+=LoopConstruct* operations+=Operation*;

    // In AllMethod we can call any method by using class name with '.' operator  
AllMethod:
    (classes+=[Class]) "." types+=[Operation] ('(' (args+=INT | ID) ',' (args+=INT | ID)* ');')?;

    // In AllMethodInClass we can see all methods present in that class
AllMethodInClass:
    types+=[Operation] ('(' (args+=INT | ID) ',' (args+=INT | ID)* ');')?;

//In LoopConstruct we define how we can use Do while loop with directive types given below
LoopConstruct:
    (directives+=Directives) ("{"
    (directives+=Directives ('!,' STRING))*
    (directives+=Directive)*
    "}")
    (directives+=Directives) ("{"
    (directives+=Directives ('!,' STRING))*
    (directives+=Directive)*
    "}")?
    (directives+=Directives)?;

Directive:
    (directives+=Directives) ('(' name=ID LOOP_CODITION_CHECK name=ID ')')?
    '{' (directives+=Directives ('!,' STRING)?)* '}';

Directives:
    name=DirectiveType;

DirectiveType:
    {DirectiveType} value=DIRECTIVES_TYPE;

    // From here all are rules which shows that what we can use in our grammar 
terminal DATA_TYPE:
    ('Integer' | 'String');

// These are some directives
// WRITE is following this rule
terminal DIRECTIVES_TYPE:
    ('SET' | 'WRITE' | 'READ' | 'QUIT' | 'If' | 'ElseIf' | 'Else' | 'EndIf' | 'Do' | 'while' | 'private' | 'public' | 'do');

terminal LOOP_CODITION_CHECK:
    ('=' | '>' | '<' | '!')+;

terminal GUESS_COMMENT : '//' !('\n'|'\r')* ('\r'? '\n');

I want to make it clear that WRITE is not only the issue.The line from where grammar breaks it shows error on the remaining lines comes after that line.

After changing my class rule with your code it gives lots of warning.I am sending the warning messages.

warning(200): ../org.xtext.example.myPoc/src-gen/org/xtext/example/mydsl/parser/antlr/internal/InternalMyPoc.g:416:2: Decision can match input such as "RULE_ID {RULE_ID..RULE_DATA_TYPE, RULE_DIRECTIVES_TYPE, 'Do'}" using multiple alternatives: 8, 9
As a result, alternative(s) 9 were disabled for that input
error(201): ../org.xtext.example.myPoc/src-gen/org/xtext/example/mydsl/parser/antlr/internal/InternalMyPoc.g:416:2: The following alternatives can never be matched: 9

warning(200): ../org.xtext.example.myPoc/src-gen/org/xtext/example/mydsl/parser/antlr/internal/InternalMyPoc.g:1166:1: Decision can match input such as "RULE_DIRECTIVES_TYPE '{' RULE_DIRECTIVES_TYPE '!,' RULE_STRING '}' RULE_DIRECTIVES_TYPE" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): ../org.xtext.example.myPoc/src-gen/org/xtext/example/mydsl/parser/antlr/internal/InternalMyPoc.g:1184:1: Decision can match input such as "'Do' RULE_ID '(' RULE_DATA_TYPE RULE_ID ',' RULE_DATA_TYPE RULE_ID ')' ';'" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): ../org.xtext.example.myPoc/src-gen/org/xtext/example/mydsl/parser/antlr/internal/InternalMyPoc.g:1546:3: Decision can match input such as "RULE_DIRECTIVES_TYPE" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): ../org.xtext.example.myPoc.ui/src-gen/org/xtext/example/mydsl/ui/contentassist/antlr/internal/InternalMyPoc.g:568:1: Decision can match input such as "RULE_ID {RULE_ID, RULE_DATA_TYPE..RULE_DIRECTIVES_TYPE, '}', 'Do'..'('}" using multiple alternatives: 8, 9
As a result, alternative(s) 9 were disabled for that input
error(201): ../org.xtext.example.myPoc.ui/src-gen/org/xtext/example/mydsl/ui/contentassist/antlr/internal/InternalMyPoc.g:568:1: The following alternatives can never be matched: 9

warning(200): ../org.xtext.example.myPoc.ui/src-gen/org/xtext/example/mydsl/ui/contentassist/antlr/internal/InternalMyPoc.g:2810:42: Decision can match input such as "RULE_DIRECTIVES_TYPE '{' RULE_DIRECTIVES_TYPE '!,' RULE_STRING '}' RULE_DIRECTIVES_TYPE" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): ../org.xtext.example.myPoc.ui/src-gen/org/xtext/example/mydsl/ui/contentassist/antlr/internal/InternalMyPoc.g:2838:39: Decision can match input such as "'Do' RULE_ID '(' RULE_DATA_TYPE RULE_ID ',' RULE_DATA_TYPE RULE_ID ')' ';'" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): ../org.xtext.example.myPoc.ui/src-gen/org/xtext/example/mydsl/ui/contentassist/antlr/internal/InternalMyPoc.g:3561:1: Decision can match input such as "RULE_DIRECTIVES_TYPE" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input

After the warning code gives an exception

 GeneratorException: (Element: -UNKNOWN-; Reported by: Generator)
     org.eclipse.emf.common.util.WrappedException: java.io.FileNotFoundException: ..\org.xtext.example.myPoc\src-gen\org\xtext\example\mydsl\parser\antlr\internal\InternalMyPocLexer.java (The system cannot find the file specified)

I have reduced my grammar and remove all the error and warnings from my code but the error highlighting in every line is still there. Now my grammar is

grammar org.xtext.example.mydsl.MyPoc with org.eclipse.xtext.common.Terminals  hidden (GUESS_COMMENT,WS)

generate myPoc "http://www.xtext.org/example/mydsl/MyPoc"

Domainmodel:
    (elements+=Type)*;

Type:Class;

// This is the starting point of the grammar
 Class:
    (packageList+=packageList)*
    (packageList+=Import)*
    (directives+=Directives) 'class' name=ID ('extends' superType=[Class])? '{'
    (greetings+=Greeting 
    |features+=Feature 
    |setValues+=SetValues)*
    '}'; 


//Package list consist of all the packages we want to include in our class  
 packageList:
    ('package' name=ID) ('.'?) (classes+=[Class])?;

//Import list consist of all the packages we want to include in our class  
 Import:
    'import' importedNamespace=QualifiedNameWithWildcard;

QualifiedNameWithWildcard:
    'QualifiedName' '.*'?;

Greeting: 
(directives+=Directives)'Hello World'';'
(directives+=Directives)?'bye'?';'
(directives+=Directives)?';'
;

// Features defines the properties of that class 
// In our grammar by default we make the property private
// our grammar takes two types of DataType String or Integer 
// Name of the property given as per rule ID defined in Terminal file
Feature:
    (directives+=Directives)* type=DATA_TYPE name=ID ';';

    // In SetValues we initialize the properties by using SET directive
SetValues:
    (directives+=Directives) name=ID ('='?) (INT | STRING)';';

Directives:
    name=DirectiveType;

DirectiveType:
    {DirectiveType} value=DIRECTIVES_TYPE;

    // From here all are rules which shows that what we can use in our grammar 
terminal DATA_TYPE:
    ('Integer' | 'String');

// These are some directives used by us taken from there website
terminal DIRECTIVES_TYPE:
    ('SET' | 'WRITE' | 'READ' | 'QUIT' | 'If' | 'ElseIf' | 'Else' | 'EndIf' | 'Do' | 'while' | 'private' | 'public' | 'do');

terminal LOOP_CODITION_CHECK:
    ('=' | '>' | '<' | '!')+;

terminal GUESS_COMMENT : '//' !('\n'|'\r')* ('\r'? '\n');

And in eclipse xtext editor when I write private as privatee it shows error in every line. My code is

public
class MyPoc {
    private
    String firstTitle ;
    **privatee**
    String title ;
    private
    String secondTitle ;
    private
    Integer firstAmount ;
    private
    Integer secondAmount ;
    SET
    firstTitle = "Ramesh";
    SET
    secondTitle = "Suresh";
    SET
    firstAmount = 100;
    SET
    secondAmount = 200; 

}

Now I add some more grammar in my class attribute.The console shows no warning and no exception.But in eclipse editor again when we break grammar syntax it shows error in every line.

Class:
    (packageList+=packageList)*
    (packageList+=Import)*
    (directives+=Directives) 'class' name=ID ('extends' superType=[Class])? LBRACKET
    (directives+=Directives* (features+=Feature | setValues+=SetValues | operations+=Operation | functionCall+=ArithmeticOperation | allMethod+=AllMethod
    | allMethodInClass+=AllMethodInClass | samples+=Samples) SEMICOLON)*
    RBRACKET;

Kindly check it once and correct me if I am doing something wrong.

I have found that problem is not in the class part.The problem is in the parts where we define the rule in the grammar. Like for ArithmeticOperation ArithmeticOperation:

(directives+=Directives)? name=ID '=' (directives+=Directives)? ('$')? types+=[Operation] ('(' (args+=ID) ',' (args+=ID)* ')')?';';

Actually I have to write this code in eclipse.Here Concat is the opeartion name means method name.

SET Result = WRITE $ Concat (firstTitle , secondTitle)

Kindly correct me if I ma doing something wrong to achieve my target code.

Regards


Solution

  • Xtext error recovery system is not the same than Java Editor (JDT). Its behavior depends on how you write your rules. Maybe your grammar is too much ambiguous and you should add a line termination symbol.

    Also, you should read this article about error recovery with Xtext: Parser error recovery

    Edit

    Currently the class rule is very ambiguous with chaining rules with the same first token. The first thing you should do is to rewrite your class rule and remove all ambiguities.(warnings & erros when compiling grammar). See the following example of class rule:

     Class:
        (packageList+=packageList)*
        (packageList+=Import)*
        (directives+=Directives) 'class' name=ID ('extends' superType=[Class])? '{'
        (greetings+=Greeting | features+=Feature | setValues+=SetValues
            | operations+=Operation | functionCall+=ArithmeticOperation
            | directives+=Directive | allMethod+=AllMethod
            | allMethodInClass+=AllMethodInClass | samples+=Samples)*
        '}';
    

    Edit 2 I made some refactorings to your grammar. And now it has the behavior you asked for.

        Domainmodel:
        (elements+=Type)*;
    
    Type:Class;
    
    // This is the starting point of the grammar
         Class:
            (packageList+=packageList)*
            (packageList+=Import)*
            (directives+=Directives) 'class' name=ID ('extends' superType=[Class])? LBRACKET
            (directives+=Directives* (features+=Feature | setValues+=SetValues) SEMICOLON)*
            RBRACKET; 
    
    
        terminal SEMICOLON:
            ';'
        ;
    
        terminal LBRACKET:
            '{'
        ;
    
        terminal RBRACKET:
            '}'
        ;
    
    //Package list consist of all the packages we want to include in our class  
     packageList:
        ('package' name=ID) ('.'?) (classes+=[Class])?;
    
    //Import list consist of all the packages we want to include in our class  
     Import:
        'import' importedNamespace=QualifiedNameWithWildcard;
    
    QualifiedNameWithWildcard:
        'QualifiedName' '.*'?;
    
    
    // Features defines the properties of that class 
    // In our grammar by default we make the property private
    // our grammar takes two types of DataType String or Integer 
    // Name of the property given as per rule ID defined in Terminal file
    Feature:
       type=DATA_TYPE name=ID ;
    
        // In SetValues we initialize the properties by using SET directive
    SetValues:
        name=ID ('='?) (INT | STRING);
    
    Directives:
        name=DirectiveType;
    
    DirectiveType:
        {DirectiveType} value=DIRECTIVES_TYPE;
    
        // From here all are rules which shows that what we can use in our grammar 
    terminal DATA_TYPE:
        ('Integer' | 'String');
    
    // These are some directives used by us taken from there website
    terminal DIRECTIVES_TYPE:
        ('SET' | 'WRITE' | 'READ' | 'QUIT' | 'If' | 'ElseIf' | 'Else' | 'EndIf' | 'Do' | 'while' | 'private' | 'public' | 'do');
    
    terminal LOOP_CODITION_CHECK:
        ('=' | '>' | '<' | '!')+;
    
    terminal GUESS_COMMENT : '//' !('\n'|'\r')* ('\r'? '\n');
    

    Details of what i changed: - Removed (useless?) greeting rule. - Made line/block separators terminals. - Moved directive to parent rule.

    Sample code for editor:

    public
    class MyPoc {
        private
        String firstTitle ;
        privatee
        String title ;
        private
        String secondTitle ;
        private
        Integer firstAmount ;
        private
        Integer secondAmount ;
        SET
        firstTitle = "Ramesh";
        SET
        secondTitle = "Suresh";
        SET
        firstAmount = 100;
        SET
        secondAmount = 200; 
    }