Skip to content

Commit

Permalink
GRAMMAR section of DECONSTRUCT is complete.
Browse files Browse the repository at this point in the history
  • Loading branch information
apr94 committed Jul 20, 2017
1 parent e3cc354 commit 8f3614a
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 3 deletions.
62 changes: 61 additions & 1 deletion bql/grammar/grammar.go
Expand Up @@ -101,6 +101,19 @@ func BQL() *Grammar {
NewTokenType(lexer.ItemSemicolon),
},
},
{
Elements: []Element{
NewTokenType(lexer.ItemDeconstruct),
NewSymbol("DECONSTRUCT_FACTS"),
NewTokenType(lexer.ItemAt),
NewSymbol("OUTPUT_GRAPHS"),
NewTokenType(lexer.ItemFrom),
NewSymbol("INPUT_GRAPHS"),
NewSymbol("WHERE"),
NewSymbol("HAVING"),
NewTokenType(lexer.ItemSemicolon),
},
},
},
"CREATE_GRAPHS": []*Clause{
{
Expand Down Expand Up @@ -879,6 +892,50 @@ func BQL() *Grammar {
},
{},
},
"DECONSTRUCT_FACTS": []*Clause{
{
Elements: []Element{
NewTokenType(lexer.ItemLBracket),
NewSymbol("DECONSTRUCT_TRIPLES"),
NewTokenType(lexer.ItemRBracket),
},
},
},
"DECONSTRUCT_TRIPLES": []*Clause{
{
Elements: []Element{
NewTokenType(lexer.ItemNode),
NewSymbol("CONSTRUCT_PREDICATE"),
NewSymbol("CONSTRUCT_OBJECT"),
NewSymbol("MORE_DECONSTRUCT_TRIPLES"),
},
},
{
Elements: []Element{
NewTokenType(lexer.ItemBlankNode),
NewSymbol("CONSTRUCT_PREDICATE"),
NewSymbol("CONSTRUCT_OBJECT"),
NewSymbol("MORE_DECONSTRUCT_TRIPLES"),
},
},
{
Elements: []Element{
NewTokenType(lexer.ItemBinding),
NewSymbol("CONSTRUCT_PREDICATE"),
NewSymbol("CONSTRUCT_OBJECT"),
NewSymbol("MORE_DECONSTRUCT_TRIPLES"),
},
},
},
"MORE_DECONSTRUCT_TRIPLES": []*Clause{
{
Elements: []Element{
NewTokenType(lexer.ItemDot),
NewSymbol("DECONSTRUCT_TRIPLES"),
},
},
{},
},
}
}

