2018-01-08 21:03:00 +01:00
|
|
|
package main
|
|
|
|
|
|
2018-01-09 00:21:35 +01:00
|
|
|
import (
|
2025-08-19 00:56:08 +02:00
|
|
|
"code.squareroundforest.org/arpio/treerack"
|
2025-08-20 00:45:32 +02:00
|
|
|
"encoding/json"
|
2026-01-15 23:33:40 +01:00
|
|
|
"io"
|
2018-01-09 00:21:35 +01:00
|
|
|
)
|
|
|
|
|
|
2018-01-10 00:44:14 +01:00
|
|
|
type showOptions struct {
|
2026-01-15 23:33:40 +01:00
|
|
|
|
|
|
|
|
// Syntax specifies the filename of the syntax definition file.
|
|
|
|
|
Syntax string
|
|
|
|
|
|
|
|
|
|
// SyntaxString specifies the syntax as an inline string.
|
|
|
|
|
SyntaxString string
|
|
|
|
|
|
|
|
|
|
// Input specifies the filename of the input content to be validated.
|
|
|
|
|
Input string
|
|
|
|
|
|
|
|
|
|
// InputString specifies the input content as an inline string.
|
|
|
|
|
InputString string
|
|
|
|
|
|
|
|
|
|
// Pretty enables indented, human-readable output.
|
|
|
|
|
Pretty bool
|
|
|
|
|
|
|
|
|
|
// Indent specifies a custom indentation string for the output.
|
|
|
|
|
Indent string
|
2018-01-09 00:21:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type node struct {
|
2026-01-15 23:33:40 +01:00
|
|
|
Name string `json:"name"`
|
|
|
|
|
From int `json:"from"`
|
|
|
|
|
To int `json:"to"`
|
|
|
|
|
Text string `json:"text,omitempty"`
|
|
|
|
|
Nodes []node `json:"nodes,omitempty"`
|
2018-01-09 00:21:35 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-15 23:33:40 +01:00
|
|
|
func mapNode(n *treerack.Node) node {
|
2018-01-09 00:21:35 +01:00
|
|
|
var nn node
|
|
|
|
|
nn.Name = n.Name
|
|
|
|
|
nn.From = n.From
|
|
|
|
|
nn.To = n.To
|
|
|
|
|
|
|
|
|
|
if len(n.Nodes) == 0 {
|
|
|
|
|
nn.Text = n.Text()
|
2026-01-15 23:33:40 +01:00
|
|
|
return nn
|
2018-01-09 00:21:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i := range n.Nodes {
|
|
|
|
|
nn.Nodes = append(nn.Nodes, mapNode(n.Nodes[i]))
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-15 23:33:40 +01:00
|
|
|
return nn
|
2018-01-09 00:21:35 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-15 23:33:40 +01:00
|
|
|
// show input content against a provided syntax definition and outputs the resulting AST (Abstract Syntax Tree)
|
|
|
|
|
// in JSON format. Syntax can be provided via a filename option or an inline string option. Input can be
|
|
|
|
|
// provided via a filename option, a positional argument filename, an inline string option, or piped from
|
|
|
|
|
// standard input.
|
|
|
|
|
func show(o showOptions, stdin io.Reader, stdout io.Writer, args ...string) error {
|
|
|
|
|
syntax, finalizeSyntax, err := initInput(o.Syntax, o.SyntaxString, nil, nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
2018-01-09 00:21:35 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-15 23:33:40 +01:00
|
|
|
defer finalizeSyntax()
|
|
|
|
|
input, finalizeInput, err := initInput(o.Input, o.InputString, stdin, args)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
2018-01-09 00:21:35 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-15 23:33:40 +01:00
|
|
|
defer finalizeInput()
|
|
|
|
|
s := &treerack.Syntax{}
|
|
|
|
|
if err := s.ReadSyntax(syntax); err != nil {
|
|
|
|
|
return err
|
2018-01-09 00:21:35 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-15 23:33:40 +01:00
|
|
|
if err := s.Init(); err != nil {
|
|
|
|
|
return err
|
2018-01-09 00:21:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
n, err := s.Parse(input)
|
|
|
|
|
if err != nil {
|
2026-01-15 23:33:40 +01:00
|
|
|
return err
|
2018-01-09 00:21:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nn := mapNode(n)
|
2026-01-15 23:33:40 +01:00
|
|
|
encode := json.Marshal
|
|
|
|
|
if o.Pretty || o.Indent != "" {
|
|
|
|
|
if o.Indent == "" {
|
|
|
|
|
o.Indent = " "
|
2018-01-09 00:21:35 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-15 23:33:40 +01:00
|
|
|
encode = func(a any) ([]byte, error) {
|
|
|
|
|
return json.MarshalIndent(a, "", o.Indent)
|
2018-01-09 00:21:35 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-15 23:33:40 +01:00
|
|
|
b, err := encode(nn)
|
2018-01-09 00:21:35 +01:00
|
|
|
if err != nil {
|
2026-01-15 23:33:40 +01:00
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if _, err := stdout.Write(b); err != nil {
|
|
|
|
|
return err
|
2018-01-09 00:21:35 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-15 23:33:40 +01:00
|
|
|
return nil
|
2018-01-08 21:03:00 +01:00
|
|
|
}
|