xtext:如何格式化块需要缩进的代码

时间:2016-10-06 20:23:51

标签: formatting xtext

我的语法由:

Model:
    'module' (mn=ID)?
        (func+=Function)+
    'end_module'
;

Function:
    'function' name=ID '('')'
        (vars+=ID)*
    'end_function'
;

我可以找到令牌,如'功能','('等等。

  • 如何在令牌'模块之后强制换行?如果可选数据mn不存在,那么在mn之后它是否存在?
  • 如何缩进块开始'模块'和' end_module'以及'功能'和' end_function'?

我正在寻找的格式:

module test
  function fdf ()
    str1
    str2
  end_function

  function ff ()
  end_function
end_module

到目前为止,我通过使用以下方法生成格式化存根:     formatter = {         generateStub = true     }

2 个答案:

答案 0 :(得分:3)

应该相当直接,例如

@Inject extension MyDslGrammarAccess

def dispatch void format(Model model, extension IFormattableDocument document) {
    model.regionFor.keyword(modelAccess.end_moduleKeyword_3).prepend[newLine] 
    if (model.mn != null) {
        model.regionFor.feature(MyDslPackage.Literals.MODEL__MN).append[newLine]
        interior(
            model.regionFor.feature(MyDslPackage.Literals.MODEL__MN), 
            model.regionFor.keyword(modelAccess.end_moduleKeyword_3)
        ) [indent]
    } else {
        model.regionFor.keyword(modelAccess.moduleKeyword_0).append[newLine]
        interior(
            model.regionFor.keyword(modelAccess.moduleKeyword_0),
            model.regionFor.keyword(modelAccess.end_moduleKeyword_3)
        ) [indent]
    }
    for (Function func : model.getFunc()) {
        func.format;
    }
}

def dispatch void format(Function function, extension IFormattableDocument document) {
    function.regionFor.keyword(functionAccess.functionKeyword_0).append[newLine].prepend[newLine]
    function.regionFor.keyword(functionAccess.end_functionKeyword_5).prepend[newLine]
    interior(
        function.regionFor.keyword(functionAccess.functionKeyword_0),
        function.regionFor.keyword(functionAccess.end_functionKeyword_5)
    ) [indent]
}

答案 1 :(得分:1)

正如Max's Answer中提出的那样,从Xtext v2.8开始,可以应对空格感知语言。 Check it out!

在你的情况下,我猜你应该按如下方式定义你的语法:

Model:
    'module' (mn=ID)?
    BEGIN
        (func+=Function)+
    END
    'end_module'
;

Function:
    'function' name=ID '('')'
    BEGIN
        (vars+=ID)*
    END
    'end_function'
;

terminal BEGIN: 'synthetic:BEGIN';
terminal END: 'synthetic:END';

如果您还想允许“空身”'函数,我想你应该改变上面的规则如下:

Function:
    'function' name=ID '('')'
    (BEGIN
         (vars+=ID)*
    END)?
    'end_function'
;

希望它有所帮助!