Skip to content

Commit 512732d

Browse files
committed
Merge branch 'release/3.1'
2 parents d65ffb8 + 53b17ce commit 512732d

31 files changed

Lines changed: 2379 additions & 1029 deletions

.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.0.0
1+
3.1.0

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
#### Version 3.1.0 (TBD)
4+
* Added support for parsing standalone `function statements` in a compiler. Now, the following forms will parse into a `FunctionTree` that contains a symbolic representation of the function expressed in the CCL statement:
5+
* `function(key)` produces a FunctionTree whose root node contains an `IndexFunction`
6+
* `function(key, record)` produces a FunctionTree whose root node contains a `KeyRecordsFunction`
7+
* `function(key, record1,record2,...,recordN)` produces a FunctionTree whose root node contains a `KeyRecordsFunction`
8+
* `function(key, condition)` produces a FunctionTree whose root node contains a `KeyConditionFunction`
9+
* `key \| function` produces a FunctionTree whose root node contains an `ImplicitKeyRecordFunction`
10+
* Fixed a bug where the paramaterized type of `KeyRecordsFunction` was a `List<String>` instead of a `List<Long>`.
11+
* Added support for including an optional timestamp within a function value statement.
12+
313
#### Version 3.0.0 (June 15, 2020)
414
##### Function Statements
515
In version `3.0.0` we added support for **function statements**.

grammar/grammar.jjt

Lines changed: 106 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ package com.cinchapi.ccl.generated;
2727

2828
import com.cinchapi.ccl.SyntaxException;
2929
import com.cinchapi.ccl.grammar.DirectionSymbol;
30+
import com.cinchapi.ccl.grammar.FunctionTokenSymbol;
3031
import com.cinchapi.ccl.grammar.KeySymbol;
3132
import com.cinchapi.ccl.grammar.ValueTokenSymbol;
32-
import com.cinchapi.ccl.type.function.KeyCclFunction;
33+
import com.cinchapi.ccl.type.function.KeyConditionFunction;
3334
import com.cinchapi.ccl.type.function.KeyRecordsFunction;
3435
import com.cinchapi.ccl.grammar.FunctionKeySymbol;
3536
import com.cinchapi.ccl.grammar.FunctionValueSymbol;
@@ -44,6 +45,7 @@ import com.cinchapi.ccl.grammar.ValueSymbol;
4445
import com.cinchapi.ccl.grammar.PageSymbol;
4546
import com.cinchapi.ccl.grammar.OrderSymbol;
4647
import com.cinchapi.ccl.syntax.AbstractSyntaxTree;
48+
import com.cinchapi.ccl.syntax.ConditionTree;
4749
import com.cinchapi.ccl.type.Operator;
4850
import com.cinchapi.ccl.util.NaturalLanguage;
4951
import com.cinchapi.common.base.AnyStrings;
@@ -109,6 +111,8 @@ SKIP :
109111

110112
TOKEN : { < OPEN_PARENTHESES : "(" > }
111113
TOKEN : { < CLOSE_PARENTHESES : ")" > }
114+
TOKEN : { < OPEN_BRACKET : "[" > }
115+
TOKEN : { < CLOSE_BRACKET : "]" > }
112116
TOKEN [IGNORE_CASE]: { < TIMESTAMP: "at" | "on" | "during" | "in" > }
113117
TOKEN [IGNORE_CASE]: { < WHERE: "where" > }
114118
TOKEN [IGNORE_CASE]: { < RESERVED_IDENTIFIER: "$id$" > }
@@ -189,7 +193,7 @@ TOKEN :
189193
|
190194
< NON_ALPHANUMERIC_AND_ALPHANUMERIC: (<NON_ALPHANUMERIC>|<ALPHANUMERIC>)+ >
191195
|
192-
< #NON_ALPHANUMERIC: ~[",", "_","a"-"z","A"-"Z", "\n", "\t", "\r", " ", "(", ")", "="] >
196+
< #NON_ALPHANUMERIC: ~[",", "_","a"-"z","A"-"Z", "\n", "\t", "\r", " ", "(", ")", "[", "]", "="] >
193197
|
194198
< #LETTER: ["_","a"-"z","A"-"Z"] >
195199
|
@@ -200,24 +204,28 @@ TOKEN :
200204

