Git Product home page Git Product logo

Comments (11)

deliciouslytyped avatar deliciouslytyped commented on August 17, 2024

A thrown together example, based on seq:

def alt(*parsers, **kw_parsers):
    if not parsers and not kw_parsers:
        return fail('<empty alt>')

    if parsers and kw_parsers:
        raise ValueError("Use either positional arguments or keyword arguments with alt, not both")

    if parsers:
        @Parser
        def alt_parser(stream, index):
            result = None
            for parser in parsers:
                result = parser(stream, index).aggregate(result)
                if result.status:
                    return result

            return result

        return alt_parser

    else:
        @Parser
        def alt_kwarg_parser(stream, index):
            result = None
            for name, parser in kw_parsers.items():
                result = parser(stream, index).aggregate(result)
                if result.status:
                    #I'm not actually sure if this is the correct way to use aggregate here, I haven't looked at how it's supposed to work
                    return Result.success(result.index, { name: result.value }).aggregate(result)

            return result

        return alt_kwarg_parser

(also needs the >= 3.6 check for ordered kwargs)

from parsy.

jneen avatar jneen commented on August 17, 2024

I would prefer (name, value) for this, but it seems reasonable to me!

from parsy.

jneen avatar jneen commented on August 17, 2024

Reason being: you could follow it up with combine, like alt(a=..., b=...).combine(Node) and would receive Node(type, value)

from parsy.

deliciouslytyped avatar deliciouslytyped commented on August 17, 2024

I'm making this up as I go and use parsy more.

What you said sounds reasonable.

I happen to have been using(/my rationale for using) dicts (was) because it's lets me directly, somewhat meaningfully address the component of the result that I want, as opposed to using some "arbitrary" numerical index, which might possibly (?) change.

I don't know right now which should be done, or if it's possible to have both.

from parsy.

spookylukey avatar spookylukey commented on August 17, 2024

@deliciouslytyped Could you give a full example of what you are thinking of? The kind of thing that could potentially go in our docs? For me at least that would help assess whether this would fit into the existing patterns we are encouraging in parsy.

from parsy.

jneen avatar jneen commented on August 17, 2024

if i understand correctly, it's something like:

letters = regex(r'\w+')
numbers = regex(r'\d+')
atom = alt(word=letters, int=numbers.map(int))

atom.parse('abcd') # => ('word', 'abcd')
atom.parse('1234') # => ('int', 1234)

from parsy.

jneen avatar jneen commented on August 17, 2024

without pattern matching, it's difficult for python to actually make use of those tuple values, but those seem more correct in general.

from parsy.

jneen avatar jneen commented on August 17, 2024

i mean, something hacky like this would work, though.

match = lambda fs: lambda v: fs[v[0]](v[1])

atom.map(match(word=lambda w: ..., int=lambda i: ...))

from parsy.

spookylukey avatar spookylukey commented on August 17, 2024

Thanks @jneen for the explanation.

Currently we have the tag method that can do something very similar:

letters = regex(r'\w+')
numbers = regex(r'\d+')
atom = letters.tag('word') | numbers.tag('int')

One of the purposes of this is to be able to pass to combine/combine_dict - see docs - as you suggest.

Regarding building this into alt, I'm wondering whether is particular value in having another way to do the same thing? Without proper sum types in Python, it's difficult to know exactly what pattern to encourage for building something that emulates them.

from parsy.

deliciouslytyped avatar deliciouslytyped commented on August 17, 2024

Sorry, I'm super tired right now, I think my use of dicts might have been minimally analogous to pattern matching, but I'm not sure.

from parsy.

deliciouslytyped avatar deliciouslytyped commented on August 17, 2024

Ok tag looks quite relevant. On the other hand you can choose to not tag some elements of the alternative. I'm not sure if that's desirable.

seq does force using one or the other of positional/kwargs, but not mixing.

from parsy.

Related Issues (20)

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.