@gram-data/gram-parse
Version:
parse text into gram data graphs
580 lines (564 loc) • 16.6 kB
text/typescript
// Generated automatically by nearley, version 2.20.1
// http://github.com/Hardmath123/nearley
// Bypasses TS6133. Allow declared but unused functions.
// @ts-ignore
import moo from 'moo';
import * as g from '@gram-data/gram-builder';
import { tokens } from '@gram-data/gram-ast';
function id(d: any[]): any {
return d[0];
}
declare var identifier: any;
declare var symbol: any;
declare var integer: any;
declare var octal: any;
declare var hexadecimal: any;
declare var measurement: any;
declare var tickedString: any;
declare var boolean: any;
declare var singleQuotedString: any;
declare var doubleQuotedString: any;
declare var taggedString: any;
declare var decimal: any;
declare var whitespace: any;
declare var lineComment: any;
let lexer = (moo.compile({
whitespace: { match: /\s+/, lineBreaks: true },
lineComment: { match: /\/\/.*?\n?$/ },
hexadecimal: tokens.hexadecimal,
octal: tokens.octal,
measurement: tokens.measurement,
decimal: tokens.decimal,
integer: tokens.integer,
taggedString: { match: tokens.taggedString },
boolean: ['true', 'TRUE', 'True', 'false', 'FALSE', 'False'],
symbol: tokens.symbol,
identifier: tokens.identifier,
doubleQuotedString: {
match: tokens.doubleQuotedString,
value: (s: string) => s.slice(1, -1),
},
singleQuotedString: {
match: tokens.singleQuotedString,
value: (s: string) => s.slice(1, -1),
},
tickedString: {
match: tokens.tickedString,
value: (s: string) => s.slice(1, -1),
},
'-->': '-->',
'--': '--',
'<--': '<--',
'-[]->': '-[]->',
'-[]-': '-[]-',
'<-[]-': '<-[]-',
'<-[': '<-[',
']->': ']->',
'-[': '-[',
']-': ']-',
'{': '{',
'}': '}',
'[': '[',
']': ']',
'(': '(',
')': ')',
',': ',',
':': ':',
'`': '`',
"'": "'",
ø: 'ø',
}) as unknown) as NearleyLexer;
const empty = () => null;
const text = ([token]: Array<any>): string => token.text;
/*
# function extractPairs(pairGroups:Array<any>) {
# return pairGroups.map((pairGroup:Array<any>) => {
# return pairGroup[3];
# })
# }
# function extractArray(valueGroups:Array<any>):Array<any> {
# return valueGroups.map( (valueGroup) => valueGroup[3]);
# }
*/
function separateTagFromString(taggedStringValue: string) {
let valueParts = taggedStringValue.match(/([^`]+)`(.+)`$/);
if (valueParts === null || valueParts === undefined)
throw Error(`Malformed tagged string: ${taggedStringValue}`);
return {
tag: valueParts![1],
value: valueParts![2],
};
}
function separateNumberFromUnits(measurementValue: string) {
let valueParts = measurementValue.match(/(-?[0-9.]+)([a-zA-Z]+)/);
if (valueParts === null || valueParts === undefined)
throw Error(`Malformed measurement : ${measurementValue}`);
return {
value: valueParts![1],
unit: valueParts![2],
};
}
interface NearleyToken {
value: any;
[key: string]: any;
}
interface NearleyLexer {
reset: (chunk: string, info: any) => void;
next: () => NearleyToken | undefined;
save: () => any;
formatError: (token: never) => string;
has: (tokenType: string) => boolean;
}
interface NearleyRule {
name: string;
symbols: NearleySymbol[];
postprocess?: (d: any[], loc?: number, reject?: {}) => any;
}
type NearleySymbol =
| string
| { literal: any }
| { test: (token: any) => boolean };
interface Grammar {
Lexer: NearleyLexer | undefined;
ParserRules: NearleyRule[];
ParserStart: string;
}
const grammar: Grammar = {
Lexer: lexer,
ParserRules: [
{
name: 'GramSeq$ebnf$1$subexpression$1',
symbols: ['Path'],
postprocess: ([pp]) => pp,
},
{ name: 'GramSeq$ebnf$1', symbols: ['GramSeq$ebnf$1$subexpression$1'] },
{
name: 'GramSeq$ebnf$1$subexpression$2',
symbols: ['Path'],
postprocess: ([pp]) => pp,
},
{
name: 'GramSeq$ebnf$1',
symbols: ['GramSeq$ebnf$1', 'GramSeq$ebnf$1$subexpression$2'],
postprocess: d => d[0].concat([d[1]]),
},
{
name: 'GramSeq',
symbols: ['_', 'GramSeq$ebnf$1'],
postprocess: ([, pp]) => g.seq(g.flatten(pp)),
},
{ name: 'Path', symbols: ['NodePattern'], postprocess: id },
{ name: 'Path', symbols: ['PathComposition'], postprocess: id },
{ name: 'Path', symbols: ['PathPair'], postprocess: id },
{
name: 'NodePattern',
symbols: ['Node', '_', 'Edge', '_', 'NodePattern'],
postprocess: ([n, , es, , np]) =>
g.cons([n, np], {
kind: es.kind,
id: es.id,
labels: es.labels,
record: es.record,
}),
},
{ name: 'NodePattern', symbols: ['Node'], postprocess: id },
{ name: 'Node$ebnf$1', symbols: ['Attributes'], postprocess: id },
{ name: 'Node$ebnf$1', symbols: [], postprocess: () => null },
{
name: 'Node',
symbols: [{ literal: '(' }, '_', 'Node$ebnf$1', { literal: ')' }, '_'],
postprocess: ([, , attrs]) =>
attrs ? g.node(attrs.id, attrs.labels, attrs.record) : g.node(),
},
{ name: 'Edge$ebnf$1', symbols: ['Attributes'], postprocess: id },
{ name: 'Edge$ebnf$1', symbols: [], postprocess: () => null },
{
name: 'Edge',
symbols: [{ literal: '-[' }, '_', 'Edge$ebnf$1', { literal: ']->' }, '_'],
postprocess: ([, , attrs]) => ({ kind: 'right', ...attrs }),
},
{ name: 'Edge$ebnf$2', symbols: ['Attributes'], postprocess: id },
{ name: 'Edge$ebnf$2', symbols: [], postprocess: () => null },
{
name: 'Edge',
symbols: [{ literal: '-[' }, '_', 'Edge$ebnf$2', { literal: ']-' }, '_'],
postprocess: ([, , attrs]) => ({ kind: 'either', ...attrs }),
},
{ name: 'Edge$ebnf$3', symbols: ['Attributes'], postprocess: id },
{ name: 'Edge$ebnf$3', symbols: [], postprocess: () => null },
{
name: 'Edge',
symbols: [{ literal: '<-[' }, '_', 'Edge$ebnf$3', { literal: ']-' }, '_'],
postprocess: ([, , attrs]) => ({ kind: 'left', ...attrs }),
},
{
name: 'Edge',
symbols: [{ literal: '-[]->' }, '_'],
postprocess: () => ({ kind: 'right' }),
},
{
name: 'Edge',
symbols: [{ literal: '-[]-' }, '_'],
postprocess: () => ({ kind: 'either' }),
},
{
name: 'Edge',
symbols: [{ literal: '<-[]-' }, '_'],
postprocess: () => ({ kind: 'left' }),
},
{
name: 'Edge',
symbols: [{ literal: '-->' }, '_'],
postprocess: () => ({ kind: 'right' }),
},
{
name: 'Edge',
symbols: [{ literal: '--' }, '_'],
postprocess: () => ({ kind: 'either' }),
},
{
name: 'Edge',
symbols: [{ literal: '<--' }, '_'],
postprocess: () => ({ kind: 'left' }),
},
{ name: 'PathComposition', symbols: ['PathPoint'], postprocess: id },
{ name: 'PathComposition', symbols: ['PathAnnotation'], postprocess: id },
{ name: 'PathComposition', symbols: ['PathExpression'], postprocess: id },
{ name: 'PathPoint$ebnf$1', symbols: ['Attributes'], postprocess: id },
{ name: 'PathPoint$ebnf$1', symbols: [], postprocess: () => null },
{
name: 'PathPoint',
symbols: [
{ literal: '[' },
'_',
'PathPoint$ebnf$1',
{ literal: ']' },
'_',
],
postprocess: ([, , attr]) => {
if (
attr &&
(attr.id || attr.labels || attr.record) &&
attr.id !== 'ø'
) {
// console.log(attr);
return g.node(attr.id, attr.labels, attr.record);
} else {
return g.empty();
}
},
},
{ name: 'PathAnnotation$ebnf$1', symbols: ['Attributes'], postprocess: id },
{ name: 'PathAnnotation$ebnf$1', symbols: [], postprocess: () => null },
{
name: 'PathAnnotation',
symbols: [
{ literal: '[' },
'_',
'PathAnnotation$ebnf$1',
'Path',
{ literal: ']' },
'_',
],
postprocess: ([, , attr, lhs]) => {
// console.log('annotate()', lhs)
return g.cons(
[lhs],
attr ? { id: attr.id, labels: attr.labels, record: attr.record } : {}
);
},
},
{ name: 'PathExpression$ebnf$1', symbols: ['Attributes'], postprocess: id },
{ name: 'PathExpression$ebnf$1', symbols: [], postprocess: () => null },
{ name: 'PathExpression$ebnf$2', symbols: ['Kind'], postprocess: id },
{ name: 'PathExpression$ebnf$2', symbols: [], postprocess: () => null },
{
name: 'PathExpression',
symbols: [
{ literal: '[' },
'_',
'PathExpression$ebnf$1',
'PathExpression$ebnf$2',
'Path',
'Path',
{ literal: ']' },
'_',
],
postprocess: ([, , attrs, kind, lhs, rhs]) => {
return g.cons([lhs, rhs], {
kind,
id: attrs.id,
labels: attrs.labels,
record: attrs.record,
});
},
},
{ name: 'PathPair$subexpression$1', symbols: ['NodePattern'] },
{ name: 'PathPair$subexpression$1', symbols: ['PathComposition'] },
{
name: 'PathPair',
symbols: ['PathPair$subexpression$1', { literal: ',' }, '_', 'Path'],
postprocess: ([lp, , , rp]) => g.pair([lp[0], rp]),
},
{
name: 'Kind',
symbols: [{ literal: ',' }, '_'],
postprocess: () => 'pair',
},
{
name: 'Kind',
symbols: [{ literal: '-->' }, '_'],
postprocess: () => 'right',
},
{
name: 'Kind',
symbols: [{ literal: '--' }, '_'],
postprocess: () => 'either',
},
{
name: 'Kind',
symbols: [{ literal: '<--' }, '_'],
postprocess: () => 'left',
},
{ name: 'Attributes$ebnf$1', symbols: ['Identity'], postprocess: id },
{ name: 'Attributes$ebnf$1', symbols: [], postprocess: () => null },
{ name: 'Attributes$ebnf$2', symbols: ['LabelList'], postprocess: id },
{ name: 'Attributes$ebnf$2', symbols: [], postprocess: () => null },
{ name: 'Attributes$ebnf$3', symbols: ['Record'], postprocess: id },
{ name: 'Attributes$ebnf$3', symbols: [], postprocess: () => null },
{
name: 'Attributes',
symbols: ['Attributes$ebnf$1', 'Attributes$ebnf$2', 'Attributes$ebnf$3'],
postprocess: function(d, _, reject) {
const [id, labels, record] = d;
if (id || labels || record) {
return { id, labels, record };
} else return reject;
},
},
{ name: 'LabelList$ebnf$1', symbols: ['Label'] },
{
name: 'LabelList$ebnf$1',
symbols: ['LabelList$ebnf$1', 'Label'],
postprocess: d => d[0].concat([d[1]]),
},
{
name: 'LabelList',
symbols: ['LabelList$ebnf$1'],
postprocess: ([labels]) => labels,
},
{
name: 'Label',
symbols: [{ literal: ':' }, 'Symbol'],
postprocess: ([, label]) => label,
},
{
name: 'Identity',
symbols: [
lexer.has('identifier') ? { type: 'identifier' } : identifier,
'_',
],
postprocess: text,
},
{ name: 'Identity', symbols: [{ literal: 'ø' }, '_'], postprocess: text },
{
name: 'Identity',
symbols: [lexer.has('symbol') ? { type: 'symbol' } : symbol, '_'],
postprocess: text,
},
{
name: 'Identity',
symbols: [lexer.has('integer') ? { type: 'integer' } : integer, '_'],
postprocess: text,
},
{
name: 'Identity',
symbols: [lexer.has('octal') ? { type: 'octal' } : octal, '_'],
postprocess: text,
},
{
name: 'Identity',
symbols: [
lexer.has('hexadecimal') ? { type: 'hexadecimal' } : hexadecimal,
'_',
],
postprocess: text,
},
{
name: 'Identity',
symbols: [
lexer.has('measurement') ? { type: 'measurement' } : measurement,
'_',
],
postprocess: text,
},
{
name: 'Identity',
symbols: [
lexer.has('tickedString') ? { type: 'tickedString' } : tickedString,
'_',
],
postprocess: ([t]) => t.text.slice(1, -1),
},
{
name: 'Symbol',
symbols: [lexer.has('symbol') ? { type: 'symbol' } : symbol, '_'],
postprocess: text,
},
{
name: 'Symbol',
symbols: [
lexer.has('tickedString') ? { type: 'tickedString' } : tickedString,
'_',
],
postprocess: ([t]) => t.text.slice(1, -1),
},
{
name: 'Record',
symbols: [{ literal: '{' }, '_', { literal: '}' }, '_'],
postprocess: empty,
},
{ name: 'Record$ebnf$1', symbols: [] },
{
name: 'Record$ebnf$1$subexpression$1',
symbols: [{ literal: ',' }, '_', 'Property'],
postprocess: ([, , p]) => p,
},
{
name: 'Record$ebnf$1',
symbols: ['Record$ebnf$1', 'Record$ebnf$1$subexpression$1'],
postprocess: d => d[0].concat([d[1]]),
},
{
name: 'Record',
symbols: [
{ literal: '{' },
'_',
'Property',
'Record$ebnf$1',
{ literal: '}' },
'_',
],
postprocess: ([, , p, ps]) => g.propertiesToRecord([p, ...ps]),
},
{
name: 'Property',
symbols: ['Symbol', { literal: ':' }, '_', 'Value'],
postprocess: ([k, , , v]) => g.property(k, v),
},
{ name: 'Value', symbols: ['StringLiteral', '_'], postprocess: id },
{ name: 'Value', symbols: ['NumericLiteral', '_'], postprocess: id },
{
name: 'Value',
symbols: [lexer.has('boolean') ? { type: 'boolean' } : boolean, '_'],
postprocess: d => g.boolean(JSON.parse(d[0].value.toLowerCase())),
},
{ name: 'Value$ebnf$1', symbols: [] },
{
name: 'Value$ebnf$1$subexpression$1',
symbols: [{ literal: ',' }, '_', 'Value'],
postprocess: ([, , v]) => v,
},
{
name: 'Value$ebnf$1',
symbols: ['Value$ebnf$1', 'Value$ebnf$1$subexpression$1'],
postprocess: d => d[0].concat([d[1]]),
},
{
name: 'Value',
symbols: [
{ literal: '[' },
'_',
'Value',
'Value$ebnf$1',
{ literal: ']' },
'_',
],
postprocess: ([, , v, vs]) => [v, ...vs],
},
{
name: 'StringLiteral',
symbols: [
lexer.has('singleQuotedString')
? { type: 'singleQuotedString' }
: singleQuotedString,
],
postprocess: d => g.string(d[0].value),
},
{
name: 'StringLiteral',
symbols: [
lexer.has('doubleQuotedString')
? { type: 'doubleQuotedString' }
: doubleQuotedString,
],
postprocess: d => g.string(d[0].value),
},
{
name: 'StringLiteral',
symbols: [
lexer.has('tickedString') ? { type: 'tickedString' } : tickedString,
],
postprocess: d => g.string(d[0].value),
},
{
name: 'StringLiteral',
symbols: [
lexer.has('taggedString') ? { type: 'taggedString' } : taggedString,
],
postprocess: d => {
const parts = separateTagFromString(d[0].value);
return g.tagged(parts.tag, parts.value);
},
},
{
name: 'NumericLiteral',
symbols: [lexer.has('integer') ? { type: 'integer' } : integer],
postprocess: d => g.integer(d[0].value),
},
{
name: 'NumericLiteral',
symbols: [lexer.has('decimal') ? { type: 'decimal' } : decimal],
postprocess: d => g.decimal(d[0].value),
},
{
name: 'NumericLiteral',
symbols: [
lexer.has('hexadecimal') ? { type: 'hexadecimal' } : hexadecimal,
],
postprocess: d => g.hexadecimal(d[0].value),
},
{
name: 'NumericLiteral',
symbols: [lexer.has('octal') ? { type: 'octal' } : octal],
postprocess: d => g.octal(d[0].value),
},
{
name: 'NumericLiteral',
symbols: [
lexer.has('measurement') ? { type: 'measurement' } : measurement,
],
postprocess: d => {
const parts = separateNumberFromUnits(d[0].value);
return g.measurement(parts.unit, parts.value);
},
},
{
name: '_$ebnf$1',
symbols: [lexer.has('whitespace') ? { type: 'whitespace' } : whitespace],
postprocess: id,
},
{ name: '_$ebnf$1', symbols: [], postprocess: () => null },
{ name: '_', symbols: ['_$ebnf$1'], postprocess: empty },
{
name: 'Comment',
symbols: [
lexer.has('lineComment') ? { type: 'lineComment' } : lineComment,
],
postprocess: empty,
},
{ name: 'EOL', symbols: [{ literal: '\n' }], postprocess: empty },
],
ParserStart: 'GramSeq',
};
export default grammar;