Expand Down Expand Up @@ -1003,7 +1060,7 @@ func SemanticBQL() *Grammar {

// CONSTRUCT clause semantic hooks.
setClauseHook(semanticBQL, []semantic.Symbol{"CONSTRUCT_FACTS"}, semantic.InitWorkingConstructClauseHook(), semantic.TypeBindingClauseHook(semantic.Construct))
constructTriplesSymbols := []semantic.Symbol{"CONSTRUCT_TRIPLES", "MORE_CONSTRUCT_TRIPLES"}
constructTriplesSymbols := []semantic.Symbol{"CONSTRUCT_TRIPLES", "MORE_CONSTRUCT_TRIPLES", "DECONSTRUCT_TRIPLES", "MORE_DECONSTRUCT_TRIPLES"}
setClauseHook(semanticBQL, constructTriplesSymbols, semantic.NextWorkingConstructClauseHook(), semantic.NextWorkingConstructClauseHook())
setClauseHook(semanticBQL, []semantic.Symbol{"CONSTRUCT_PREDICATE"}, semantic.NextWorkingConstructPredicateObjectPairClauseHook(), nil)
setClauseHook(semanticBQL, []semantic.Symbol{"CONSTRUCT_OBJECT"}, nil, semantic.NextWorkingConstructPredicateObjectPairClauseHook())
Expand All @@ -1012,5 +1069,8 @@ func SemanticBQL() *Grammar {
setElementHook(semanticBQL, []semantic.Symbol{"CONSTRUCT_PREDICATE"}, semantic.ConstructPredicateHook(), nil)
setElementHook(semanticBQL, []semantic.Symbol{"CONSTRUCT_OBJECT"}, semantic.ConstructObjectHook(), nil)

// DECONSTRUCT clause semantic hooks.
setClauseHook(semanticBQL, []semantic.Symbol{"DECONSTRUCT_FACTS"}, semantic.InitWorkingConstructClauseHook(), semantic.TypeBindingClauseHook(semantic.Deconstruct))

return semanticBQL
}
85 changes: 83 additions & 2 deletions bql/grammar/grammar_test.go
Expand Up @@ -145,6 +145,18 @@ func TestAcceptByParse(t *testing.T) {
from ?b where {?s "old_predicate_1"@[,] ?o1.
?s "old_predicate_2"@[,] ?o2.
?s "old_predicate_3"@[,] ?o3};`,
// Test Deconstruct clause.
`deconstruct {?s "new_predicate"@[] ?o} at ?a from ?b where {?s "old_predicate"@[,] ?o} having ?s = ?o;`,
`deconstruct {?s "new_predicate"@[] ?o} at ?a from ?b where {?s "old_predicate"@[,] ?o};`,
`deconstruct {?s ?p ?o.
_:v "_subject"@[] ?s.
_:v "_predicate"@[] ?p.
_:v "_object"@[] ?o}
at ?a, ?b
from ?c, ?d
where {?n "_subject"@[] ?s.
?n "_predicate"@[] ?p.
?n "_object"@[] ?o};`,
}
p, err := NewParser(BQL())
if err != nil {
Expand Down Expand Up @@ -262,6 +274,29 @@ func TestRejectByParse(t *testing.T) {
from ?b
where {?s "old_predicate_1"@[,] ?o1.
?s "old_predicate_2"@[,] ?o2};`,
// Deconstruct clause without source.
`deconstruct {?s "foo"@[,] ?o} at ?a where{?s "foo"@[,] ?o} having ?s = ?o;`,
// Deconstruct clause without destination.
`deconstruct {?s "foo"@[,] ?o} from ?b where{?s "foo"@[,] ?o} having ?s = ?o;`,
// Deconstruct clause with badly formed blank node.
`deconstruct {?s ?p ?o.
_v "some_pred"@[] ?k}
at ?a
from ?b
where {?s "foo"@[,] ?o};`,
// Deconstruct clause with badly formed triple.
`deconstruct {?s ?p ?o.
_:v "some_pred"@[]}
at ?a
from ?b
where {?s "foo"@[,] ?o};`,
// Deconstruct clause with multiple predicate-object pairs.
`deconstruct {?s "predicate_1"@[] ?o1;
"predicate_1"@[] ?o1}
at ?a
from ?b
where {?s "old_predicate_1"@[,] ?o1.
?s "old_predicate_2"@[,] ?o2};`,
}
p, err := NewParser(BQL())
if err != nil {
Expand Down Expand Up @@ -319,14 +354,30 @@ func TestAcceptGraphOpsByParseAndSemantic(t *testing.T) {
?s "old_predicate_2"@[,] ?o2.
?s "old_predicate_3"@[,] ?o3};`, empty, []string{"?b"}, []string{"?a"}, 0},

// construct data into multiple output graphs from multple input graphs.
// Construct data into multiple output graphs from multple input graphs.
{`construct {?s "predicate_1"@[] ?o1;
"predicate_2"@[] ?o2}
into ?a, ?b
from ?c, ?d
where {?s "old_predicate_1"@[,] ?o1.
?s "old_predicate_2"@[,] ?o2.
?s "old_predicate_3"@[,] ?o3};`, empty, []string{"?c", "?d"}, []string{"?a", "?b"}, 0},

// Deconstruct data. Graphs can be input or output graphs.
{`deconstruct {?s "predicate_1"@[] ?o1}
at ?a
from ?b
where {?s "old_predicate_1"@[,] ?o1.
?s "old_predicate_2"@[,] ?o2.
?s "old_predicate_3"@[,] ?o3};`, empty, []string{"?b"}, []string{"?a"}, 0},

// Construct data into multiple output graphs from multple input graphs.
{`deconstruct {?s "predicate_1"@[] ?o1}
at ?a, ?b
from ?c, ?d
where {?s "old_predicate_1"@[,] ?o1.
?s "old_predicate_2"@[,] ?o2.
?s "old_predicate_3"@[,] ?o3};`, empty, []string{"?c", "?d"}, []string{"?a", "?b"}, 0},
}
p, err := NewParser(SemanticBQL())
if err != nil {
Expand Down Expand Up @@ -461,7 +512,7 @@ func TestSemanticStatementGraphClausesLengthCorrectness(t *testing.T) {
}
}

func TestSemanticStatementConstructClausesLengthCorrectness(t *testing.T) {
func TestSemanticStatementConstructDeconstructClausesLengthCorrectness(t *testing.T) {
table := []struct {
query string
want int
Expand All @@ -487,6 +538,25 @@ func TestSemanticStatementConstructClausesLengthCorrectness(t *testing.T) {
?s "old_predicate_3"@[,] ?o3};`,
want: 2,
},
{
query: `deconstruct {?s "predicate_1"@[] ?o1}
at ?a
from ?b
where {?s "old_predicate_1"@[,] ?o1.
?s "old_predicate_2"@[,] ?o2.
?s "old_predicate_3"@[,] ?o3};`,
want: 1,
},
{
query: `deconstruct {?s "predicate_1"@[] ?o1.
?s "predicate_3"@[] ?o3}
at ?a
from ?b
where {?s "old_predicate_1"@[,] ?o1.
?s "old_predicate_2"@[,] ?o2.
?s "old_predicate_3"@[,] ?o3};`,
want: 2,
},
}
p, err := NewParser(SemanticBQL())
if err != nil {
Expand Down Expand Up @@ -578,6 +648,17 @@ func TestSemanticStatementPredicateObjectPairsLengthCorrectness(t *testing.T) {
wantOne: 3,
wantTwo: 3,
},
{
query: `deconstruct {?s "predicate_1"@[] ?o1.
?s1 "predicate_1"@[] ?o1}
at ?a
from ?b
where {?s "old_predicate_1"@[,] ?o1.
?s "old_predicate_2"@[,] ?o2.
?s1 "old_predicate_3"@[,] AT ?t ?o3};`,
want_one: 1,
want_two: 1,
},
}
p, err := NewParser(SemanticBQL())
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions bql/lexer/lexer.go
Expand Up @@ -43,6 +43,8 @@ const (
ItemCreate
// ItemConstruct represents the construct keyword in BQL.
ItemConstruct
// ItemDeconstruct represents the deconstruct keyword in BQL.
ItemDeconstruct
// ItemDrop represent the destruction of a graph in BQL.
ItemDrop
// ItemGraph represent the graph to be created of destroyed in BQL.
Expand Down Expand Up @@ -145,6 +147,8 @@ func (tt TokenType) String() string {
return "CREATE"
case ItemConstruct:
return "CONSTRUCT"
case ItemDeconstruct:
return "DECONSTRUCT"
case ItemDrop:
return "DROP"
case ItemGraph:
Expand Down Expand Up @@ -262,6 +266,7 @@ const (
delete = "delete"
create = "create"
construct = "construct"
deconstruct = "deconstruct"
drop = "drop"
graph = "graph"
data = "data"
Expand Down Expand Up @@ -475,6 +480,10 @@ func lexKeyword(l *lexer) stateFn {
consumeKeyword(l, ItemConstruct)
return lexSpace
}
if strings.EqualFold(input, deconstruct) {
consumeKeyword(l, ItemDeconstruct)
return lexSpace
}
if strings.EqualFold(input, drop) {
consumeKeyword(l, ItemDrop)
return lexSpace
Expand Down
4 changes: 4 additions & 0 deletions bql/semantic/semantic.go
Expand Up @@ -50,6 +50,8 @@ const (
Drop
// Construct statement.
Construct
// Deconstruct statement.
Deconstruct
)

// String provides a readable version of the StatementType.
Expand All @@ -67,6 +69,8 @@ func (t StatementType) String() string {
return "DROP"
case Construct:
return "CONSTRUCT"
case Deconstruct:
return "DECONSTRUCT"
default:
return "UNKNOWN"
}
Expand Down

0 comments on commit 8f3614a

Please sign in to comment.