< :前の番号
^ :番号順リスト
> :次の番号
P :前の記事(スレッド移動)
N :次の記事(スレッド移動)
|<:前のスレッド
>|:次のスレッド
^ :返事先
_:自分への返事
>:同じ返事先を持つ記事(前)
<:同じ返事先を持つ記事(後)
---:分割してスレッド表示、再表示
| :分割して(縦)スレッド表示、再表示
~ :スレッドのフレーム消去
.:インデックス
..:インデックスのインデックス
Issue #16841 has been updated by jeremyevans0 (Jeremy Evans).
Status changed from Open to Feedback
This doesn't seem to be a bug, it is by design. Trying to move all syntax errors into the parser is probably too difficult to justify the effort even if it is possible.
If you want to more fully check for valid syntax without having to execute code, you can probably use the same approach used in rdoc:
```ruby
check = lambda do |code|
begin
eval "BEGIN {return true}\n#{code}"
rescue SyntaxError
false
end
end
check.("class X; end") # => true
check.("class X; break; end") # => false
```
Do you think that will work for your purposes?
----------------------------------------
Bug #16841: Some syntax errors are thrown from compile.c
https://bugs.ruby-lang.org/issues/16841#change-85842
* Author: ibylich (Ilya Bylich)
* Status: Feedback
* Priority: Normal
* ruby -v: ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN
----------------------------------------
`compile.c` has a few places where it raises `SyntaxError`. Because of that `ruby -c`, Ripper and `RubyVM::AbstractSyntaxTree` don't catch them:
```sh
> ruby -vce 'class X; break; end'
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]
Syntax OK
```
```ruby
2.7.1 :001 > require 'ripper'
=> false
2.7.1 :002 > Ripper.sexp('class X; break; end')
=> [:program, [[:class, [:const_ref, [:@const, "X", [1, 6]]], nil, [:bodystmt, [[:void_stmt], [:break, []]], nil, nil, nil]]]]
2.7.1 :003 > RubyVM::AbstractSyntaxTree.parse('class X; break; end')
=> #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-1:19>
```
I've changed locally `assert_valid_syntax` to use `RubyVM::AbstractSyntaxTree` for parsing and got ~5 failing tests (like `Invalid next/break/redo` and one more related to pattern matching).
I started playing with `parse.y` yesterday but then I quickly realized that to reject such code we need some information about scopes (basically something like a stack of scopes).
This way we could reject `break` if we are not directly in block/lambda/loop.
But then I realized that we can't properly collect stack elements (by doing something like `scopes.push(<scope name>)`) for post-loops:
```ruby
break while true
```
because the rule is
```
| stmt modifier_while expr_value
```
and adding something like `{ push_context(p, IN_LOOP) }` in front of it causes a ton of shift/reduce conflicts (which makes a lot of sense). Is it the reason why these cases are rejected during compilation?
If so, is there any simple way to reject it in the grammar? Maybe some kind of the AST post-processor? But then I guess we need a separate version for Ripper, right?
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>