Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Parser Lib Laravel Package

jms/parser-lib

jms/parser-lib is a lightweight PHP parser library by JMS, providing reusable parsing components to build custom parsers quickly. Ideal for interpreting structured text and creating DSLs. Full docs available at jmsyst.com/libs/parser-lib.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require jms/parser-lib
    

    Add to composer.json if using a monorepo or custom package structure.

  2. First Use Case: Parsing a Simple Grammar Define a grammar class extending JMS\Parser\Parser:

    use JMS\Parser\Parser;
    
    class MyGrammarParser extends Parser
    {
        protected function parse()
        {
            $this->sequence(
                $this->match('start'),
                $this->match('value'),
                $this->match('end')
            );
        }
    }
    
  3. Parse Input

    $parser = new MyGrammarParser();
    $result = $parser->parse('start value end');
    
  4. Key Files to Reference

    • src/JMS/Parser/Parser.php (Core class)
    • src/JMS/Parser/Exception/ (Error handling)
    • tests/ (Usage examples)

Implementation Patterns

Common Workflows

  1. Recursive Descent Parsing Use sequence(), choice(), and repeat() to define grammar rules:

    $this->sequence(
        $this->match('('),
        $this->repeat($this->choice(
            $this->match('number'),
            $this->match('string')
        )),
        $this->match(')')
    );
    
  2. Custom Matchers Extend JMS\Parser\Matcher\Matcher for domain-specific rules:

    class EmailMatcher extends Matcher
    {
        public function match($input)
        {
            return preg_match('/^[^\s@]+@[^\s@]+\.[^\s@]+$/', $input);
        }
    }
    
  3. Error Handling Catch JMS\Parser\Exception\ParseException for invalid input:

    try {
        $parser->parse($input);
    } catch (ParseException $e) {
        // Log or handle error (e.g., $e->getPosition())
    }
    
  4. Integration with Laravel

    • Validation: Use parsers in FormRequest or Validator extensions.
      $parser = new MyGrammarParser();
      if (!$parser->parse($request->input('data'))) {
          return back()->withErrors(['data' => 'Invalid format']);
      }
      
    • Artisan Commands: Parse CLI input for complex commands.
      $parser = new ConfigParser();
      $config = $parser->parse($input);
      
  5. Performance Optimization

    • Pre-compile grammars for repeated use:
      $parser = new MyGrammarParser();
      $parser->compile(); // Cache the parser state
      

Gotchas and Tips

Pitfalls

  1. State Management

    • Parsers are stateful. Reuse instances carefully or reset with $parser->reset().
    • Avoid parsing concurrent inputs with the same instance.
  2. Backtracking Overhead

    • Complex choice() rules can cause exponential backtracking. Optimize with:
      $this->choice(
          $this->sequence($this->match('A'), $this->match('B')),
          $this->sequence($this->match('X'), $this->match('Y'))
      );
      
    • Prefer deterministic rules where possible.
  3. Input Consumption

    • match() consumes input. Use $this->peek() for lookahead without consumption:
      if ($this->peek()->match('(')) {
          // Handle nested structure
      }
      
  4. Whitespace Handling

    • By default, whitespace is ignored. Override with:
      $parser->setWhitespaceHandling(false);
      

Debugging Tips

  1. Enable Verbose Output

    $parser->setVerbose(true); // Logs parsing steps to stderr
    
  2. Inspect Parser State

    $parser->getPosition(); // Current input position
    $parser->getRemainingInput(); // Unparsed input
    
  3. Unit Testing

    • Mock matchers for isolated tests:
      $matcher = $this->createMock(Matcher::class);
      $matcher->method('match')->willReturn(true);
      $parser->addMatcher('test', $matcher);
      

Extension Points

  1. Custom Lexers Extend JMS\Parser\Lexer\Lexer to tokenize input before parsing:

    class MyLexer extends Lexer
    {
        protected function tokenize($input)
        {
            return ['TOKEN1', 'TOKEN2']; // Custom logic
        }
    }
    
  2. AST Builders Attach callbacks to build abstract syntax trees (AST):

    $this->match('number')->then(function ($match) {
        return new NumberNode($match->getValue());
    });
    
  3. Integration with PHPStan Add type hints to matchers for static analysis:

    class JsonMatcher extends Matcher
    {
        public function match(string $input): bool { ... }
    }
    

Configuration Quirks

  • Case Sensitivity: Matchers are case-sensitive by default. Use regex or strtolower() for case-insensitive rules.
  • Unicode Support: Ensure input is UTF-8 encoded. Use mb_* functions if needed:
    $this->match(mb_strtolower($input, 'UTF-8'));
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
babenkoivan/elastic-client
innmind/static-analysis
innmind/coding-standard
datacore/hub-sdk
alengo/sulu-http-cache-bundle
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme
agtp/agtp-php
agtp/mod-php
centraldesktop/protobuf-php