Xtext为表达式创建详细的错误消息:如何获取语法错误的规则跟踪?

时间:2015-02-01 19:03:38

标签: antlr xtext

我正在尝试扩展SyntaxErrorMessageProvider以覆盖语法错误消息但是我不知道如何获取调用此语法错误的规则的堆栈跟踪:

class MySyntaxErrorMessageProvider extends SyntaxErrorMessageProvider {
    def override SyntaxErrorMessage getSyntaxErrorMessage(ISyntaxErrorMessageProvider.IParserErrorContext context) {
        if(context.recognitionException != null) {
            handle(context.recognitionException)
        } else {
            handleException(context)
        }

我想要实现的是例如给出以下文字:

1. 1 +

2. 1 + +

3. 1 1

4. 1 1 +

错误消息应该是并提供以下quickfix选项:

1. 1 + is an incomplete expression, mainly + has no right hand operand

2. 1 + + is an incomplete expression, mainly 1 + in (1 +) + has no right operand or expression and + in 1 + (+) has no left or right operands or expressions

这些选项的快速修正可以是(添加或删除):

1. Remove the + or Add in an expression

2. Add in an operand/expression for both ends of + or remove leftmost token.

我正在努力寻找使用Xtext api的方法。我得到了错误解析的INode,但是当我使用.getAsTreeIterable()遍历树时,我从这些节点得到的并不是完整的输入。它只显示在模型中有效的文本。

  1. 我是否必须在语法中添加一些错误规则来捕获这些不正确的情况,以便能够使用INode接口识别它们?

  2. 输入:

    badinput = 1 + 2 + +

  3. 我得到以下节点:

    Start....
    
    Defsym_exprImpl@153802c5 (defSymbolName: badinput)
    
    AdditionImpl@1dc74ee0
    
    AdditionImpl@2335d787
    
    INTEGER_CONSTANTImpl@19816081 (value: 1)
    
    INTEGER_CONSTANTImpl@4cfa675e (value: 2)
    
    UNARY_PLUSImpl@6bed906f
    
    End....
    

    我可以迭代它们并检查它们的某些相应值是否为空,这是正确的前进方式吗?

    有人提出更多建议吗?

    我的实现语法如下:

        Expression returns Expression:
        Assignment
    ;
    
    Assignment returns Expression:
        Ternary (
                ( ({AndEquals.left=current} AND EQUALS)
                | ({OrEquals.left=current} OR EQUALS)
                | ({PlusEquals.left=current} PLUS EQUALS)
                | ({MinusEquals.left=current} MINUS EQUALS)
                | ({MultiplyEquals.left=current} MULTIPLY EQUALS)
                | ({DivideEquals.left=current} DIVIDE EQUALS)
                | ({Equals.left=current} EQUALS)
                | ({LeftShiftEquals.left=current} LEFT_SHIFT EQUALS)
                | ({RightShiftEquals.left=current} RIGHT_SHIFT EQUALS)
                )
            right=Ternary
        )*
    ;
    
    Ternary returns Expression:
         OrOr ({Ternar.left=current} SEMICOLON rightTrue=OrOr QUESTION rightFalse=OrOr)*
    ;
    
    OrOr returns Expression:
        AndAnd ({OrOr.left=current} OR_OR right=AndAnd)*
    ;
    
    AndAnd returns Expression:
        BitwiseOr ({AndAnd.left=current} AND_AND right=BitwiseOr)*
    ;
    
    BitwiseOr returns Expression:
        BitwiseXOR ({Or.left=current} OR right=BitwiseXOR)*
    ;
    
    BitwiseXOR returns Expression:
        BitwiseAnd ({XOr.left=current} XOR right=BitwiseAnd)*
    ;
    
    BitwiseAnd returns Expression:
        Comparisons ({And.left=current} AND right=Comparisons)*
    ;
    
    Comparisons returns Expression:
        Shifting (( ( {EqualsEquals.left=current} EQUALS_EQUALS) 
                 | ( {NotEquals.left=current} NOT_EQUALS)
                 | ( {GreaterThan.left=current} GREATER_THAN)
                 | ( {LessThan.left=current} LESS_THAN)
                 | ( {LessThanEquals.left=current} LESS_THAN_EQUALS)
                 | ( {GreaterEquals.left=current} GREATER_EQUALS)
                 )
                 right=Shifting
        )*
    ;
    
    Shifting returns Expression:
        AdditionOrSubtraction (  ( {LeftShift.left=current} LEFT_SHIFT 
                                 | {RightShift.left=current} RIGHT_SHIFT
                                 ) right=AdditionOrSubtraction)*
    ;
    
    AdditionOrSubtraction returns Expression:
        MultiplicationOrDivision (   ( {Addition.left=current} PLUS 
                                     | {Subtraction.left=current} MINUS
                                   ) (right=MultiplicationOrDivision))*
    ;
    
    MultiplicationOrDivision returns Expression: 
        UnaryOperations ( ( {Multiplication.left=current} MULTIPLY 
                          | {Division.left=current} DIVIDE 
                          | {Modulus.left=current} MOD
                          ) right=UnaryOperations)*
    ;
    
    UnaryOperations returns Expression:
        ({UNARY_MINUS} MINUS value=UnaryOperations)
        /* +(1 + 2) is not supported in the original LD*/
        | ({UNARY_PLUS} PLUS value=UnaryOperations)
        | ({UNARY_BITWISE_NOT} BITWISE_NOT value=UnaryOperations)
        | ({UNARY_LOGICAL_NOT} LOGICAL_NOT value=UnaryOperations)
        | Primary
    ;
    
    Primary returns Expression:
        RecursiveExpressions
        | AtomicExpressions
        | Constants
        | Atom
    ;
    
    RecursiveExpressions returns Expression:
        OPEN_BRACKET Expression CLOSE_BRACKET
        | {NEXT_BUILT_IN} NEXT OPEN_BRACKET value=Expression CLOSE_BRACKET
        | {LOG2CEIL_BUILT_IN} LOG2CEIL OPEN_BRACKET value=Expression CLOSE_BRACKET
        | {ABSOLUTE_BUILT_IN} ABSOLUTE OPEN_BRACKET value=Expression CLOSE_BRACKET
        | {ALIGN_BUILT_IN} ALIGN OPEN_BRACKET left=Expression (COMMA right=Expression)? CLOSE_BRACKET
        | {SEGMENT_ALIGN_BUILT_IN} DATA_SEGMENT_ALIGN OPEN_BRACKET left=Expression COMMA right=Expression CLOSE_BRACKET
        | {SEGMENT_RELRO_END_BUILT_IN} DATA_SEGMENT_RELRO_END OPEN_BRACKET left=Expression COMMA right=Expression CLOSE_BRACKET
        | {SEGMENT_BUILT_IN} DATA_SEGMENT_END OPEN_BRACKET value=Expression CLOSE_BRACKET
        | {START_BUILT_IN} SEGMENT_START OPEN_BRACKET name=ID COMMA value=Expression CLOSE_BRACKET
        | {BLOCK_BUILT_IN} BLOCK OPEN_BRACKET value=Expression CLOSE_BRACKET
        | {MAX_DOUBLE_BUILT_IN} MAX OPEN_BRACKET left=Expression COMMA right=Expression CLOSE_BRACKET
        | {MIN_DOUBLE_BUILT_IN} MIN OPEN_BRACKET left=Expression COMMA right=Expression CLOSE_BRACKET
        | {ASSERT_E_BUILT_IN} ASSERT OPEN_BRACKET value=Expression COMMA name=ID CLOSE_BRACKET
    ;
    
    Constants returns Expression:
        /* Constants */
        {COUNTER} LOCATION_COUNTER
        | {SIZE_OF_HEADER} SIZEOF_HEADERS   
    ;
    
    AtomicExpressions returns Expression:
        {ATOMIC_DEFINED} DEFINED OPEN_BRACKET value=ID CLOSE_BRACKET
        | {ATOMIC_ALIGN_OF} ALIGN_OF OPEN_BRACKET value=ID CLOSE_BRACKET
        | {ATOMIC_SIZE_OF} SIZEOF OPEN_BRACKET value=ID CLOSE_BRACKET
        | {ATOMIC_ADDR} ADDR OPEN_BRACKET value=ID CLOSE_BRACKET
        | {ATOMIC_LOAD_ADDR} LOADADDR OPEN_BRACKET value=ID CLOSE_BRACKET
        | {ATOMIC_CONSTANT} CONSTANT OPEN_BRACKET value=ID CLOSE_BRACKET
        | {ATOMIC_ORIGIN} ORIGIN OPEN_BRACKET value=ID CLOSE_BRACKET
        | {ATOMIC_LENGTH} LENGTH OPEN_BRACKET value=ID CLOSE_BRACKET    
    ;
    
    Atom returns Expression:
        {INTEGER_CONSTANT} value=INT
    ;
    

    我是否需要添加以下规则?

    1. 1 +
    
    2. 1 + +
    
    3. 1 1
    
    4. 1 1 +
    

    案例1可由直接AST

    处理

    案例2:

    Operators:
       '+' | '-' | '*' | '/' etc...;
    
    AdditionOrSubtraction returns Expression:
        MultiplicationOrDivision (   ( {Addition.left=current} PLUS 
                                     | {Subtraction.left=current} MINUS
                                     ) 
                                     (right=MultiplicationOrDivision)
                                     | Operators  /* however how do I flag/paraphrase this to be of type Error of some sort? this may also be ambiguous grammar */
                                 )*
    ;
    

    对于案例3,我不知道案件4似乎很难。

1 个答案:

答案 0 :(得分:1)

查看node

的字段tokenRecognitionException