201205
ASTStart StartCommandLine() #Start : {}
202206
{
203-
(
207+
( LOOKAHEAD(4)
204208
(<WHERE>)? DisjunctionExpression() (Order())? (Page())? "\n"
205209
|
206210
Page() "\n"
207211
|
208212
Order() "\n"
213+
|
214+
Function() "\n"
209215
)
210216
{ return jjtThis; }
211217
}
212218

213219
ASTStart generateAST() #Start : {}
214220
{
215-
(
221+
( LOOKAHEAD(4)
216222
(<WHERE>)? DisjunctionExpression() (Order())? (Page())? <EOF>
217223
|
218224
Page() <EOF>
219225
|
220226
Order() <EOF>
227+
|
228+
Function() <EOF>
221229
)
222230
{ return jjtThis; }
223231
}
@@ -258,13 +266,13 @@ void RelationalExpression() #Expression :
258266
{
259267
key=Key()
260268
(
261-
operator=LinksToOperator() value1=LinksToValue() timestamp=Timestamp()
269+
operator=LinksToOperator() value1=LinksToValue() (timestamp=Timestamp())?
262270
|
263-
operator=RegexBasedOperator() value1=RegexValue() timestamp=Timestamp()
271+
operator=RegexBasedOperator() value1=RegexValue() (timestamp=Timestamp())?
264272
|
265-
operator=UnaryOperator() value1=UnaryValue() timestamp=Timestamp()
273+
operator=UnaryOperator() value1=UnaryValue() (timestamp=Timestamp())?
266274
|
267-
operator=BinaryOperator() value1=BinaryValue() value2=BinaryValue() timestamp=Timestamp()
275+
operator=BinaryOperator() value1=BinaryValue() value2=BinaryValue() (timestamp=Timestamp())?
268276
) { jjtThis.key(key);
269277
jjtThis.operator(operator);
270278
jjtThis.addValue(value1);
@@ -275,15 +283,15 @@ void RelationalExpression() #Expression :
275283

276284
KeyTokenSymbol Key() :
277285
{
286+
FunctionKeySymbol function;
278287
Token key;
279-
Token function;
280288
}
281289
{
282290
(
283291
LOOKAHEAD(2)
284292

285-
(key=<SIGNED_INTEGER> | key=<SIGNED_DECIMAL> | key=<NUMERIC> | key=<ALPHANUMERIC> | key=<PERIOD_SEPARATED_STRING>) <PIPE> function=<ALPHANUMERIC>
286-
{ return new FunctionKeySymbol(new ImplicitKeyRecordFunction(function.image, key.image.substring(0, key.image.length())));}
293+
(function=KeyFunction())
294+
{ return function; }
287295
|
288296
(key=<RESERVED_IDENTIFIER> | key=<SIGNED_INTEGER> | key=<SIGNED_DECIMAL> | key=<NUMERIC> | key=<ALPHANUMERIC>)
289297
{ return new KeySymbol(key.image); }
@@ -295,7 +303,7 @@ KeyTokenSymbol Key() :
295303

296304
ValueTokenSymbol UnaryValue() :
297305
{
298-
Token function;
306+
FunctionValueSymbol function;
299307
Token key;
300308
Token word;
301309
String value = "";
@@ -305,25 +313,8 @@ ValueTokenSymbol UnaryValue() :
305313
{
306314
LOOKAHEAD(2)
307315

308-
function=<ALPHANUMERIC> <OPEN_PARENTHESES>
309-
(
310-
LOOKAHEAD(3)
311-
312-
(key=<SIGNED_INTEGER> | key=<SIGNED_DECIMAL> | key=<ALPHANUMERIC> | key=<PERIOD_SEPARATED_STRING>) <CLOSE_PARENTHESES>
313-
{ return new FunctionValueSymbol(new IndexFunction(function.image, key.image));}
314-
|
315-
LOOKAHEAD(3)
316-
317-
(key=<SIGNED_INTEGER> | key=<SIGNED_DECIMAL> | key=<ALPHANUMERIC> | key=<PERIOD_SEPARATED_STRING>)
318-
(<COMMA> (word=<SIGNED_INTEGER> | word=<NUMERIC>){ records.add(word.image); })+ <CLOSE_PARENTHESES>
319-
{ return new FunctionValueSymbol(new KeyRecordsFunction(function.image, key.image, records));}
320-
|
321-
(key=<SIGNED_INTEGER> | key=<SIGNED_DECIMAL> | key=<ALPHANUMERIC> | key=<PERIOD_SEPARATED_STRING>) <COMMA> ccl=generateSubAST() <CLOSE_PARENTHESES>
322-
{
323-
AbstractSyntaxTree tree = (AbstractSyntaxTree) ccl.jjtAccept(visitor, null);
324-
325-
return new FunctionValueSymbol(new KeyCclFunction(function.image, key.image, tree));}
326-
)
316+
(function=ValueFunction())
317+
{ return function; }
327318
|
328319
( LOOKAHEAD(2) (word=<SIGNED_INTEGER> | word=<SIGNED_DECIMAL> | word=<NUMERIC> | word=<ALPHANUMERIC> | word=<NON_ALPHANUMERIC_AND_ALPHANUMERIC> | word=<PERIOD_SEPARATED_STRING>) { value += (value.equals("")) ? word.image : " " + word.image; })+
329320
{
@@ -379,7 +370,7 @@ ValueTokenSymbol RegexValue() :
379370

380371
ValueTokenSymbol BinaryValue() :
381372
{
382-
Token function;
373+
FunctionValueSymbol function;
383374
Token key;
384375
Token word;
385376
String value = "";
@@ -389,25 +380,8 @@ ValueTokenSymbol BinaryValue() :
389380
{
390381
LOOKAHEAD(2)
391382

392-
function=<ALPHANUMERIC> <OPEN_PARENTHESES>
393-
(
394-
LOOKAHEAD(3)
395-
396-
(key=<SIGNED_INTEGER> | key=<SIGNED_DECIMAL> | key=<ALPHANUMERIC>) <CLOSE_PARENTHESES>
397-
{ return new FunctionValueSymbol(new IndexFunction(function.image, key.image));}
398-
|
399-
LOOKAHEAD(3)
400-
401-
(key=<SIGNED_INTEGER> | key=<SIGNED_DECIMAL> | key=<ALPHANUMERIC> | key=<PERIOD_SEPARATED_STRING>)
402-
(<COMMA> (word=<SIGNED_INTEGER> | word=<NUMERIC>){ records.add(word.image); })+ <CLOSE_PARENTHESES>
403-
{ return new FunctionValueSymbol(new KeyRecordsFunction(function.image, key.image, records));}
404-
|
405-
(key=<SIGNED_INTEGER> | key=<SIGNED_DECIMAL> | key=<ALPHANUMERIC> | key=<PERIOD_SEPARATED_STRING>) <COMMA> ccl=generateSubAST() <CLOSE_PARENTHESES>
406-
{
407-
AbstractSyntaxTree tree = (AbstractSyntaxTree) ccl.jjtAccept(visitor, null);
408-
409-
return new FunctionValueSymbol(new KeyCclFunction(function.image, key.image, tree));}
410-
)
383+
(function=ValueFunction())
384+
{ return function; }
411385
|
412386
(word=<SIGNED_INTEGER> | word=<SIGNED_DECIMAL> | word=<NUMERIC> | word=<ALPHANUMERIC> | word=<NON_ALPHANUMERIC_AND_ALPHANUMERIC> | word=<PERIOD_SEPARATED_STRING>)
413387
{
@@ -438,7 +412,6 @@ ValueTokenSymbol BinaryValue() :
438412
|
439413
(word=<QUOTED_STRING>)
440414
{ return new ValueSymbol(transformValue(word.image.replace("\\\"", "\""))); }
441-
442415
}
443416

444417
OperatorSymbol LinksToOperator() :
@@ -479,9 +452,8 @@ TimestampSymbol Timestamp() :
479452
String timestamp = "";
480453
}
481454
{
482-
(<TIMESTAMP> (LOOKAHEAD(2) (word=<QUOTED_STRING> | word=<SIGNED_INTEGER> | word=<SIGNED_DECIMAL> | word=<NUMERIC> | word=<ALPHANUMERIC> | word=<NON_ALPHANUMERIC_AND_ALPHANUMERIC>) { timestamp += (timestamp.equals("")) ? word.image : " " + word.image; })+
483-
{ return new TimestampSymbol(NaturalLanguage.parseMicros(timestamp)); })?
484-
{ return null; }
455+
<TIMESTAMP> (LOOKAHEAD(2) (word=<QUOTED_STRING> | word=<SIGNED_INTEGER> | word=<SIGNED_DECIMAL> | word=<NUMERIC> | word=<ALPHANUMERIC> | word=<NON_ALPHANUMERIC_AND_ALPHANUMERIC>) { timestamp += (timestamp.equals("")) ? word.image : " " + word.image; })+
456+
{ return new TimestampSymbol(NaturalLanguage.parseMicros(timestamp)); }
485457
}
486458

487459
void Page() #Page :
@@ -546,7 +518,7 @@ OrderComponentSymbol OrderClause() :
546518
|
547519
key=Key() (direction=WordDirection())?
548520
)
549-
timestamp=Timestamp())
521+
(timestamp=Timestamp())?)
550522
{
551523
if(direction != null) {
552524
if(timestamp != null) {
@@ -595,4 +567,82 @@ DirectionSymbol WordDirection() :
595567
direction=<DESC>
596568
{ return DirectionSymbol.DESCENDING; }
597569
)
570+
}
571+
572+
void Function() #Function :
573+
{
574+
FunctionTokenSymbol function;
575+
}
576+
{
577+
( LOOKAHEAD(2)
578+
function = KeyFunction()
579+
|
580+
function = ValueFunction()
581+
)
582+
{ jjtThis.function(function);}
583+
}
584+
585+
FunctionKeySymbol KeyFunction() :
586+
{
587+
Token key;
588+
Token function;
589+
}
590+
{
591+
(key=<SIGNED_INTEGER> | key=<SIGNED_DECIMAL> | key=<NUMERIC> | key=<ALPHANUMERIC> | key=<PERIOD_SEPARATED_STRING>) <PIPE> function=<ALPHANUMERIC>
592+
{ return new FunctionKeySymbol(new ImplicitKeyRecordFunction(function.image, key.image.substring(0, key.image.length())));}
593+
}
594+
595+
FunctionValueSymbol ValueFunction() :
596+
{
597+
Token function;
598+
Token key;
599+
Token word;
600+
List<String> records = Lists.newArrayList();
601+
ASTStart ccl;
602+
TimestampSymbol timestamp = null;
603+
}
604+
{
605+
function=<ALPHANUMERIC> <OPEN_PARENTHESES>
606+
(
607+
LOOKAHEAD(3)
608+
609+
(key=<SIGNED_INTEGER> | key=<SIGNED_DECIMAL> | key=<ALPHANUMERIC> | key=<PERIOD_SEPARATED_STRING>)
610+
(
611+
<CLOSE_PARENTHESES>
612+
{ return new FunctionValueSymbol(new IndexFunction(function.image, key.image));}
613+
|
614+
<COMMA> timestamp=Timestamp() <CLOSE_PARENTHESES>
615+
{ return new FunctionValueSymbol(new IndexFunction(function.image, key.image, timestamp.timestamp()));}
616+
)
617+
|
618+
LOOKAHEAD(3)
619+
620+
(key=<SIGNED_INTEGER> | key=<SIGNED_DECIMAL> | key=<ALPHANUMERIC> | key=<PERIOD_SEPARATED_STRING>) <COMMA>
621+
(
622+
(word=<SIGNED_INTEGER> | word=<NUMERIC>){ records.add(word.image);}
623+
(<COMMA> (word=<SIGNED_INTEGER> | word=<NUMERIC>){ records.add(word.image); })* <CLOSE_PARENTHESES>
624+
{ return new FunctionValueSymbol(new KeyRecordsFunction(function.image, key.image, records));}
625+
|
626+
<OPEN_BRACKET>
627+
(word=<SIGNED_INTEGER> | word=<NUMERIC>){ records.add(word.image);}
628+
(<COMMA> (word=<SIGNED_INTEGER> | word=<NUMERIC>){ records.add(word.image); })*
629+
<CLOSE_BRACKET> <COMMA> timestamp=Timestamp() <CLOSE_PARENTHESES>
630+
{ return new FunctionValueSymbol(new KeyRecordsFunction(function.image, key.image, records, timestamp.timestamp()));}
631+
)
632+
|
633+
(key=<SIGNED_INTEGER> | key=<SIGNED_DECIMAL> | key=<ALPHANUMERIC> | key=<PERIOD_SEPARATED_STRING>) <COMMA> ccl=generateSubAST()
634+
(
635+
<CLOSE_PARENTHESES>
636+
{
637+
ConditionTree tree = (ConditionTree) ccl.jjtAccept(visitor, null);
638+
return new FunctionValueSymbol(new KeyConditionFunction(function.image, key.image, tree));
639+
}
640+
|
641+
<COMMA> timestamp=Timestamp() <CLOSE_PARENTHESES>
642+
{
643+
ConditionTree tree = (ConditionTree) ccl.jjtAccept(visitor, null);
644+
return new FunctionValueSymbol(new KeyConditionFunction(function.image, key.image, tree, timestamp.timestamp()));
645+
}
646+
)
647+
)
598648
}

src/main/java/com/cinchapi/ccl/Compiler.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import com.cinchapi.ccl.syntax.ConditionTree;
3838
import com.cinchapi.ccl.syntax.ConjunctionTree;
3939
import com.cinchapi.ccl.syntax.ExpressionTree;
40+
import com.cinchapi.ccl.syntax.FunctionTree;
4041
import com.cinchapi.ccl.syntax.OrTree;
4142
import com.cinchapi.ccl.syntax.OrderTree;
4243
import com.cinchapi.ccl.syntax.PageTree;
@@ -348,6 +349,15 @@ public List<Symbol> visit(PageTree tree, Object... data) {
348349
return symbols;
349350
}
350351

352+
@SuppressWarnings("unchecked")
353+
@Override
354+
public List<Symbol> visit(FunctionTree tree,
355+
Object... data) {
356+
List<Symbol> symbols = (List<Symbol>) data[0];
357+
symbols.add(tree.root());
358+
return symbols;
359+
}
360+
351361
};
352362
return ast.accept(visitor, Lists.newArrayList());
353363
}
@@ -358,7 +368,7 @@ public List<Symbol> visit(PageTree tree, Object... data) {
358368
* {@link ExpressionSymbol}s that are sorted by the proper order of
359369
* operations.
360370
*
361-
* @param ast
371+
* @param tree
362372
* @return a {@link Queue} of {@link PostfixNotationSymbol
363373
* PostfixNotationSymbols}
364374
*/

0 commit comments

Comments
 (0)