Giter Site home page Giter Site logo

lpeter1997 / cppcmb Goto Github PK

View Code? Open in Web Editor NEW
122.0 122.0 8.0 349 KB

A generic C++17 parser-combinator library with a natural grammar notation.

License: MIT License

C++ 99.37% CMake 0.05% Python 0.58%
c-plus-plus c-plus-plus-17 parser parser-combinator parser-combinators parser-library

cppcmb's People

Contributors

colinh avatar lpeter1997 avatar marazmarci avatar quarticcat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

cppcmb's Issues

InputIterator?

The documentation says that CppCmb works on an InputIterator for tokens, but I'm wondering, don't you actually require a ForwardIterator (that allows you to perform backtracking)?

For example consider something with a structure like alt< seq< one, one, one >, one > with an input of two tokens, where you are effectively backtracking to let the second branch of the alt start at the same position as the first...

pc::product<> with no template arguments?

If I have a code like below

cppcmb_decl(expr, pc::product<>);

cppcmb_def(expr) = pc::pass
    | (num & match<'+'> & num)// [pc::select<1,0,2>]
    ;

std::string to_num(std::vector<char> const& chs) {//just for conversion from vector<char>->string
    const std::string str(chs.begin(), chs.end());
    return str;
}
cppcmb_def(num) = (+digit)[to_string];
cppcmb_def(digit) = pc::one[pc::filter(isdigit)];

I get an error like

error: no viable conversion from returned value of type 'result<product<std::__1::vector<char, std::__1::allocator<char> >, char, std::__1::vector<char, std::__1::allocator<char> >>>' to function return type 'result<product<(no argument), (no argument), (no argument)>>'

if I specify a return type to template arguments of pc::product

cppcmb_decl(expr, pc::product<std::string,char,std::string>);

The compiltion succeeds.
When can we use pc::product<> without template arguments?

Better compiler error messages

Hi,
I don't know if its possible but maybe this can be somehow handled better:

If I have a grammar rule like so:

cppcmb_def(expr) = pc::pass
                   | (expr & match<Token::PLUS> & primary) [BinaryExpr::make]
                   | (expr & match<Token::MINUS> & primary) [BinaryExpr::make]
                   | primary
                   %= pc::as_memo_d;

And the method looks like this:

class BinaryExpr: public Expr {
       static ExprPtr  make(ExprPtr left_ ,ExprPtr right_ , Token op_ )
}

Can we have better error messages, that indicate what was wrong?

Error reporting

Sorry for the long time no activity, it's time to pick this project back up where I left off!

The first thing being, this project needs proper error-types to report more precise errors in case of a parse failure.

Matching N times

I am trying to write a parser using CppCmb that will match N characters. I see that there are operators for matching zero or many (*) and one or many (+). I did not see the equivalent {N} operator that many grep languages afford.

My use case is to actually match up to N characters or the first null '\0' character from an input stream. E.g. if N is 3 and "\0" is the null character escape code, matching strings would be:

INPUT NOTES
"123" "123" is captured
"ABCD" "ABC" is captured, "D" remains and may be used for a different match
"12\0" "12" or "12\0" as captures are fine, as long as the "\0" is consumed
"\0" "" or "\0" are acceptable captures, as long as the "\0" is consumed

Examples of not matching strings would be:

INPUT NOTES
"12" where there is no "\0" following the "2"
"" an empty stream with no "\0"

I tried to see if I could use a template with a non type parameter to recursively apply a match where N is decremented each call, but It didn't seem to work correctly with your cppcmb_decl / def macro system.

Here is a function that will match up to N characters or the first NULL character given a filter predicate and a begin and end iterator. It returns a pair containing a boolean of the match outcome and the iterator pointing to the furthest character in the stream that was parsed.

template <size_t N, typename F, typename I>
constexpr auto parseNor0(F&& filter, I begin, I end) {
  if constexpr (N == 0) {
    return std::make_pair(false, begin);
  }
  
  if (*begin == '\0') {
    return std::make_pair(true, begin);
  }

  if (filter(*begin)) {
    if constexpr (N == 1) {
      return std::make_pair(true, begin); 
    }
    if constexpr (N > 1) {
      if (++begin != end) {
        //call recursively
        return parseNor0<N-1>(filter, begin, end);
      }
    }
  }

  return std::make_pair(false, begin);
}

Do you have any suggestions on how to match N times?

can this library support customized Token parsing?

Hi, this library is nice! Good work! Though it has many advanced C++ template code which is a bit hard for me.

Back to my question, I mean in my application, I have my own lexer(mainly the C-preprocessor) implemented myself, so my question is: can the library support parsing rules for custom lexer.

For example, the lexer has some kinds of std::vector<Token> supplied, the Token class may have definition like:

class Token
{
    TokenKind kind;
    std::string lexeme;
}

So, I would like this library to parse the Token stream not the char stream.

Any suggestions?
Thanks.

Better README

The README doesn't do justice to the library and it's overall awful. Should be rewritten to something like the other libraries.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.