解析器和词法分析器规则重叠
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' 的步骤,有人可能会忘记这样做。
我在 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' 的步骤,有人可能会忘记这样做。