我在Antlr4中有语法,用于解析和验证自定义语言。其中我的语法应该视为“有效”以下
//将字符串值分配给变量
myVar = 'aString';
//带字符串参数的函数
firstFunction('thisIsAnArg');
//具有字符串参数的函数,具有特定格式(日期)
secondFunction('26/06/2016');
以下是我语法的“相关”部分
/*
* 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
课程中(日,月,年)分隔日期的能力。
对此有何想法?
答案 0 :(得分:0)
虽然由于各种原因我开始时都是“否定”(请参阅问题的评论讨论),但我决定关注@LucasTrzesniewski并将其他验证逻辑放入代码而不是语法文件。
逻辑很简单:
ValidationListener
,它扩展/继承了构建语法(.g4文件)时创建的BaseListener
。我覆盖了我需要进行任何其他验证的任何方法。在我的情况下,我覆盖了EnterFunction_call
Listener
都必须延长/继承ValidationListener
而不是BaseListener
。Listener
中的方法时,都会覆盖ValidationListener
,我必须确保首先调用base.{methodName}()
,以便在自定义之前运行“自定义”验证别的。我可以将验证直接放在我创建的每个Listener
上并省略ValidationListener
,但大多数验证在听众中很常见(正如我所说的那样,我希望将它们放在一起)在语法水平上)并使用上述设计我可以实现更好的分离。然而,代码维护有一个小的(恕我直言)缺点,因为正如我所说,我必须确保首先调用base.{methodName}()
,这是一个人们可能忘记做的“手动”步骤。