pigeon
pigeon copied to clipboard
[Feature Request] Operator Precedence Climbing
{
//------ start
package main
type CompExpr struct {
left string
op string
right string
}
type LogicExpr struct {
left interface{}
op string
right interface{}
}
func main() {
if len(os.Args) != 2 {
log.Fatal("Usage: calculator 'EXPR'")
}
got, err := ParseReader("", strings.NewReader(os.Args[1]))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%#v\n", got)
}
// ------ end
}
Input <- expr:Expr EOF {
return expr, nil
}
Expr <- LogicExpr / Atom
LogicExpr <- _ atom:Atom _ op: LogicOp _ expr: Expr _ {
return LogicExpr {left : atom, op : op.(string), right: expr}, nil
}
Atom <- '(' expr:Expr ')' {
return expr, nil
} / _ field: Ident _ op:BinOp _ value:Value _{
return CompExpr{left : field.(string), op: op.(string), right : value.(string)}, nil
}
LogicOp <- ("and" / "or"){
return string(c.text), nil
}
BinOp <- ("!=" / ">=" / "<=" / "=" / "<>" / ">" / "<") {
return string(c.text),nil
}
Ident <- [a-zA-Z][a-zA-Z0-9]* {
return string(c.text),nil
}
Value <- [0-9]+ {
return string(c.text),nil
}
_ "whitespace" <- [ \n\t\r]*
EOF <- !.
The right recursion grammar will auto-generate right association
If pigeon can implement precedence climbing or something else, it will be very convenient ~
This is not something that is planned to be implemented. See here for an example, how this can be achieved with the current implementation: https://github.com/mna/pigeon/blob/master/examples/calculator/calculator.peg
If you feel like implementing this, make an outline / design description first.