2015-04-12 00:49:38 -04:00
/*
* Copyright (C) 2015 Christian Meffert <christian.meffert@googlemail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
grammar SMARTPL;
options {
output = AST;
ASTLabelType = pANTLR3_BASE_TREE;
language = C;
}
playlist : STR '{' expression '}' EOF
;
2018-03-17 08:26:08 -04:00
expression : aexpr (OR^ aexpr)* (HAVING^ aexpr)? (ORDERBY^ orderexpr)? (LIMIT^ limitexpr)?
;
orderexpr : ordertag SORTDIR
;
ordertag : STRTAG
| INTTAG
| DATETAG
| ENUMTAG
| (XXX)? NeverUsedRule
;
NeverUsedRule: /* antlr3 seems to have a problem with ordertag, introducing the NeverUsedRule fixes it. See: https://stackoverflow.com/questions/20057063/follow-set-in-is-undefined-in-generated-parser */
;
XXX : 'XXX' /**/
;
limitexpr : INT
2015-04-12 00:49:38 -04:00
;
aexpr : nexpr (AND^ nexpr)*
;
nexpr : NOT^ crit
| crit
;
crit : LPAR expression RPAR -> expression
2015-07-03 23:50:11 -04:00
| STRTAG (INCLUDES|IS|STARTSWITH) STR
2015-04-12 00:49:38 -04:00
| INTTAG INTBOOL INT
| DATETAG (AFTER|BEFORE) dateval
2015-04-23 05:36:36 -04:00
| ENUMTAG IS ENUMVAL
2018-03-17 08:26:08 -04:00
| GROUPTAG INTBOOL INT
2015-04-12 00:49:38 -04:00
;
dateval : DATE
| interval BEFORE DATE
| interval AFTER DATE
| interval AGO
;
interval : INT DATINTERVAL
;
STRTAG : 'artist'
| 'album_artist'
| 'album'
| 'title'
| 'genre'
| 'composer'
| 'path'
| 'type'
2015-05-21 00:22:55 -04:00
| 'grouping'
2018-10-26 10:59:30 -04:00
| 'artist_id'
| 'album_id'
| 'songartistid'
2019-01-29 11:40:31 -05:00
| 'songalbumid'
2015-04-12 00:49:38 -04:00
;
2015-04-23 05:36:36 -04:00
INTTAG : 'play_count'
2018-08-18 16:56:27 -04:00
| 'skip_count'
2015-04-23 05:36:36 -04:00
| 'rating'
| 'year'
| 'compilation'
2018-12-10 07:20:20 -05:00
| 'track'
| 'disc'
2015-04-12 00:49:38 -04:00
;
2015-04-23 05:36:36 -04:00
DATETAG : 'time_added'
2016-08-13 10:53:09 -04:00
| 'time_modified'
2015-04-23 05:36:36 -04:00
| 'time_played'
2018-08-18 16:56:27 -04:00
| 'time_skipped'
2015-04-12 00:49:38 -04:00
;
2015-04-23 05:36:36 -04:00
ENUMTAG : 'data_kind'
2015-04-12 00:49:38 -04:00
| 'media_kind'
2015-04-23 05:36:36 -04:00
;
2018-03-17 08:26:08 -04:00
GROUPTAG : 'track_count'
| 'album_count'
;
2015-04-23 05:36:36 -04:00
INCLUDES : 'includes'
;
IS : 'is'
2015-04-12 00:49:38 -04:00
;
2015-07-03 23:50:11 -04:00
STARTSWITH : 'starts with'
;
2015-04-12 00:49:38 -04:00
INTBOOL : (GREATER|GREATEREQUAL|LESS|LESSEQUAL|EQUAL)
;
fragment
GREATER : '>'
;
fragment
GREATEREQUAL: '>='
;
fragment
LESS : '<'
;
fragment
LESSEQUAL : '<='
;
fragment
EQUAL : '='
;
AFTER : 'after'
;
BEFORE : 'before'
;
AGO : 'ago'
;
AND : 'AND'
| 'and'
;
OR : 'OR'
| 'or'
;
NOT : 'NOT'
| 'not'
;
LPAR : '('
;
RPAR : ')'
;
DATE : ('0'..'9')('0'..'9')('0'..'9')('0'..'9')'-'('0'..'1')('0'..'9')'-'('0'..'3')('0'..'9')
| 'today'
| 'yesterday'
| 'last week'
| 'last month'
| 'last year'
;
DATINTERVAL : 'days'
| 'weeks'
| 'months'
| 'years'
;
2015-04-23 05:36:36 -04:00
ENUMVAL : 'music'
| 'movie'
| 'podcast'
| 'audiobook'
| 'tvshow'
| 'file'
| 'url'
| 'spotify'
| 'pipe'
;
2018-03-17 08:26:08 -04:00
ORDERBY : 'order by'
| 'ORDER BY'
;
SORTDIR : 'asc'
| 'ASC'
| 'desc'
| 'DESC'
;
LIMIT : 'limit'
| 'LIMIT'
;
HAVING : 'having'
| 'HAVING'
;
2015-04-12 00:49:38 -04:00
STR : '"' ~('"')+ '"'
;
INT : ('0'..'9')+
;
WHITESPACE : ('\t'|' '|'\r'|'\n'|'\u000C') { $channel = HIDDEN; }
;