hydra-0.15.0: src/main/haskell/Hydra/Sources/Gql/PathAlgebra/Syntax.hs
module Hydra.Sources.Gql.PathAlgebra.Syntax where
-- Standard imports for type-level sources outside of the kernel
import Hydra.Kernel
import Hydra.Dsl.Annotations
import Hydra.Dsl.Bootstrap
import Hydra.Dsl.Types ((>:))
import qualified Hydra.Dsl.Types as T
import qualified Hydra.Sources.Kernel.Types.Core as Core
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Set as S
import qualified Data.Maybe as Y
ns :: Namespace
ns = Namespace "com.gdblab.pathAlgebra.syntax"
define :: String -> Type -> Binding
define = defineType ns
pathAlg :: String -> Type
pathAlg = typeref ns
module_ :: Module
module_ = Module {
moduleNamespace = ns,
moduleDefinitions = (map toTypeDef definitions),
moduleTermDependencies = [Core.ns],
moduleTypeDependencies = [Core.ns],
moduleDescription = Just ("A syntax model for the path algebra grammar by Angles et al."
++ " See the paper \"Path-based Algebraic Foundations of Graph Query Languages\""
++ " and the ANTLR grammar at https://github.com/pathalgebra/AlgebraParser")}
where
definitions = terminals ++ nonterminals
terminals = [
number, text, label, variable, pathName_]
nonterminals = [
pathQuery, projection, partProj, groupProj, pathProj, restrictorExt,
orderBy, groupBy, orderByOption, groupByOption, pathPattern, nodePattern,
edgePattern, edgeDirection, rpq, plus_, star_, concatenation, alternation,
rpqRestrictor, complexCondition, compoundComplexCondition, condition,
compareSym, function_, simpleFunction, nestedFunction, complexFunction, boolOp]
-- Terminals from the grammar
number :: Binding
number = define "Number" T.bigint
text :: Binding
text = define "Text" T.string
label :: Binding
label = define "Label" T.string
variable :: Binding
variable = define "Variable" T.string
pathName_ :: Binding
pathName_ = define "PathName" T.string
-- Nonterminal productions from the grammar
pathQuery :: Binding
pathQuery = define "PathQuery" $ T.record [
"projection">: pathAlg "Projection",
"restrictorExt">: T.optional $ pathAlg "RestrictorExt",
"pathPattern">: pathAlg "PathPattern",
"groupBy">: T.optional $ pathAlg "GroupBy",
"orderBy">: T.optional $ pathAlg "OrderBy"]
projection :: Binding
projection = define "Projection" $ T.record [
"partProj">: pathAlg "PartProj",
"groupProj">: pathAlg "GroupProj",
"pathProj">: pathAlg "PathProj"]
partProj :: Binding
partProj = define "PartProj" $ T.union [
"all">: T.unit,
"limited">: pathAlg "Number"]
groupProj :: Binding
groupProj = define "GroupProj" $ T.union [
"all">: T.unit,
"limited">: pathAlg "Number"]
pathProj :: Binding
pathProj = define "PathProj" $ T.union [
"all">: T.unit,
"limited">: pathAlg "Number"]
restrictorExt :: Binding
restrictorExt = define "RestrictorExt" $ T.enum [
"walk",
"trail",
"simple",
"acyclic",
"shortest"]
orderBy :: Binding
orderBy = define "OrderBy" $ T.wrap $ pathAlg "OrderByOption"
groupBy :: Binding
groupBy = define "GroupBy" $ T.wrap $ pathAlg "GroupByOption"
orderByOption :: Binding
orderByOption = define "OrderByOption" $ T.enum [
"partition",
"group",
"path",
"partitionGroup",
"partitionPath",
"groupPath",
"partitionGroupPath"]
groupByOption :: Binding
groupByOption = define "GroupByOption" $ T.enum [
"source",
"target",
"length",
"sourceTarget",
"sourceLength",
"targetLength",
"sourceTargetLength"]
pathPattern :: Binding
pathPattern = define "PathPattern" $ T.record [
"pathName">: pathAlg "PathName",
"startNode">: pathAlg "NodePattern",
"edge">: pathAlg "EdgePattern",
"endNode">: pathAlg "NodePattern",
"condition">: T.optional $ pathAlg "ComplexCondition"]
nodePattern :: Binding
nodePattern = define "NodePattern" $ T.record [
"variable">: T.optional $ pathAlg "Variable"]
edgePattern :: Binding
edgePattern = define "EdgePattern" $ T.record [
"direction">: pathAlg "EdgeDirection",
"rpq">: T.optional $ pathAlg "Rpq"]
edgeDirection :: Binding
edgeDirection = define "EdgeDirection" $ T.enum [
"outgoing",
"incoming",
"undirected"]
rpq :: Binding
rpq = define "Rpq" $ T.union [
"parenthesis">: pathAlg "Rpq",
"label">: pathAlg "Label",
"negated">: pathAlg "Label",
"reverse">: pathAlg "Label",
"optional">: pathAlg "Rpq",
"plus">: pathAlg "Plus",
"star">: pathAlg "Star",
"concatenation">: pathAlg "Concatenation",
"alternation">: pathAlg "Alternation"]
plus_ :: Binding
plus_ = define "Plus" $ T.record [
"expression">: pathAlg "Rpq",
"restrictor">: T.optional $ pathAlg "RpqRestrictor"]
star_ :: Binding
star_ = define "Star" $ T.record [
"expression">: pathAlg "Rpq",
"restrictor">: T.optional $ pathAlg "RpqRestrictor"]
concatenation :: Binding
concatenation = define "Concatenation" $ T.record [
"left">: pathAlg "Rpq",
"right">: pathAlg "Rpq"]
alternation :: Binding
alternation = define "Alternation" $ T.record [
"left">: pathAlg "Rpq",
"right">: pathAlg "Rpq"]
rpqRestrictor :: Binding
rpqRestrictor = define "RpqRestrictor" $ T.wrap $ pathAlg "RestrictorExt"
complexCondition :: Binding
complexCondition = define "ComplexCondition" $ T.union [
"simple">: pathAlg "Condition",
"compound">: pathAlg "CompoundComplexCondition"]
compoundComplexCondition :: Binding
compoundComplexCondition = define "CompoundComplexCondition" $ T.record [
"lhs">: pathAlg "Condition",
"operator">: pathAlg "BoolOp",
"rhs">: pathAlg "ComplexCondition"]
condition :: Binding
condition = define "Condition" $ T.record [
"function">: pathAlg "Function",
"compareSym">: pathAlg "CompareSym",
"value">: pathAlg "Text"]
compareSym :: Binding
compareSym = define "CompareSym" $ T.enum [
"equal",
"notEqual",
"lessThan",
"greaterThan",
"lessThanOrEqual",
"greaterThanOrEqual"]
function_ :: Binding
function_ = define "Function" $ T.union [
"simple">: pathAlg "SimpleFunction",
"nested">: pathAlg "NestedFunction",
"complex">: pathAlg "ComplexFunction"]
simpleFunction :: Binding
simpleFunction = define "SimpleFunction" $ T.record [
"name">: pathAlg "Text",
"argument">: pathAlg "Text"]
nestedFunction :: Binding
nestedFunction = define "NestedFunction" $ T.record [
"name">: pathAlg "Text",
"innerFunction">: pathAlg "Function"]
complexFunction :: Binding
complexFunction = define "ComplexFunction" $ T.record [
"name">: pathAlg "Text",
"innerFunction">: pathAlg "Function",
"additionalArg">: pathAlg "Text"]
boolOp :: Binding
boolOp = define "BoolOp" $ T.enum [
"and",
"or"]