如何在单个规则中指定多个词法分析器规则?

时间:2020-02-10 14:49:43

标签: antlr antlr4 language-recognition

我有以下解析器规则:

declaration     : (KW_VARIABLE DT_IDENTIFIER) |
                  (KW_VARIABLE DT_IDENTIFIER OP_ASSIGNMENT DT_DATA_TYPES) OP_SEMICOLON;

和以下词法分析器规则:

KW_VARIABLE     : 'var';

OP_ASSIGNMENT   : '=';
OP_SEMICOLON    : ';';

DT_IDENTIFIER   : [a-z]+;
DT_INTEGER      : [0-9]+;
DT_DATA_TYPES   : (DT_IDENTIFIER | DT_INTEGER);

使用上述规则,我希望能够编写以下代码:

var a = 10;
var b = 40;
var c = 50;
var d = c;

我用于退出声明的侦听器代码如下:

public override void ExitDeclaration([NotNull] PyroParser.DeclarationContext context)
{
    bool isAssigned = context.OP_ASSIGNMENT() != null;

    if (!isAssigned)
    {
        return;
    }

    Console.WriteLine(context.DT_DATA_TYPES().GetText());
    base.ExitDeclaration(context);
}

我在运行第一行时说:

第1:8行的输入“ 10”不匹配,预期为DT_DATA_TYPES

我只想能够在一个规则中引用所有数据类型,我该怎么做?

1 个答案:

答案 0 :(得分:2)

这是不正确的:

DT_IDENTIFIER   : [a-z]+;
DT_INTEGER      : [0-9]+;
DT_DATA_TYPES   : (DT_IDENTIFIER | DT_INTEGER);

一旦DT_IDENTIFIERDT_INTEGER被匹配,它将永远不会成为DT_DATA_TYPES。词法分析器从上到下匹配规则,一旦找到匹配项,它就不会放弃。只需更改规则的顺序即可:

DT_DATA_TYPES   : (DT_IDENTIFIER | DT_INTEGER);
DT_IDENTIFIER   : [a-z]+;
DT_INTEGER      : [0-9]+;

也不起作用:这样,词法分析器将永远不会产生DT_IDENTIFIERDT_INTEGER令牌。

您可以改为执行以下操作:

dt_data_types   : (DT_IDENTIFIER | DT_INTEGER);

DT_IDENTIFIER   : [a-z]+;
DT_INTEGER      : [0-9]+;
相关问题