From e05b1d210ef851bad691117bbe8818ae2e7c7907 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Fri, 20 Oct 2017 16:06:56 -0400 Subject: [PATCH] fix #24153, make `<|` right associative --- NEWS.md | 2 ++ doc/src/manual/mathematical-operations.md | 3 ++- src/julia-parser.scm | 11 ++++++++++- test/parse.jl | 4 ++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index c374310c8d3b05..f19be669efa985 100644 --- a/NEWS.md +++ b/NEWS.md @@ -44,6 +44,8 @@ Language changes * The parsing of `1<<2*3` as `1<<(2*3)` is deprecated, and will change to `(1<<2)*3` in a future version ([#13079]). + * The parsing of `<|` is now right associative. `|>` remains left associative ([#24153]). + * `{ }` expressions now use `braces` and `bracescat` as expression heads instead of `cell1d` and `cell2d`, and parse similarly to `vect` and `vcat` ([#8470]). diff --git a/doc/src/manual/mathematical-operations.md b/doc/src/manual/mathematical-operations.md index 91a429338182d8..077709fb222c6b 100644 --- a/doc/src/manual/mathematical-operations.md +++ b/doc/src/manual/mathematical-operations.md @@ -360,7 +360,8 @@ Julia applies the following order and associativity of operations, from highest | Multiplication | `* / % & \` | Left[^2] | | Bitshifts | `<< >> >>>` | Left | | Addition | `+ - \| ⊻` | Left[^2] | -| Syntax | `: ..` followed by `\|>` | Left | +| Syntax | `: ..` | Left | +| Syntax | `\|> <\|` | `\|>` Left, `<\|` Right | | Comparisons | `> < >= <= == === != !== <:` | Non-associative | | Control flow | `&&` followed by `\|\|` followed by `?` | Right | | Assignments | `= += -= *= /= //= \= ^= ÷= %= \|= &= ⊻= <<= >>= >>>=` | Right | diff --git a/src/julia-parser.scm b/src/julia-parser.scm index 742b2387c9dedc..8d6d395e6e9b6e 100644 --- a/src/julia-parser.scm +++ b/src/julia-parser.scm @@ -821,7 +821,16 @@ `(call ,op ,arg1 ,arg2)))) (else ex))))) -(define (parse-pipes s) (parse-LtoR s parse-range is-prec-pipe?)) +(define (parse-pipes s) + (let loop ((ex (parse-range s)) + (t (peek-token s))) + (cond ((or (eq? t '|\|>|) (eq? t '|.\|>|)) ; |> associates left + (begin (take-token s) + (loop (list 'call t ex (parse-range s)) (peek-token s)))) + ((or (eq? t '|<\||) (eq? t '|.<\||)) ; <| associates right + (begin (take-token s) + (list 'call t ex (parse-pipes s)))) + (else ex)))) ; parse ranges and postfix ... ; colon is strange; 3 arguments with 2 colons yields one call: diff --git a/test/parse.jl b/test/parse.jl index 997c0343a0c8fc..91cb09af425b71 100644 --- a/test/parse.jl +++ b/test/parse.jl @@ -384,6 +384,10 @@ end @test parse("1 == 2|>3") == Expr(:call, :(==), 1, Expr(:call, :(|>), 2, 3)) +# issue #24153 +@test parse("a|>b|>c|>d") == parse("((a|>b)|>c)|>d") +@test parse("a<|b<|c<|d") == parse("a<|(b<|(c<|d))") + # issue #12501 and pr #12502 parse(""" baremodule A