Skip to content
Snippets Groups Projects
Select Git revision
  • 64998e762b4158627f18f10e6f34449a50363553
  • master default protected
  • rednatco-v2
  • rednatco
  • test
  • ntc-tube-uniform-color
  • ntc-tube-missing-atoms
  • restore-vertex-array-per-program
  • watlas2
  • dnatco_new
  • cleanup-old-nodejs
  • webmmb
  • fix_auth_seq_id
  • update_deps
  • ext_dev
  • ntc_balls
  • nci-2
  • plugin
  • bugfix-0.4.5
  • nci
  • servers
  • v0.5.0-dev.1
  • v0.4.5
  • v0.4.4
  • v0.4.3
  • v0.4.2
  • v0.4.1
  • v0.4.0
  • v0.3.12
  • v0.3.11
  • v0.3.10
  • v0.3.9
  • v0.3.8
  • v0.3.7
  • v0.3.6
  • v0.3.5
  • v0.3.4
  • v0.3.3
  • v0.3.2
  • v0.3.1
  • v0.3.0
41 results

helper.ts

Blame
  • helper.ts 14.84 KiB
    /**
     * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
     *
     * @author Alexander Rose <alexander.rose@weirdbyte.de>
     * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
     * @author Koya Sakuma
     */
    // import * as Q from 'parsimmon';
    import * as P from '../../mol-util/monadic-parser';
    import { MolScriptBuilder } from '../../mol-script/language/builder';
    const B = MolScriptBuilder;
    import { Expression } from '../language/expression';
    import { KeywordDict, PropertyDict, FunctionDict, OperatorList } from './types';
    
    export function escapeRegExp(s: String) {
        return String(s).replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
    }
    
    // Takes a parser for the prefix operator, and a parser for the base thing being
    // parsed, and parses as many occurrences as possible of the prefix operator.
    // Note that the parser is created using `P.lazy` because it's recursive. It's
    // valid for there to be zero occurrences of the prefix operator.
    export function prefix(opParser: P.MonadicParser<any>, nextParser: P.MonadicParser<any>, mapFn: any) {
        const parser: P.MonadicParser<any> = P.MonadicParser.lazy(() => {
            return P.MonadicParser.seq(opParser, parser)
                .map(x => mapFn(...x))
                .or(nextParser);
        });
        return parser;
    }
    
    // Ideally this function would be just like `PREFIX` but reordered like
    // `P.seq(parser, opParser).or(nextParser)`, but that doesn't work. The
    // reason for that is that Parsimmon will get stuck in infinite recursion, since
    // the very first rule. Inside `parser` is to match parser again. Alternatively,
    // you might think to try `nextParser.or(P.seq(parser, opParser))`, but
    // that won't work either because in a call to `.or` (aka `P.alt`), Parsimmon
    // takes the first possible match, even if subsequent matches are longer, so the
    // parser will never actually look far enough ahead to see the postfix
    // operators.
    export function postfix(opParser: P.MonadicParser<any>, nextParser: P.MonadicParser<any>, mapFn: any) {
        // Because we can't use recursion like stated above, we just match a flat list
        // of as many occurrences of the postfix operator as possible, then use
        // `.reduce` to manually nest the list.
        //
        // Example:
        //
        // INPUT  :: "4!!!"
        // PARSE  :: [4, "factorial", "factorial", "factorial"]
        // REDUCE :: ["factorial", ["factorial", ["factorial", 4]]]
        return P.MonadicParser.seqMap(/* no seqMap() in monadic-parser.ts, any suitable replacement? */
            nextParser,
            opParser.many(),
            (x: any, suffixes: any) =>
                suffixes.reduce((acc: any, x: any) => {
                    return mapFn(x, acc);
                }, x)
        );
    }
    
    // Takes a parser for all the operators at this precedence level, and a parser
    // that parsers everything at the next precedence level, and returns a parser
    // that parses as many binary operations as possible, associating them to the
    // right. (e.g. 1^2^3 is 1^(2^3) not (1^2)^3)
    export function binaryRight(opParser: P.MonadicParser<any>, nextParser: P.MonadicParser<any>, mapFn: any) {
        const parser: P.MonadicParser<any> = P.MonadicParser.lazy(() =>
            nextParser.chain(next =>
                P.MonadicParser.seq(
                    opParser,
                    P.MonadicParser.of(next),