Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a syntax to support embed custom parser code during parsing (a proposal with demo code) #146

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

fy0
Copy link

@fy0 fy0 commented Apr 28, 2024

Sometimes, i want to use a hand writing parser for some exprerssion, for example:

e <- '{' myExpr '}'

myExpr <- {
   // some code to make brackets certainly matching, accept text like "{ {} }"
}

For that, i made a fork. Owe to pigeon's clear design, it's much easier than i thought it should be.

I use sign "*{}" to describle custom parser code block:

{
package main
}

e <- "begin" x "end" !.

myExpr <- '1' / '2' / '3'

x <-  *{
	start := p.pt

	arr := []rune{}
	for i := 0 ; i < 3; i+=1  {
		cur := p.pt.rn
		arr = append(arr, cur)
		p.read()
	}

	r, ok := p.parseExpr(p.rules["myExpr"].expr)

	p.failAt(true, start.position, "3 char + myExpr")
	return string(arr) + string(r.([]uint8)), ok, nil
}

test code:

package main

import "fmt"

func main() {
	fmt.Println(Parse("", []byte("beginxxx1end")))
}
> go run .
[[98 101 103 105 110] xxx1 [101 110 100] <nil>] <nil>

But if i want to control the parser by manual, expose "parser" object to action is necessary.
I noticed parser object is willful hide for all code blocks.
So i'm worried about i had break a guideline.

Have a look and have a nice day.

@breml
Copy link
Collaborator

breml commented May 2, 2024

Hi @fy0
Thanks for your pull request. I would like to better understand in what kind of situations you want to control the parser manually. Can you elaborate and provide some real world examples?

@fy0
Copy link
Author

fy0 commented May 3, 2024

Hi @fy0 Thanks for your pull request. I would like to better understand in what kind of situations you want to control the parser manually. Can you elaborate and provide some real world examples?

For example, I want to embed another parser inside my peg parser.

{
package main
}

e <- "<%js" js_code "%>" !.

js_code <- *{
    // there is a js parser, eat unknow length text, return a object
}

If do this work with current pigeon, I need to describe all syntax by peg, or just match '%>' and pray for '%>' is not appears in js code part.

It's also useful to implement meta programming language feature.
Another example, i want user can register their own operators. pigeon's #{ syntax is nearly works, but not good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants