regexparsingstring-parsingpegparslet

How to perform lookaheads in a PEG without making the rule too greedy?


I'm writing a parser in Parslet. In the file I want to parse, I have the following structure:

Item #1
denis calls 20
anna raises 60
denis calls 40

Item #2
another player raises 60
anna calls 60

...

To parse the actions, I did the following:

The problem is that the player name rule is too greedy, so, after the parsing, I get a response like this:

{
  item: '1',
  players: [
    { player: 'denis', action: 'calls 20' },
    { player: 'anna', action: 'raises 60' },
    { player: 'denis', action: 'calls 40' },
    { player: '\n\nItem #2\nanother player', action: 'raises 60' },
    { player: 'anna', action: 'calls 60' },
  ]
}

This is the code I'm using:

  rule :game_actions do
    game_action >> space
  end

  rule :game_action do
    in_game_action_player >> str(': ') >> in_game_action.as(:action) >> space >> game_action.as(:next).maybe
  end

  rule :in_game_action_player do
    ((str(': ') >> in_game_action).absent? >> any).repeat(1).as(:player)
  end

  rule :in_game_action do
    fold | check | call | bet | raises
  end

So, this seems to be a problem with my thinking, not the parser, and that's why I'm posting here and not in a forum or such. Can you guys help me figure out what I'm doing wrong?


Solution

  • It looks like you just need to say that a name can't start with a '\n'

    Put str ('\n ').absnt? At the beginning of you name rule.