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])