ityonemo
Pegasus - PEG grammar nimbleparsec generator
Pegasus - Nimbleparsec parser generator
This library converts a PEG parser library to nimbleparsec parsers. You can “hook” extra functions on to the combinators generated by the PEG language.
The PEG language is here:
Unlike yecc/leex, This PEG grammar is extremely easy to read and write, given ABNF descriptions given in most RFCs or other standards documents (e.g. ECMA). This also leverages the extremely effective compile-time nature of the NimbleParsec library.
Most Liked
tj0
Wow, I didn’t realize I needed this library. Much, much easier to use than regular expressions. PEG seems like it would be an excellent addition to the core library as an alternative to Regex.
The following code is me just messing around trying to get things to work, but I hope it helps someone.
defmodule PegasusExample do
import NimbleParsec
require Pegasus
@moduledoc """
Examples for PEG parsing.
PegasusExample.get_pairs("grass=4,horse=1, star=2")
From https://github.com/xored/peg/blob/master/docs/grammar-examples.md
PegasusExample.get_timestamp("2009-09-22T06:59:28")
PegasusExample.get_timestamp("2009-09-22 06:59:28")
PegasusExample.get_timestamp("Fri Jun 17 03:50:56 PDT 2011")
PegasusExample.get_timestamp("2010-10-26 10:00:53.360")
"""
@parser_options [
Pair: [tag: :pair],
Word: [tag: :word],
Number: [tag: :number],
Space: [ignore: true],
Separator: [ignore: true],
Equals: [ignore: true],
]
Pegasus.parser_from_string(
"""
List <- Pair (Space* Separator Space* Pair)*
Pair <- Word Equals Number
Word <- [A-Za-z0-9_]+
Number <- [0-9]+
Space <- ' ' / '\t' / EndOfLine
EndOfLine <- '\r\n' / '\n' / '\r'
EndOfFile <- !.
Separator <- ','
Equals <- '='
""",
@parser_options
)
defparsec :get_pairs, parsec(:List)
@parser_timestamp [
Hour: [tag: :hour],
Minute: [tag: :minute],
Second: [tag: :second],
Year: [tag: :year],
Month: [tag: :month],
Day: [tag: :day],
TZ: [tag: :tz],
Space: [ignore: true],
Separator: [ignore: true],
Equals: [ignore: true],
]
Pegasus.parser_from_string(
"""
Timestamp <- DateTime / FreeDateTime
# Times
Hour <- [0-1] [0-9] / '2' [0-4]
Minute <- [0-5] [0-9]
Second <- [0-5] [0-9] / '60'
Fraction <- ('.' / ',') [0-9]+
IsoTz <- 'Z' / ('+' / '-') Hour (':'? Minute)?
TzL <- [A-Z]
TzAbbr <- TzL TzL (TzL (TzL TzL?)?)?
TZ <- IsoTz / TzAbbr
HM <- Hour ':' Minute Fraction?
HMS <- Hour ':' Minute ':' Second Fraction?
Time <- ('T' ' '?)? (HMS / HM) (' '? TZ)?
# Dates
Year <- [0-9] [0-9] [0-9] [0-9]
Month <- '0' [1-9] / '1' [0-2]
Day <- '0' [1-9] / [1-2] [0-9] / '3' [0-1]
Date <- Year '-' Month ('-' Day)?
# Combined
DateTime <- Date ' '? Time
# Free style
MonthAbbr <- 'Jan' / 'Feb' / 'Mar' / 'Apr' / 'May' / 'Jun' / 'Jul' / 'Aug' / 'Sep' / 'Sept' / 'Oct' / 'Nov' / 'Dec'
WeekDayAbbr <- 'Mon' / 'Tu' / 'Tue' / 'Tues' / 'Wed' / 'Th' / 'Thu' / 'Thur' / 'Thurs' / 'Fri' / 'Sat' / 'Sun'
FreeDateTime <- WeekDayAbbr ' ' MonthAbbr ' ' Day ' ' Time ' ' Year
""",
@parser_timestamp)
defparsec :get_timestamp, parsec(:Timestamp)
end
iex> PegasusExample.get_pairs("grass=4,horse=1, star=2")
{:ok,
[
pair: [word: ~c"grass", number: ~c"4"],
pair: [word: ~c"horse", number: ~c"1"],
pair: [word: ~c"star", number: ~c"2"]
], "", %{}, {1, 0}, 23}
TwistingTwists
ityonemo
Popular in Announcing
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









