我是antlr和ebnf的初学者。
我在antlr4中表达以下语法:
grammar RecordGrammar;
Record: 'record';
EndRecord: 'endrecord';
Track: 'track';
EndTrack: 'endtrack';
Length: 'length';
Name: [a-zA-Z]+;
Number: [0-9]+;
WS: [ \t\r\n]+;
records: (record)+ EOF;
record: Record WS Name WS
tracks WS?
EndRecord WS?;
tracks: track WS? (track WS)*;
track: Track WS
length
EndTrack WS?;
length: Length WS Number WS?;
当我在文本上使用上面的语法(与antlr结合使用)时:
record help
track
length 2
endtrack
track
length 4
endtrack
track
length 42
endtrack
endrecord
...效果很好,很漂亮。
但是我想在EBNF中扩展“名称”规则以也接受空格。
所以我也希望语法也接受该文本文件:
record help me
track
length 2
endtrack
track
length 4
endtrack
track
length 42
endtrack
endrecord
观察记录标签右侧的文本“帮助我”。
如何在语法上做到这一点?由于Space是自然的分隔符,因此在我的规则中需要对此进行某种特殊处理。感谢您的所有帮助,我可以得到...
答案 0 :(得分:0)
您可以创建与多个SELECT TIMESTAMPDIFF(YEAR, dob, NOW()) AS age_group,
COUNT( IF( TIMESTAMPDIFF(YEAR, dob, NOW()) <25, 1, 0 ) ) AS ag_C,
COUNT( IF( TIMESTAMPDIFF(YEAR, dob, NOW()) BETWEEN 25 AND 35 , 1, 0 ) ) AS ag_B,
COUNT( IF( TIMESTAMPDIFF(YEAR, dob, NOW()) BETWEEN 35 AND 50 , 1, 0 ) ) AS ag_C,
COUNT( IF( TIMESTAMPDIFF(YEAR, dob, NOW()) >50, 1, 0 ) ) AS ag_D
FROM emp GROUP BY age_group
令牌匹配的name
解析器规则:
Name
但是由于您实际上并没有对空格做任何事情,因此请注意,在标记化过程中,通过向其添加name : Name (WS+ Name)*;
并从解析器规则中删除所有-> skip
来丢弃它们:
WS
这将导致以下分析树:
答案 1 :(得分:0)
您应该首先确定如何确定名称的实际结尾。在最初的语法中,这很容易-它是一个单词,因此以空格字符结尾。在Bart的回答中,它是单词'record'和'track' * 之间的每个单词。但这是您的情况,还是名称实际上包含“ track”一词?
您可能还需要考虑以下选项:
"
)或撇号('
)中加上多字名称-在这种情况下,空格并不重要,可以按照Bart的回答跳过。*)比实际上要复杂得多-但这是如何查找记录名称结尾的基本概念。