解析器和词法分析器规则重叠

Parser and Lexer rules overlap

我在 Antlr4 中有语法,用于解析和验证自定义语言。除其他外,我的语法应该考虑 'valid' 以下

// Assign string value to a variable
myVar = 'aString';
// Function with string argument
firstFunction('thisIsAnArg');
// Function with string argument, which have specific format (date)
secondFunction('26/06/2016');

以下是我语法的'relevant'部分

/*
 * Parser Rules
*/
function_call
     : firstFunction'(' literal ')'
     | secondFunction '(' date_formated_string ')'

literal
    : SINGLE_QUOTE_STRING
    | date_formated_string
    | '(' literal ')'  // recursive parentheses
    ;

date_formated_string
    : '\'' day = (TWO_DIGITS | ONE_DIGIT) ('/') month = (TWO_DIGITS | ONE_DIGIT) ('/') year = FOUR_DIGITS '\'';

/*
 * Lexer Rules
 */
SINGLE_QUOTE_STRING:            '\'' (~'\'' | '\'\'')* '\'';

这里的问题是 secondFunction 的参数被词法分析器解析为 SINGLE_QUOTE_STRING,因此解析器在尝试匹配 secondFunction 时抛出异常。一种解决方案是将 date_formated_string 规则移至词法分析器。但是这样我将失去在 Listener class.

中将日期分隔为(日、月、年)的能力

对此有什么想法吗?

Although I was 'negative' at the beginning for various reasons (see question's comments discussion), I decided to follow @LucasTrzesniewski and put the additional validation logic into the code and not the grammar file.

逻辑很简单:

  • 我创建了一个 ValidationListener,它扩展/继承了在构建语法(.g4 文件)时创建的 BaseListener。我覆盖了我需要进行任何额外验证的任何方法。在我的例子中,我覆盖了 EnterFunction_call
  • 我现在做的每个 Listener 都必须扩展/继承 ValidationListener 而不是 BaseListener
  • 每次我覆盖任何 Listener 中的方法时,覆盖 ValidationListener,我必须确保首先调用 base.{methodName}() 以便进行 'custom' 验证先到 运行。

我本可以直接对我创建的每个 Listener 进行验证并省略 ValidationListener,但大多数验证在听众中很常见(正如我在问题中所说的那样,我希望将它们放在语法级别)并使用上述设计我可以实现更好的分离。然而,在代码维护方面有一个小的(恕我直言)缺点,因为正如我所说,我必须确保首先调用 base.{methodName}(),这是一个 'manual' 的步骤,有人可能会忘记这样做。