Skip to content

Export and document lark.tools.standalone.gen_standalone #1583

@fyellin

Description

@fyellin

Please export and document:
lark.tools.standalone.gen_standalone

While I love the standalone parser, I don't like the fact that the grammar has to live in its own file. My experience is that the grammar and the Transformer evolve in parallel, and having them next to each other makes that task easier.

I've been using the following code to let me quickly switch between using the standalone parser and the standard parser. I've had to reach into lark.tools.standalone and use methods that I'm not sure are public. But the grammar is just a string in the file.

def generate_standalone(filename: Path | str, compress=False, verbose=True):
    from lark import lark
    from lark.tools.standalone import gen_standalone
    parser = lark.Lark(GRAMMAR, parser='lalr', start='statement')
    with open(filename, "w") as out:
        gen_standalone(parser, out=out, compress=compress)
        out.write(f"\nGRAMMAR_HASH = '{get_grammar_hash()}'\n")
    assert filename.exists() and filename.stat().st_size > 1_000, f"Failed to generate {filename}"
    if verbose:
        print(f"Generated {filename} size: {filename.stat().st_size:,} bytes")

def get_grammar_hash() -> str:
    return hashlib.sha256(GRAMMAR.encode('utf-8')).hexdigest()

At use time I then have:

USE_PREBUILT = True

# Note that "lark" is a module if USE_PREBUILT is True and a package if it is False.
# This makes "from XX import YY" difficult. However, qualified names, Lark.XX, work the
# same for both, so we use those.

if USE_PREBUILT:
    import solver.equation_parser_prebuilt as lark
else:
    import lark

.....
def MyParser:

    @staticmethod
    def get_parser(transformer: lark.Transformer | None) -> lark.Lark:
        if not USE_PREBUILT:
            parser = lark.Lark(GRAMMAR, parser='lalr', cache=True, start='statement',
                               transformer=transformer)
        else:
            parser = lark.Lark_StandAlone(transformer=transformer)
            if lark.GRAMMAR_HASH != EquationParser.get_grammar_hash():
                raise Exception("Prebuilt parser is out of date")
        return parser

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions