Several changed and improvements

This commit is contained in:
Fatih Arslan 2015-10-26 01:34:41 +03:00
parent c9e7ec3621
commit 710dd69efb
6 changed files with 66 additions and 42 deletions

View File

@ -4,33 +4,33 @@ HCL is a lexer and parser family written in Go for
[HCL](https://github.com/hashicorp/hcl) (Hashicorp Configuration Language). It [HCL](https://github.com/hashicorp/hcl) (Hashicorp Configuration Language). It
has several components, similar to Go's own parser family. It provides a set of has several components, similar to Go's own parser family. It provides a set of
packages to write tools and customize files written in HCL. For example both packages to write tools and customize files written in HCL. For example both
[`hclfmt`](https://github.com/fatih/hclfmt) and `hcl2json` is written based on [`hclfmt`](https://github.com/fatih/hclfmt) and `hcl2json` (coming soon) is
these tools. written based on these tools.
## API ## API
If you are already familiar with Go's own parser family it's really easy to If you are already familiar with Go's own parser family it's really easy to
dive. It basically resembles the same logic. Howser there several differences dive. It basically resembles the same logic. However there are several differences
and the implemntation is completely different. Right now it contains the and the implementation is completely different. Right now it contains the
following packages: following packages:
* `token`: defines constants reresenting the lexical tokens for a scanned HCL file. * `token`: defines constants representing the lexical tokens for a scanned HCL file.
* `scanner`: scanner is a lexical scanner. It scans a given HCL file and * `scanner`: scanner is a lexical scanner. It scans a given HCL file and
returns a stream of tokens. returns a stream of tokens.
* `ast`: declares the types used to repesent the syntax tree for parsed HCL files. * `ast`: declares the types used to represent the syntax tree for parsed HCL files.
* `parser`: parses a given HCL file and creates a AST representation * `parser`: parses a given HCL file and creates a AST representation
* `printer`: prints any given ast node and formats * `printer`: prints any given AST node and formats
## Why did you create it? ## Why
The whole parser familiy was created because I wanted a proper `hclfmt` The whole parser family was created because I wanted a `hclfmt` command, which
command, which like `gofmt` formats a HCL file. I didn't want to use the like `gofmt` would format a HCL file. I didn't want to use the package
package [github/hashicorp/hcl](https://github.com/hashicorp/hcl) in the first [github/hashicorp/hcl](https://github.com/hashicorp/hcl) in the first place,
place, because the lexer and parser is generated and it doesn't expose any kind because the lexer and parser is generated and it doesn't expose any kind of
of flexibility. flexibility.
Another reason was that I wanted to learn and experience how to implement a Another reason was that I wanted to learn and experience how to implement a
proper lexer and parser in Go. It was really fun and I think it was worht it. proper lexer and parser in Go. It was really fun and I think it was worth it.
## License ## License

View File

@ -1,42 +1,41 @@
// This comes from Terraform, as a test
variable "foo" { variable "foo" {
default = "bar" default = "bar"
description = "bar" description = "bar"
} }
provider "aws" { provider "aws" {
access_key = "foo" access_key = "foo"
secret_key = "bar" secret_key = "bar"
} }
provider "do" { provider "do" {
api_key = "${var.foo}" api_key = "${var.foo}"
} }
resource "aws_security_group" "firewall" { resource "aws_security_group" "firewall" {
count = 5 count = 5
} }
resource aws_instance "web" { resource aws_instance "web" {
ami = "${var.foo}" ami = "${var.foo}"
security_groups = [ security_groups = [
"foo", "foo",
"${aws_security_group.firewall.foo}" "${aws_security_group.firewall.foo}",
] ]
network_interface = {
device_index = 0
description = "Main network interface"
}
network_interface { foo = ["faith", arslan]
device_index = 0
description = "Main network interface"
}
} }
resource "aws_instance" "db" { resource "aws_instance" "db" {
security_groups = "${aws_security_group.firewall.*.id}" security_groups = "${aws_security_group.firewall.*.id}"
VPC = "foo" VPC = "foo"
depends_on = ["aws_instance.web"]
depends_on = ["aws_instance.web"]
} }
output "web_ip" { output "web_ip" {
value = "${aws_instance.web.private_ip}" value = "${aws_instance.web.private_ip}"
} }

View File

@ -13,7 +13,7 @@ const (
tab = byte('\t') tab = byte('\t')
) )
// node // output prints creates a printable HCL output and returns it.
func (p *printer) output(n ast.Node) []byte { func (p *printer) output(n ast.Node) []byte {
var buf bytes.Buffer var buf bytes.Buffer

View File

@ -26,6 +26,7 @@ type entry struct {
var data = []entry{ var data = []entry{
{"complexhcl.input", "complexhcl.golden"}, {"complexhcl.input", "complexhcl.golden"},
{"list.input", "list.golden"}, {"list.input", "list.golden"},
{"comment.input", "comment.golden"},
} }
func TestFiles(t *testing.T) { func TestFiles(t *testing.T) {
@ -115,12 +116,6 @@ func format(src []byte) ([]byte, error) {
var buf bytes.Buffer var buf bytes.Buffer
// test with Spaces
// cfg := &Config{SpacesWidth: 4}
// if err := cfg.Fprint(&buf, node); err != nil {
// return nil, fmt.Errorf("print: %s", err)
// }
cfg := &Config{} cfg := &Config{}
if err := cfg.Fprint(&buf, node); err != nil { if err := cfg.Fprint(&buf, node); err != nil {
return nil, fmt.Errorf("print: %s", err) return nil, fmt.Errorf("print: %s", err)

15
printer/testdata/comment.golden vendored Normal file
View File

@ -0,0 +1,15 @@
// Foo
/* Bar */
/*
/*
Baz
*/
# Another
# Multiple
# Lines
foo = "bar"

15
printer/testdata/comment.input vendored Normal file
View File

@ -0,0 +1,15 @@
// Foo
/* Bar */
/*
/*
Baz
*/
# Another
# Multiple
# Lines
foo = "bar"