zclparse: ParseZCL and ParseZCLFile methods
These are the top-level interface to parsing configuration files in the native zcl syntax, similarly to the existing methods for parsing other syntaxes.
This commit is contained in:
parent
e953e1c18a
commit
9348014b2d
@ -143,7 +143,7 @@ func TestParseConfig(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.input, func(t *testing.T) {
|
t.Run(test.input, func(t *testing.T) {
|
||||||
got, diags := ParseConfig([]byte(test.input), "", zcl.Pos{Byte: 0, Line: 1, Column: 1})
|
file, diags := ParseConfig([]byte(test.input), "", zcl.Pos{Byte: 0, Line: 1, Column: 1})
|
||||||
if len(diags) != test.diagCount {
|
if len(diags) != test.diagCount {
|
||||||
t.Errorf("wrong number of diagnostics %d; want %d", len(diags), test.diagCount)
|
t.Errorf("wrong number of diagnostics %d; want %d", len(diags), test.diagCount)
|
||||||
for _, diag := range diags {
|
for _, diag := range diags {
|
||||||
@ -151,6 +151,8 @@ func TestParseConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
got := file.Body
|
||||||
|
|
||||||
if !reflect.DeepEqual(got, test.want) {
|
if !reflect.DeepEqual(got, test.want) {
|
||||||
diff := prettyConfig.Compare(test.want, got)
|
diff := prettyConfig.Compare(test.want, got)
|
||||||
t.Errorf("wrong result\ninput: %s\ndiff: %s", test.input, diff)
|
t.Errorf("wrong result\ninput: %s\ndiff: %s", test.input, diff)
|
||||||
|
@ -5,14 +5,24 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ParseConfig parses the given buffer as a whole zcl config file, returning
|
// ParseConfig parses the given buffer as a whole zcl config file, returning
|
||||||
// a Body representing its contents. If HasErrors called on the returned
|
// a *zcl.File representing its contents. If HasErrors called on the returned
|
||||||
// diagnostics returns true, the returned body is likely to be incomplete
|
// diagnostics returns true, the returned body is likely to be incomplete
|
||||||
// and should therefore be used with care.
|
// and should therefore be used with care.
|
||||||
func ParseConfig(src []byte, filename string, start zcl.Pos) (*Body, zcl.Diagnostics) {
|
//
|
||||||
|
// The body in the returned file has dynamic type *zclsyntax.Body, so callers
|
||||||
|
// may freely type-assert this to get access to the full zclsyntax API in
|
||||||
|
// situations where detailed access is required. However, most common use-cases
|
||||||
|
// should be served using the zcl.Body interface to ensure compatibility with
|
||||||
|
// other configurationg syntaxes, such as JSON.
|
||||||
|
func ParseConfig(src []byte, filename string, start zcl.Pos) (*zcl.File, zcl.Diagnostics) {
|
||||||
tokens := LexConfig(src, filename, start)
|
tokens := LexConfig(src, filename, start)
|
||||||
peeker := newPeeker(tokens, false)
|
peeker := newPeeker(tokens, false)
|
||||||
parser := &parser{peeker: peeker}
|
parser := &parser{peeker: peeker}
|
||||||
return parser.ParseBody(TokenEOF)
|
body, diags := parser.ParseBody(TokenEOF)
|
||||||
|
return &zcl.File{
|
||||||
|
Body: body,
|
||||||
|
Bytes: src,
|
||||||
|
}, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseExpression parses the given buffer as a standalone zcl expression,
|
// ParseExpression parses the given buffer as a standalone zcl expression,
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
package zclparse
|
package zclparse
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/zclconf/go-zcl/zcl"
|
"github.com/zclconf/go-zcl/zcl"
|
||||||
"github.com/zclconf/go-zcl/zcl/hclhil"
|
"github.com/zclconf/go-zcl/zcl/hclhil"
|
||||||
"github.com/zclconf/go-zcl/zcl/json"
|
"github.com/zclconf/go-zcl/zcl/json"
|
||||||
|
"github.com/zclconf/go-zcl/zcl/zclsyntax"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NOTE: This is the public interface for parsing. The actual parsers are
|
// NOTE: This is the public interface for parsing. The actual parsers are
|
||||||
@ -24,6 +28,39 @@ type Parser struct {
|
|||||||
files map[string]*zcl.File
|
files map[string]*zcl.File
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseZCL parses the given buffer (which is assumed to have been loaded from
|
||||||
|
// the given filename) as a native-syntax configuration file and returns the
|
||||||
|
// zcl.File object representing it.
|
||||||
|
func (p *Parser) ParseZCL(src []byte, filename string) (*zcl.File, zcl.Diagnostics) {
|
||||||
|
if existing := p.files[filename]; existing != nil {
|
||||||
|
return existing, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return zclsyntax.ParseConfig(src, filename, zcl.Pos{Byte: 0, Line: 1, Column: 1})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseZCLFile reads the given filename and parses it as a native-syntax zcl
|
||||||
|
// configuration file. An error diagnostic is returned if the given file
|
||||||
|
// cannot be read.
|
||||||
|
func (p *Parser) ParseZCLFile(filename string) (*zcl.File, zcl.Diagnostics) {
|
||||||
|
if existing := p.files[filename]; existing != nil {
|
||||||
|
return existing, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
src, err := ioutil.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, zcl.Diagnostics{
|
||||||
|
{
|
||||||
|
Severity: zcl.DiagError,
|
||||||
|
Summary: "Failed to read file",
|
||||||
|
Detail: fmt.Sprintf("The configuration file %q could not be read.", filename),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.ParseZCL(src, filename)
|
||||||
|
}
|
||||||
|
|
||||||
// ParseJSON parses the given JSON buffer (which is assumed to have been loaded
|
// ParseJSON parses the given JSON buffer (which is assumed to have been loaded
|
||||||
// from the given filename) and returns the zcl.File object representing it.
|
// from the given filename) and returns the zcl.File object representing it.
|
||||||
func (p *Parser) ParseJSON(src []byte, filename string) (*zcl.File, zcl.Diagnostics) {
|
func (p *Parser) ParseJSON(src []byte, filename string) (*zcl.File, zcl.Diagnostics) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user