我创建了以下语法(请查看下面的内容)当我解析后面的字符串
“Schedule; cron(\”* / 3 * * * * 美国/纽约\“);'TestFile'yyyy-M-DD-HH-毫米;美国/纽约; 20"
没有错误消息
“第1:89行:不匹配的输入'20'期待NUMBER”
。 这很奇怪,就像我的观点一样:NUMBER:[0-9] +;将允许“20”。哪里我错了?
此致 弗拉基米尔
lexer grammar FileTriggerLexer;
@header {
}
STEP
:
'/' INTEGER
;
SCHEDULE
:
'Schedule'
;
SEMICOLON
:
';'
;
ASTERISK
:
'*'
;
CRON
:
'cron'
;
MARKET_CRON
:
'marketCron'
;
COMBINED
:
'combined'
;
FILE_FEED
:
'FileFeed'
;
LBRACKET
:
'('
;
RBRACKET
:
')'
;
PERCENT
:
'%'
;
INTEGER
:
[0-9]+
;
MINUTES_INTERVAL
:
[1-59]
;
HOURS_INTERVAL
:
[0-23]
;
WEEK_DAYS_INTERVAL
:
[1-7]
;
MONTH_INTERVAL
:
[1-12]
;
DAYS_OF_MONTH_INTERVAL
:
[1-31]
;
DASH
:
'-'
;
NUMBER
:
[0-9]+
;
DOUBLE_QUOTE
:
'"'
;
QUOTE
:
'\''
;
SLASH
:
'/'
;
DOT
:
'.'
;
COMMA
:
','
;
UNDERSCORE
:
'_'
;
ID
:
[a-zA-Z] [a-zA-Z0-9]*
;
REGEX
:
(
ID
| DOT
| ASTERISK
| NUMBER
|PERCENT
)+
;
WS
:
[ \t\r\n]+ -> skip
; // skip spaces, tabs, newlines
/**
* Define a grammar called Hello
*/
grammar FileTriggerValidator;
options
{
tokenVocab = FileTriggerLexer;
}
r
:
(schedule
| file_feed)+
;
expression
:
schedule
| file_feed
;
file_feed
:
file_feed_name SEMICOLON source_file SEMICOLON source_host SEMICOLON
source_host SEMICOLON regEx SEMICOLON regEx
(
SEMICOLON source_host
)*
;
formatString
:
source_host
(
'%' source_host?
)* DOT source_host
;
regEx
:
REGEX
;
source_host
:
ID
(
DASH ID
)*
;
file_feed_name
:
FILE_FEED
;
source_file
:
(
ID
| DASH
| UNDERSCORE
)+
;
schedule
:
SCHEDULE SEMICOLON schedule_defining SEMICOLON file_name SEMICOLON timezone
(
SEMICOLON NUMBER
)?
;
schedule_defining
:
cron
| market_cron
| combined_cron
;
cron
:
CRON LBRACKET DOUBLE_QUOTE cron_part timezone DOUBLE_QUOTE RBRACKET
;
market_cron
:
MARKET_CRON LBRACKET DOUBLE_QUOTE cron_part timezone DOUBLE_QUOTE COMMA
DOUBLE_QUOTE ID DOUBLE_QUOTE RBRACKET
;
combined_cron
:
COMBINED LBRACKET cron_list_element
(
COMMA cron_list_element
)* RBRACKET
;
mic_defining
:
ID
;
file_name
:
(
ID
| DOT
| QUOTE
| DASH
)+
;
cron_list_element
:
cron
| market_cron
;
//
schedule_defined_string
:
cron
;
//
cron_part
:
minutes hours days_of_month month week_days
;
//
minutes
:
MINUTES_INTERVAL
| with_step_value
;
//
hours
:
HOURS_INTERVAL
| with_step_value
;
//
int_list
:
INTEGER
(
COMMA INTEGER
)*
;
interval
:
INTEGER DASH INTEGER
;
//
days_of_month
:
DAYS_OF_MONTH_INTERVAL
| with_step_value
;
//
month
:
MONTH_INTERVAL
| with_step_value
;
//
week_days
:
WEEK_DAYS_INTERVAL
| with_step_value
;
//
timezone
:
timezone_part
(
SLASH timezone_part
)?
;
//
timezone_part
:
ID
(
UNDERSCORE ID
)?
;
//
with_step_value
:
(
int_list
| interval
| ASTERISK
) STEP?
;
//
答案 0 :(得分:1)
你基本上犯了#1 lexer错误。
Lexer规则定义了priority rules,在您的情况下,INTEGER
规则优先于NUMBER
。两者都有相同的定义,因此您无论如何都可以简单地用NUMBER
替换所有INTEGER
出现。
请注意,您的*_INTERVAL
规则定义并不代表您的想法。例如,DAYS_OF_MONTH_INTERVAL
(定义为[1-31]
)将匹配范围1-3
或1
中的一位数,这意味着它将匹配1
,{ {1}}或2
,没有别的。 和它被3
规则遮蔽,就像您的INTEGER
规则一样。
删除所有这些NUMBER
规则,并仅保留 *_INTERVAL
规则。请记住,lexing是一个独立的传递,解析器对它没有影响。不要试图在语法中验证你的cron表达式,你将度过一段非常艰难的时期。首先,解析您的文件,然后对结果执行单独的验证传递。