jackalcooper
Is it possible to define recursive/inter-dependent parse combinators in NimbleParsec?
I’m trying to parse Zig source with NimbleParsec and come across some cases like these:
- in the definition of
containerdeclarations, it uses itself
containerdeclarations = choice(
testdecl |> concat(containerdeclarations),
toplevelcomptime |> concat(containerdeclarations),
optional(doc_comment) |> optional(keyword_pub) |> concat(topleveldecl) |> concat(containerdeclarations)
)
exprusesasmexprindirectly whileasmexprusesexpr
asmexpr =
keyword_asm
|> optional(keyword_volatile)
|> concat(lparen)
|> concat(expr)
|> optional(asmoutput)
|> concat(rparen)
primaryexpr =
choice([
asmexpr,
ifexpr,
keyword_break |> optional(breaklabel) |> optional(expr),
keyword_comptime |> concat(expr),
keyword_nosuspend |> concat(expr),
keyword_continue |> optional(breaklabel),
keyword_resume |> concat(expr),
keyword_return |> optional(expr),
optional(blocklabel) |> concat(loopexpr),
block,
curlysuffixexpr
])
prefixexpr = repeat(prefixop) |> concat(primaryexpr)
multiplyexpr = prefixexpr |> optional(multiplyop |> concat(prefixexpr))
additionexpr = multiplyexpr |> optional(additionop |> concat(multiplyexpr))
bitshiftexpr = additionexpr |> optional(bitshiftop |> concat(additionexpr))
bitwiseexpr = bitshiftexpr |> optional(bitwiseop |> concat(bitshiftexpr))
compareexpr = bitwiseexpr |> optional(compareop |> concat(bitwiseexpr))
boolandexpr = compareexpr |> optional(keyword_and |> concat(compareexpr))
boolorexpr = boolandexpr |> optional(keyword_or |> concat(boolandexpr))
expr = boolorexpr
Marked As Solved
kip
Yes, you can have recursive combinators. But they need to be defined as defparsec in order to create their own context. They will need to be defined in their own module since they become functions. Something like (not complete):
defmodule Combinators do
import NimbleParsec
defparsec :asmexpr,
keyword_asm
|> optional(keyword_volatile)
|> concat(lparen)
|> parsec(:expr)
|> optional(asmoutput)
|> concat(rparen)
defparsec :primaryexpr,
choice([
parsec(:asmexpr),
ifexpr,
keyword_break |> optional(breaklabel) |> optional(parsec(:expr)),
keyword_comptime |> parsec(:expr),
keyword_nosuspend |> parsec(:expr),
keyword_continue |> optional(breaklabel),
keyword_resume |> parsec(Lexpr),
keyword_return |> optional(parsec(:expr)),
optional(blocklabel) |> concat(loopexpr),
block,
curlysuffixexpr
])
# Other combinators
end
Also Liked
jackalcooper
update:
- after changing all combinators from variable to
defcombinatorp, it compiles fast - the parsing doesn’t terminate now, there should be some other bugs
- new version: Zig parser in elixir based on https://github.com/ziglang/zig-spec/blob/master/grammar/grammar.y · GitHub
100phlecs
This may be of interest to you, though I’m not certain on its status: GitHub - E-xyza/zig_parser: Zig Parser for Elixir · GitHub
It is created with GitHub - ityonemo/pegasus: peg -> nimbleparsec · GitHub
An unrelated thought, but curious of the advantages and disadvantages of the PEG route vs a traditional lexer + parser
ityonemo
It works (well enough for my zigler 0.10.x development branch) and is currently designed to parse zig 0.10.x
Last Post!
jackalcooper
@ityonemo
the problematic expr seems not to be covered by the fix in the last commit
pub const __LDBL_MAX__ = @as(c_longdouble, 1.18973149535723176502e+4932);
https://github.com/ityonemo/zig_parser/issues/2#issuecomment-1365148468
Trending in Questions
Other Trending 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
- #elixirconf-us
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









