73 lines
1.6 KiB
JavaScript
73 lines
1.6 KiB
JavaScript
import { join } from './fn.js'
|
|
import { alpha, alphanumeric, any, char, many, map, noCaseString, parse, seq, skip } from './parser.js'
|
|
|
|
// MATCH (a:Label)-[e:Label]->(b:Label)
|
|
// RETURN a, b
|
|
|
|
const Identifier = (name, label) => ({ name, label })
|
|
|
|
const ObjectType = Object.freeze({
|
|
Node: 0,
|
|
Edge: 1
|
|
})
|
|
|
|
const GraphObject = ({ name, label }, type, properties = []) => Object.freeze({
|
|
name,
|
|
label,
|
|
type,
|
|
properties
|
|
})
|
|
|
|
const whitespace = char(' ')
|
|
const matchKeyword = noCaseString('match')
|
|
const returnKeyword = noCaseString('return')
|
|
|
|
const name = map(
|
|
join(''),
|
|
seq(alpha, many(alphanumeric))
|
|
)
|
|
const colon = char(':')
|
|
const label = seq(skip(colon), name)
|
|
|
|
const id = any(
|
|
map(
|
|
([name, label]) => Identifier(name, label),
|
|
seq(name, label)
|
|
),
|
|
map(
|
|
([name]) => Identifier(name),
|
|
name
|
|
),
|
|
map(
|
|
([label]) => Identifier(undefined, label),
|
|
label
|
|
)
|
|
)
|
|
|
|
const lparen = char('(')
|
|
const rparen = char(')')
|
|
const node = map(
|
|
([id]) => GraphObject(id, ObjectType.Node),
|
|
seq(skip(lparen), id, skip(rparen))
|
|
)
|
|
|
|
const lsquare = char('[')
|
|
const rsquare = char(']')
|
|
const edge = map(
|
|
([id]) => GraphObject(id, ObjectType.Edge),
|
|
seq(skip(lsquare), id, skip(rsquare))
|
|
)
|
|
|
|
const hyphen = char('-')
|
|
const rchevron = char('>')
|
|
const arrow = seq(hyphen, rchevron)
|
|
const relationship = seq(skip(hyphen), edge, skip(arrow), node)
|
|
|
|
const matchParameters = seq(node, many(relationship))
|
|
const matchStmt = seq(skip(matchKeyword), skip(many(whitespace)), matchParameters)
|
|
|
|
const query = 'MATCH (:Label)-[e:Label]->(b:Label)'
|
|
const result = parse(matchStmt, query)
|
|
console.log(result.value[0])
|
|
|
|
|