[smartpl.g] Add ORDER BY, LIMIT and HAVING to smart playlist grammar

This commit is contained in:
chme 2018-03-17 13:26:08 +01:00 committed by ejurgensen
parent 7dd8955a92
commit 84f262401e
2 changed files with 129 additions and 6 deletions

View File

@ -27,7 +27,26 @@ options {
playlist : STR '{' expression '}' EOF playlist : STR '{' expression '}' EOF
; ;
expression : aexpr (OR^ aexpr)* 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
; ;
aexpr : nexpr (AND^ nexpr)* aexpr : nexpr (AND^ nexpr)*
@ -42,6 +61,7 @@ crit : LPAR expression RPAR -> expression
| INTTAG INTBOOL INT | INTTAG INTBOOL INT
| DATETAG (AFTER|BEFORE) dateval | DATETAG (AFTER|BEFORE) dateval
| ENUMTAG IS ENUMVAL | ENUMTAG IS ENUMVAL
| GROUPTAG INTBOOL INT
; ;
dateval : DATE dateval : DATE
@ -79,6 +99,10 @@ ENUMTAG : 'data_kind'
| 'media_kind' | 'media_kind'
; ;
GROUPTAG : 'track_count'
| 'album_count'
;
INCLUDES : 'includes' INCLUDES : 'includes'
; ;
@ -163,6 +187,24 @@ ENUMVAL : 'music'
| 'pipe' | 'pipe'
; ;
ORDERBY : 'order by'
| 'ORDER BY'
;
SORTDIR : 'asc'
| 'ASC'
| 'desc'
| 'DESC'
;
LIMIT : 'limit'
| 'LIMIT'
;
HAVING : 'having'
| 'HAVING'
;
STR : '"' ~('"')+ '"' STR : '"' ~('"')+ '"'
; ;

View File

@ -40,8 +40,8 @@ options {
@members { @members {
} }
playlist returns [ pANTLR3_STRING title, pANTLR3_STRING query ] playlist returns [ pANTLR3_STRING title, pANTLR3_STRING query, pANTLR3_STRING orderby, pANTLR3_STRING having, int limit ]
@init { $title = NULL; $query = NULL; } @init { $title = NULL; $query = NULL; $orderby = NULL; $having = NULL; $limit = -1; }
: STR '{' e = expression '}' : STR '{' e = expression '}'
{ {
pANTLR3_UINT8 val; pANTLR3_UINT8 val;
@ -56,12 +56,54 @@ playlist returns [ pANTLR3_STRING title, pANTLR3_STRING query ]
$query->append8($query, "("); $query->append8($query, "(");
$query->appendS($query, $e.result); $query->appendS($query, $e.result);
$query->append8($query, ")"); $query->append8($query, ")");
$limit = $e.limit;
$orderby = $e.result->factory->newRaw($e.result->factory);
$orderby->appendS($orderby, $e.orderby);
$having = $e.result->factory->newRaw($e.result->factory);
$having->appendS($having, $e.having);
} }
; ;
expression returns [ pANTLR3_STRING result ] expression returns [ pANTLR3_STRING result, pANTLR3_STRING orderby, pANTLR3_STRING having, int limit ]
@init { $result = NULL; } @init { $result = NULL; $orderby = NULL; $having = NULL; $limit = -1; }
: ^(NOT a = expression) : ^(LIMIT a = expression INT)
{
$result = $a.result->factory->newRaw($a.result->factory);
$result->appendS($result, $a.result);
$having = $a.result->factory->newRaw($a.result->factory);
$having->appendS($having, $a.having);
$orderby = $a.result->factory->newRaw($a.result->factory);
$orderby->appendS($orderby, $a.orderby);
$limit = atoi((const char *)$INT.text->chars);
}
| ^(ORDERBY a = expression o = ordertag SORTDIR)
{
$result = $a.result->factory->newRaw($a.result->factory);
$result->appendS($result, $a.result);
$having = $a.result->factory->newRaw($a.result->factory);
$having->appendS($having, $a.having);
$orderby = $o.result->factory->newRaw($o.result->factory);
$orderby->appendS($orderby, $o.result);
$orderby->append8($orderby, " ");
$orderby->appendS($orderby, $SORTDIR.text->toUTF8($SORTDIR.text));
}
| ^(HAVING a = expression b = expression)
{
$result = $a.result->factory->newRaw($a.result->factory);
$result->appendS($result, $a.result);
$having = $b.result->factory->newRaw($b.result->factory);
$having->appendS($having, $b.result);
}
| ^(NOT a = expression)
{ {
$result = $a.result->factory->newRaw($a.result->factory); $result = $a.result->factory->newRaw($a.result->factory);
$result->append8($result, "NOT("); $result->append8($result, "NOT(");
@ -216,6 +258,43 @@ expression returns [ pANTLR3_STRING result ]
$result = $ENUMTAG.text->factory->newRaw($ENUMTAG.text->factory); $result = $ENUMTAG.text->factory->newRaw($ENUMTAG.text->factory);
$result->append8($result, str); $result->append8($result, str);
} }
| GROUPTAG INTBOOL INT
{
$result = $GROUPTAG.text->factory->newRaw($GROUPTAG.text->factory);
$result->appendS($result, $GROUPTAG.text->toUTF8($GROUPTAG.text));
$result->append8($result, " ");
$result->appendS($result, $INTBOOL.text->toUTF8($INTBOOL.text));
$result->append8($result, " ");
$result->appendS($result, $INT.text->toUTF8($INT.text));
}
;
ordertag returns [ pANTLR3_STRING result ]
@init { $result = NULL; }
: STRTAG
{
$result = $STRTAG.text->factory->newRaw($STRTAG.text->factory);
$result->append8($result, "f.");
$result->appendS($result, $STRTAG.text->toUTF8($STRTAG.text));
}
| INTTAG
{
$result = $INTTAG.text->factory->newRaw($INTTAG.text->factory);
$result->append8($result, "f.");
$result->appendS($result, $INTTAG.text->toUTF8($INTTAG.text));
}
| DATETAG
{
$result = $DATETAG.text->factory->newRaw($DATETAG.text->factory);
$result->append8($result, "f.");
$result->appendS($result, $DATETAG.text->toUTF8($DATETAG.text));
}
| ENUMTAG
{
$result = $ENUMTAG.text->factory->newRaw($ENUMTAG.text->factory);
$result->append8($result, "f.");
$result->appendS($result, $ENUMTAG.text->toUTF8($ENUMTAG.text));
}
; ;
dateval returns [ int result ] dateval returns [ int result ]
@ -364,3 +443,5 @@ interval returns [ int result ]
} }
} }
; ;