无法使用antlr4

时间:2017-06-06 21:36:18

标签: parsing grammar antlr4

我正在使用antlr4来解析文件并且似乎遇到了一个问题,这个问题让我现在几个小时都处于清醒状态。以下是我在ESQLGrammar.g4文件中定义的简单语法,即放在我的项目src / main / antlr4。

grammar ESQLGrammar;

esqlCode:   
    declBrokerSchema? esqlContents;

declBrokerSchema
    :   BROKER SCHEMA schemaName (PATH schemaPathList ';')?;
schemaName
    :   IDENTIFIER;
schemaPathList
    :   IDENTIFIER (',' IDENTIFIER)*;

esqlContents
    :   (declareVariable)*?;

declareVariable
    :   DECLARE variableNames esqlDataType ';';
variableNames
    :   variableName (',' variableName)*;
variableName
    :   IDENTIFIER;
esqlDataType    
    :   (BLOB|CHARACTER|BOOLEAN|NAMESPACE);

WS              :   [ \r\t\n]+    -> skip ;
IDENTIFIER      :   [a-zA-Z_][a-zA-Z0-9_.]*;

BROKER  :   'BROKER';
SCHEMA  :   'SCHEMA';
PATH    :   'PATH';
DECLARE :   'DECLARE';
BLOB        :   'BLOB';
CHARACTER   :   'CHARACTER';
BOOLEAN :   'BOOLEAN';
NAMESPACE   :   'NAMESPACE';

我的输入是一个文件

BROKER SCHEMA nameOfSchema PATH pathVal1,pathVal2;
DECLARE iSharedVar CHARACTER;

然而,当我更改语法行如下时,使用固定关键字,其中包含额外的空格

declBrokerSchema
    :   'BROKER SCHEMA ' schemaName ('PATH ' schemaPathList ';')?;
// Notice the keywords in ' ' with extra space at end.
declareVariable
    :   'DECLARE ' variableNames esqlDataType ';';

然后它似乎解析行并抛出下面提供的错误:

line 2:19 mismatched input 'CHARACTER' expecting {'BLOB', 'CHARACTER', 'BOOLEAN', 'NAMESPACE'}

DeclBrokerSchema(schemaName=nameOfSchema, schemaPathList=pathVal1,pathVal2)
[DeclareVariable(varibleNames=iSharedVar, dataType=CHARACTER, defultValue=null, modifier=null, isConstant=false, aliasType=null, initialValueExpression=null)]

似乎认出了它但有错误。所以需要你对这些专家的看法:

  • 我找不到任何可以在词法分析阶段匹配'CHARACTER'的规则..那为什么会抛出错误?
  • 另外,为什么还需要我使用“额外空间”中的令牌?如果我删除空间,则无法解析它..

我在这里错过了什么..请帮助..!

1 个答案:

答案 0 :(得分:1)

您的原始语法很好,除了您的词法规则中的一个小但重要的错误。由于此错误,几乎所有输入都被词法分析器标记为IDENTIFIER

[@0,0:5='BROKER',<IDENTIFIER>,1:0]
[@1,7:12='SCHEMA',<IDENTIFIER>,1:7]
[@2,14:25='nameOfSchema',<IDENTIFIER>,1:14]
[@3,27:30='PATH',<IDENTIFIER>,1:27]
[@4,32:39='pathVal1',<IDENTIFIER>,1:32]
[@5,40:40=',',<','>,1:40]
[@6,41:48='pathVal2',<IDENTIFIER>,1:41]
[@7,49:49=';',<';'>,1:49]
[@8,52:58='DECLARE',<IDENTIFIER>,2:0]
[@9,60:69='iSharedVar',<IDENTIFIER>,2:8]
[@10,71:79='CHARACTER',<IDENTIFIER>,2:19]
[@11,80:80=';',<';'>,2:28]
[@12,83:82='<EOF>',<EOF>,3:0]

让我们通过将IDENTIFIER的词法分析器规则移到底部来解决这个问题,以便该规则在其他所有规则之前不匹配:

etc...
BLOB        :   'BLOB';
CHARACTER   :   'CHARACTER';
BOOLEAN :   'BOOLEAN';
NAMESPACE   :   'NAMESPACE';
IDENTIFIER      :   [a-zA-Z_][a-zA-Z0-9._]*;

现在,如果你运行它,词法分析器会按照你期望的方式标记:

[@0,0:5='BROKER',<'BROKER'>,1:0]
[@1,7:12='SCHEMA',<'SCHEMA'>,1:7]
[@2,14:25='nameOfSchema',<IDENTIFIER>,1:14]
[@3,27:30='PATH',<'PATH'>,1:27]
[@4,32:39='pathVal1',<IDENTIFIER>,1:32]
[@5,40:40=',',<','>,1:40]
[@6,41:48='pathVal2',<IDENTIFIER>,1:41]
[@7,49:49=';',<';'>,1:49]
[@8,52:58='DECLARE',<'DECLARE'>,2:0]
[@9,60:69='iSharedVar',<IDENTIFIER>,2:8]
[@10,71:79='CHARACTER',<'CHARACTER'>,2:19]
[@11,80:80=';',<';'>,2:28]
[@12,83:82='<EOF>',<EOF>,3:0]

现在它有效。词法分析器的顺序很重要。请记住,规则从上到下进行评估。 ;)