-
-
Notifications
You must be signed in to change notification settings - Fork 62
Add simple tutorial on common APIs #38
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# SyntaxTree Usage | ||
|
||
## Utilizing SyntaxTree's API | ||
|
||
Aside from providing a formatted view of AST nodes, SyntaxTree also provides access to information on each AST node. | ||
|
||
This quick tutorial will show you some common APIs in SyntaxTree. Keep in mind this is only a fraction of methods available to use and you can find more in the [official documentation](https://ruby-syntax-tree.github.io/syntax_tree/). | ||
|
||
Alright! Let's attain the `:+` operator in the following Ruby source code: | ||
|
||
```ruby | ||
require "syntax_tree" | ||
tree = SyntaxTree.parse("puts 1+1") | ||
``` | ||
|
||
Everything with a block of code inside of it has a list of statements represented by a `SyntaxTree::Statements` node. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here for example it's confusing if you don't know what kind of node is |
||
|
||
```ruby | ||
statements = tree.statements | ||
# => (statements (command (ident "puts") (args ((binary (int "1") :+ (int "1")))))) | ||
``` | ||
|
||
Let's extract the first (and only) statement of our source code that is a `SyntaxTree::Command` node, representing the `puts` method call. | ||
|
||
```ruby | ||
puts_command = statements.body.first | ||
# => (command (ident "puts") (args ((binary (int "1") :+ (int "1"))))) | ||
``` | ||
|
||
Using `#child_nodes` we can get an array of child nodes for any particular `SyntaxTree::Node`. In this case, the command node's child nodes are the method name and the arguments. | ||
|
||
We are only interested in the arguments, so we can use the instance method `#arguments` to access the `Syntax::Args` node directly. | ||
|
||
```ruby | ||
puts_command.child_nodes | ||
# => [(ident "puts"), (args ((binary (int "1") :+ (int "1"))))] | ||
|
||
args = puts_command.arguments | ||
# => (args ((binary (int "1") :+ (int "1")))) | ||
``` | ||
Comment on lines
+30
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should say this the other way around. The important info here is that you can access [(ident "puts"), (args ((binary (int "1") :+ (int "1"))))]
```">
Here, we are only interested in the arguments, so we can use the instance method `#arguments` to access the `Syntax::Args` node directly. ```ruby args = puts_command.arguments # => (args ((binary (int "1") :+ (int "1")))) ``` Note that we can also get an array of child nodes for any particular `SyntaxTree::Node` using `#child_nodes`. In this case, the command node's child nodes would be the method name and the arguments. ```ruby puts_command.child_nodes # => [(ident "puts"), (args ((binary (int "1") :+ (int "1"))))] ``` |
||
|
||
The `#parts` method returns an array of arguments. In this case, we want the first argument to access the `SyntaxTree::Binary` node. | ||
|
||
```ruby | ||
binary = args.parts.first | ||
# => [(binary (int "1") :+ (int "1"))] | ||
``` | ||
|
||
A `SyntaxTree::Binary` node represents an expression with two operands and an operator in between, and we can get the operator using the instance method `#operator`. | ||
|
||
```ruby | ||
binary.operator | ||
# => :+ | ||
``` | ||
|
||
Lastly, each node has a `SyntaxTree::Location` object, providing information on the row and column of the node. | ||
|
||
```ruby | ||
binary.location | ||
# => # |
||
``` | ||
|
||
## Visiting Nodes | ||
|
||
SyntaxTree allows you to perform additional operations on nodes through the [visitor pattern](https://en.wikipedia.org/wiki/Visitor_pattern). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can use the name of the node we get here:
This will help in the following example to explain where
statements
is coming from.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could also do a
pp program
and show the output in this doc so readers can follow along which nodes we're accessing? Or just show the output like you did in other code snippets:# => (program (statements (command (ident "puts") (args ((binary (int "1") :+ (int "1")))))))