taocpp / PEGTL

Parsing Expression Grammar Template Library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Why do I have an infinite loop?

dprogm opened this issue · comments

I am currently trying to write a parser for the Franca IDL. For some reason the grammar has an infinite loop. But I cannot figure out whats wrong with it. I cannot see any cycle in the grammar.

struct FrancaIdentifier
  : tao::pegtl::star<
      tao::pegtl::sor<
        tao::pegtl::alnum, tao::pegtl::one<'_'>
      >
    >
  { };

struct FrancaTypeIdentifier
  : tao::pegtl::star<
      tao::pegtl::sor<
        tao::pegtl::alnum, tao::pegtl::one<'_'>, tao::pegtl::one<'.'>
      >
    >
  { };

struct FrancaComment
  : tao::pegtl::sor<
      tao::pegtl::seq<
        tao::pegtl::two<'/'>, tao::pegtl::until<tao::pegtl::eolf>
      >,
      tao::pegtl::seq<
        tao::pegtl::string<'/','*'>, tao::pegtl::until<tao::pegtl::string<'*','/'>>
      >
    >
  { };

struct FrancaIgnore
  : tao::pegtl::sor<
      FrancaComment, tao::pegtl::space
    >
  { };

template<typename Rule>
struct FrancaPadded
  : tao::pegtl::pad<Rule,
      FrancaIgnore
    >
  { };

struct FrancaArgument
  : tao::pegtl::seq<
      FrancaPadded<FrancaTypeIdentifier>, FrancaPadded<FrancaIdentifier>
    >
  { };

template<typename Keyword>
struct FrancaArgumentsList
  : tao::pegtl::seq<
      FrancaPadded<Keyword>,
      tao::pegtl::one<'{'>,
        tao::pegtl::plus<FrancaArgument>,
      tao::pegtl::one<'}'>
    >
  { };

struct FrancaInputArguments
  : FrancaArgumentsList<tao::pegtl::keyword<'i','n'>>
  { };

struct FrancaOutputArguments
  : FrancaArgumentsList<tao::pegtl::keyword<'o','u','t'>>
  { };

struct FrancaMethod
  : tao::pegtl::seq<
      FrancaPadded<tao::pegtl::keyword<'m','e','t','h','o','d'>>,
      FrancaPadded<FrancaIdentifier>,
      tao::pegtl::one<'{'>,
      tao::pegtl::opt<FrancaInputArguments>,
      tao::pegtl::opt<FrancaOutputArguments>,
      tao::pegtl::one<'}'>
    >
  { };

struct FrancaInterface
  : tao::pegtl::seq<
      FrancaPadded<tao::pegtl::keyword<'i','n','t','e','r','f','a','c','e'>>,
      tao::pegtl::one<'{'>,
      tao::pegtl::plus<tao::pegtl::sor<FrancaMethod>>,
      tao::pegtl::one<'}'>>
  { };

struct FrancaGrammar
  : tao::pegtl::seq<
      FrancaInterface, tao::pegtl::eof
    >
  { };

The analyze function prints the following:

WARNING: Possible cycle without progress at rule tao::pegtl::opt<tao::pegtl::plus<franca::FrancaArgument> >
- involved (transformed) rule: tao::pegtl::opt<tao::pegtl::plus<franca::FrancaArgument> >
- involved (transformed) rule: tao::pegtl::plus<franca::FrancaArgument>

But I don't see such a rule in my grammar definition. Would be happy if someone can help me out.

FrancaArgument uses FrancaIndentifier and FrancaTypeIdentifier, both of which have star<> as their top-level rule and therefore match the empty input, i.e. they can match without progress. Now putting that into a plus<> in FrancaArgumentsList means the parser gets stuck with no progress.

You probably want to change the identifier rules from star<> to plus<>, so that identifiers have at least one character.

Good to see the grammar analysis doing its job.

Thank you so far for the fast response! Changing from star<> to plus<> solves the problem! I want to ask something related to the grammar mentioned in this issue. Should I open a new issue or continue with this one? If I should create a new one this one can be closed.

If you have questions, you can also open a discussion.