Xtext语法错误“决策可以匹配输入...使用多个替代方案:1,3,4,5”

时间:2013-12-29 23:47:31

标签: parsing antlr grammar xtext

我遇到了我的xtext语法定义。基本上我喜欢为组件定义多个参数。该组件应包含至少一个参数定义paramAparamBparamC OR(paramA AND paramB)OR(paramB AND {{ 1}})或(paramC AND paramAparamB)。

总的来说,这6个案例,你可以在我的语法定义中看到

paramC

以下是我减少语法时的工作仅使用Component: 'Define available parameters:' ( (newParamA = ParamA | newParamB = ParamB | newParamC = ParamC) | (newParamA = ParamA & newParamB = ParamB) | (newParamA = ParamA & newParamC = ParamC) | (newParamB = ParamB & newParamC = ParamC) | (newParamA = ParamA & newParamB = ParamB & newParamC = ParamC) ) ; ParamA: ('paramA = ' paramA=Integer ';'); ParamB: ('paramB = ' paramB=Integer ';'); ParamC: ('paramC = ' paramC=Integer ';'); // Datatype Integer returns ecore::EIntegerObject: '-'? INT; ,意味着第一个代码段中没有其他情况:

(newParamA = ParamA | newParamB = ParamB | newParamC = ParamC)

但我希望能够在我的dsl中定义多个可用的参数,例如

Define available parameters:
    paramA = 1;
...
Define available parameters:
    paramB = 2;
...
Define available parameters:
    paramC = 3;

知道如何解决这个问题吗?希望你能帮助我,我很感激任何帮助!

这是从代码段#1生成语法时遇到的错误:

Define available parameters:
    paramA = 1; paramB = 2;
...
Define available parameters:
    paramB = 2; paramC = 3;
...
Define available parameters:
    paramA = 1; paramB = 2; paramC = 3;

以下是我尝试过的解决方法(可行)但它不是解决方案,因为语言中的关键字正在发生变化以避免解析器错误:

warning(200): ../my.packagename/src-gen/my/packagename/projectname/parser/antlr/internal/InternalMyDSL.g:722:1: Decision can match input such as "'paramC = ' '-' RULE_INT ';'" using multiple alternatives: 1, 3, 4, 5
As a result, alternative(s) 3,5,4 were disabled for that input
Semantic predicates were present but were hidden by actions.

...

4514 [main] ERROR enerator.CompositeGeneratorFragment  - java.io.FileNotFoundException: ..\my.packagename.ui\src-gen\my\packagename\projectname\ui\contentassist\antlr\internal\InternalMyDSLParser.java (The system cannot find the file specified)
org.eclipse.emf.common.util.WrappedException: java.io.FileNotFoundException: ..\my.packagename.ui\src-gen\my\packagename\projectname\ui\contentassist\antlr\internal\InternalMyDSLParser.java (The system cannot find the file specified)
    at org.eclipse.xtext.util.Files.readFileIntoString(Files.java:129)
    at org.eclipse.xtext.generator.parser.antlr.AbstractAntlrGeneratorFragment.simplifyUnorderedGroupPredicates(AbstractAntlrGeneratorFragment.java:130)
    at org.eclipse.xtext.generator.parser.antlr.AbstractAntlrGeneratorFragment.simplifyUnorderedGroupPredicatesIfRequired(AbstractAntlrGeneratorFragment.java:118)
    at org.eclipse.xtext.generator.parser.antlr.XtextAntlrUiGeneratorFragment.generate(XtextAntlrUiGeneratorFragment.java:86)

2 个答案:

答案 0 :(得分:2)

我认为您真正想要的是一种验证,确保在语义级别而不是句法级别上至少给出一个参数。这将大大简化您的语法,例如您可以使用

(newParamA = ParamA)? & (newParamB = ParamB)? & (newParamC = ParamC)?

(为了清楚起见,添加了父母)

另请注意,避免关键字中的空格通常是个好主意。您应该更喜欢'paramA' '='而不是'paramA ='。这将大大改善词法分析器/解析器中的错误处理。

答案 1 :(得分:1)

你想要做的是这样的事情:

你想要一个简单的语法(正如塞巴斯蒂安所描述的那样):

(newParamA = ParamA)? & (newParamB = ParamB)? & (newParamC = ParamC)?

要确保至少需要一个参数,您可以编写自己的验证器,如下所示:

class MyDSLValidator extends AbstractMyDSLValidator {
    @Check
    def void atLeastOneParameter(Component component) {
        if (component.newParamA == null && component.newParamB == null && component.newParamC == null) {
            error('requires at least one parameter definition', MyDSLPackage.Literals.COMPONENT__PARAMA);
        }
    }
}