{"id":8185,"library":"funcparserlib","title":"funcparserlib","description":"funcparserlib is a recursive descent parsing library for Python, based on functional combinators. It is currently at version 1.0.1 and is primarily designed for parsing small languages or external Domain Specific Languages (DSLs). The library provides a concise and type-hinted API, focusing on ease of parser construction without extensive manual lookahead management. It maintains an active development status with a moderately paced release cadence.","status":"active","version":"1.0.1","language":"en","source_language":"en","source_url":"https://github.com/vlasovskikh/funcparserlib","tags":["parsing","parser combinators","lexer","functional programming","DSL"],"install":[{"cmd":"pip install funcparserlib","lang":"bash","label":"Install latest stable version"}],"dependencies":[],"imports":[{"symbol":"make_tokenizer","correct":"from funcparserlib.lexer import make_tokenizer"},{"symbol":"TokenSpec","correct":"from funcparserlib.lexer import TokenSpec"},{"symbol":"Token","correct":"from funcparserlib.lexer import Token"},{"symbol":"tok","correct":"from funcparserlib.parser import tok"},{"symbol":"Parser","correct":"from funcparserlib.parser import Parser"},{"symbol":"many","correct":"from funcparserlib.parser import many"},{"symbol":"forward_decl","correct":"from funcparserlib.parser import forward_decl"},{"symbol":"finished","correct":"from funcparserlib.parser import finished"}],"quickstart":{"code":"from typing import List\nfrom funcparserlib.lexer import make_tokenizer, TokenSpec, Token\nfrom funcparserlib.parser import tok, Parser, many, finished\n\ndef tokenize(s: str) -> List[Token]:\n    specs = [\n        TokenSpec('whitespace', r'\\s+'),\n        TokenSpec('number', r'\\d+'),\n        TokenSpec('op', r'[+-*/()]'),\n    ]\n    tokenizer = make_tokenizer(specs)\n    return [t for t in tokenizer(s) if t.type != 'whitespace']\n\n# Define parsers\nnumber_parser: Parser[Token, int] = tok('number') >> (lambda t: int(t.value))\nop_parser: Parser[Token, str] = tok('op') >> (lambda t: t.value)\n\n# A simple grammar for 'number op number'\nexpr_parser: Parser[Token, tuple] = number_parser + op_parser + number_parser\n\n# Parse a string\ninput_str = \"123 + 45\"\ntokens = tokenize(input_str)\nresult = (expr_parser + -finished).parse(tokens)\n\nprint(f\"Input: {input_str}\")\nprint(f\"Tokens: {tokens}\")\nprint(f\"Parsed result: {result}\")\n# Expected: (123, '+', 45)","lang":"python","description":"This quickstart demonstrates how to define a tokenizer using `make_tokenizer` and then build a simple parser for 'number operator number' expressions using `funcparserlib`'s combinators like `tok`, `+`, and `>>`. It covers tokenizing input, defining terminal parsers, and combining them into a full grammar, finally parsing a sample string."},"warnings":[{"fix":"Upgrade your Python environment to 3.8+ or pin `funcparserlib` to a 1.x version if Python 2.7 compatibility is required.","message":"Future versions (e.g., 2.0.0 and beyond) will drop support for Python 2.7. If you rely on Python 2.7, ensure you pin your `funcparserlib` version to `<2.0.0` (e.g., `~=1.0`).","severity":"breaking","affected_versions":">=2.0.0 (upcoming)"},{"fix":"Upgrade your Python environment to 3.7+ (or 3.8+ for full current support) to use `funcparserlib` 1.0.0 or newer.","message":"Version 1.0.0 dropped support for Python versions 3.4, 3.5, and 3.6. Using `funcparserlib` 1.0.0+ with these Python versions will lead to incompatibilities.","severity":"breaking","affected_versions":"1.0.0+"},{"fix":"Always use primitive parsers like `tok()`, `a()`, `some()`, `forward_decl()`, `finished`, and parsing combinators (`+`, `|`, `>>`, `many()`, etc.) to construct new parser objects.","message":"The `Parser.__init__()` constructor is considered internal and may change in future versions. Directly instantiating `Parser` is discouraged.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Explicitly transform the parsing result into the desired structure using the `>>` operator with a lambda function (e.g., `(p1 + p2) >> (lambda x: MyNode(x[0], x[1]))`) or use `-p` / `skip(p)` to prevent unwanted elements from appearing in the result tuple.","message":"When combining parsers with the `+` operator (e.g., `p1 + p2`), the result can be a tuple of parsed values. If any component parser is skipped (e.g., `-p` or `skip(p)`), the tuple structure might be affected, potentially leading to unexpected results if not explicitly handled.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Upgrade `funcparserlib` to version 1.0.0 or newer, which has modernized its codebase for Python 3 compatibility. `pip install --upgrade funcparserlib`.","cause":"Using an older version of funcparserlib (e.g., 0.3.6) with modern Python versions (e.g., Python 3.13) which no longer support Python 2-style exception syntax (e.g., `except NoParseError, e:`).","error":"SyntaxError: multiple exception types must be parenthesized"},{"fix":"Upgrade `funcparserlib` to version 1.0.0 or newer. Version 1.0.0 improved parse exceptions to include expected tokens and grammar rules at the stopped position, making debugging easier.","cause":"In older versions of funcparserlib, parse error messages were less informative, only showing the unexpected token without indicating what was expected.","error":"funcparserlib.parser.NoParseError: got unexpected token: X"},{"fix":"Ensure the right-hand side of `>>` is a callable (e.g., a function, a lambda, or a type constructor) that accepts the output of the left-hand parser and returns the desired transformed value.","cause":"The `>>` operator expects a function as its right-hand operand to transform the parser's result. If a non-callable object (like a string) is provided, this error occurs.","error":"TypeError: 'str' object is not callable (when using `>>` with an unexpected argument)"}]}