libparser

package module
v0.4.7-beta.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 18, 2025 License: ISC Imports: 12 Imported by: 2

README

Tomefile Parser

Library to parse Tomefile code and output a node tree for use by another program.

Features

Parsing

Parses the input file into a *libparser.NodeRoot{} including string segments.

Hooks

Allow to run custom libparser.Hook() functions on libparser.Node before it gets appended to the tree. Returns as soon as an error is encountered. Used to validate, discard or modify nodes.

Roadmap

Things that need to be done before v1:

  • Save context to Nodes and allow for partial parsing.
  • Partial parsing
  • Improve runtime string modifier evaluation (currently it just fails silently)
  • Multi-line arguments (...)
  • Revisit all of the code and make sure it's well-made (it isn't)
  • Better test coverage (Add more edge-cases where formatting isn't perfect)

Usage

Parsing a file:

// Close all files when all parsers have finished.
defer libparser.CloseAll()

file, err := libparser.OpenFile("example.tome")
if err != nil {
    panic(err)
}

parser := libparser.New(file)
parser.Hooks = []libparser.Hook{
    libparser.NoShebangHook,  // remove UNIX shebang, e.g. #!/bin/tome
    libparser.ExcludeHook[*libparser.NodeComment],  // by default, the parser includes ALL file contents, you can discard what's not needed.
}

if derr := parser.Run(); derr != nil {
    derr.Print(os.Stderr)
    os.Exit(1)
}

// [parser.Result] is [*libparser.NodeTree]
return parser.Result

Documentation

Index

Constants

This section is empty.

Variables

View Source
var EOA = &liberrors.DetailedError{Name: "EOA", Details: "End of Arguments"}
View Source
var EOB = &liberrors.DetailedError{Name: "EOB", Details: "End of Block"}
View Source
var EOF = &liberrors.DetailedError{Name: "EOF", Details: "End of File"}
View Source
var OpenedFiles = []File{}
View Source
var UNEXPECTED_EOF = &liberrors.DetailedError{Name: "EOF", Details: "Unexpected End of File"}

Functions

func CloseAll

func CloseAll()

Close all OpenedFiles.

Recommended to be defered in [main], e.g. `defer libparser.CloseAll()`.

func OpenFile

func OpenFile(path string) (*os.File, error)

Recommended way of opening files for parsing.

Use `defer CloseAll()` in [main] to make sure no files are closed before parsing is finished.

func ShouldStringBeQuoted

func ShouldStringBeQuoted(value string) bool

Types

type File

type File interface {
	io.Reader
	Name() string
	Close() error
}

The parts of *os.File that parser cares about

type Hook

type Hook func(original Node) (modified Node, derr *liberrors.DetailedError)

A function to be called on every Node before the parser attempts to append it to the tree.

Return `nil` to discard the Node.

func StreamHook

func StreamHook(channel chan Node) Hook

Puts the node to chan before it gets appended to the tree. Useful for tracking the progress of parsing in very large files.

Example usage:

channel := make(chan libparser.Node)

parser := libparser.New(file)
parser.Hooks = []libparser.Hook{
    libparser.StreamHook(channel),
}

go func() {
    defer close(channel) // IMPORTANT! Without this you'll hang the process FOREVER.
    if derr := parser.Run(); derr != nil {
        ...
    }
}()

for node := range channel {
    ...
}

type LiteralStringSegment

type LiteralStringSegment struct {
	Contents string
}

func (*LiteralStringSegment) Eval

func (segment *LiteralStringSegment) Eval(_ Locals) (string, error)

func (*LiteralStringSegment) Segment

func (segment *LiteralStringSegment) Segment() string

type Locals

type Locals map[string]string

type ModifierName

type ModifierName string
const (
	MOD_NOT          ModifierName = "not"
	MOD_TO_LOWER     ModifierName = "to_lower"
	MOD_TO_UPPER     ModifierName = "to_upper"
	MOD_TO_SNAKE     ModifierName = "to_snake"
	MOD_TO_KEBAB     ModifierName = "to_kebab"
	MOD_TO_CAMEL     ModifierName = "to_camel"
	MOD_TO_PASCAL    ModifierName = "to_pascal"
	MOD_TO_DELIMITED ModifierName = "to_delimited"
	MOD_DOES_EXIST   ModifierName = "does_exist"
	MOD_IS_EMPTY     ModifierName = "is_empty"
	MOD_IS_FILE      ModifierName = "is_file"
	MOD_IS_DIR       ModifierName = "is_dir"
	MOD_IS_SYMLINK   ModifierName = "is_symlink"
	MOD_LENGTH       ModifierName = "length"
	MOD_QUOTED       ModifierName = "quoted"
	MOD_TRIM         ModifierName = "trim"
	MOD_TRIM_PREFIX  ModifierName = "trim_prefix"
	MOD_TRIM_SUFFIX  ModifierName = "trim_suffix"
	MOD_PAD          ModifierName = "pad"
	MOD_PAD_LEFT     ModifierName = "pad_left"
	MOD_PAD_RIGHT    ModifierName = "pad_right"
	MOD_HAS_PREFIX   ModifierName = "has_prefix"
	MOD_HAS_SUFFIX   ModifierName = "has_suffix"
	MOD_SLICE        ModifierName = "slice"
	MOD_REVERSE      ModifierName = "reverse"
	MOD_INVERT       ModifierName = "invert"
	MOD_CONTAINS     ModifierName = "contains"
)

type Node

type Node interface {
	Context() NodeContext
	String() string
}

func ExcludeHook

func ExcludeHook[T Node](node Node) (Node, *liberrors.DetailedError)

Discards Nodes of type T

func NoShebangHook

func NoShebangHook(node Node) (Node, *liberrors.DetailedError)

Removes the UNIX shebang

type NodeArgs

type NodeArgs []Node

func (NodeArgs) String

func (args NodeArgs) String() string

type NodeCall

type NodeCall struct {
	Macro string
	NodeContext
	NodeArgs
}

func (*NodeCall) Context

func (node *NodeCall) Context() NodeContext

func (*NodeCall) String

func (node *NodeCall) String() string

type NodeChildren

type NodeChildren []Node

func (NodeChildren) String

func (children NodeChildren) String() string

type NodeComment

type NodeComment struct {
	Contents string
	NodeContext
}

func (*NodeComment) Context

func (node *NodeComment) Context() NodeContext

func (*NodeComment) String

func (node *NodeComment) String() string

type NodeContext

type NodeContext struct {
	OffsetStart, OffsetEnd uint
}

func (NodeContext) String

func (context NodeContext) String() string

type NodeDirective

type NodeDirective struct {
	Name string
	NodeContext
	NodeArgs
	NodeChildren
}

func (*NodeDirective) Context

func (node *NodeDirective) Context() NodeContext

func (*NodeDirective) String

func (node *NodeDirective) String() string

type NodeExec

type NodeExec struct {
	Name string
	NodeContext
	NodeArgs
}

func (*NodeExec) Context

func (node *NodeExec) Context() NodeContext

func (*NodeExec) String

func (node *NodeExec) String() string

type NodeLiteral

type NodeLiteral struct {
	Contents string
	NodeContext
}

func (*NodeLiteral) Context

func (node *NodeLiteral) Context() NodeContext

func (*NodeLiteral) String

func (node *NodeLiteral) String() string

func (*NodeLiteral) ToStringNode

func (node *NodeLiteral) ToStringNode() *NodeString

type NodePipe

type NodePipe struct {
	Source Node
	Dest   Node
	NodeContext
}

func (*NodePipe) Context

func (node *NodePipe) Context() NodeContext

func (*NodePipe) String

func (node *NodePipe) String() string

type NodeRedirect

type NodeRedirect struct {
	Source Node
	Stdin  *NodeString
	Stdout *NodeString
	Stderr *NodeString
	NodeContext
}

func (*NodeRedirect) Context

func (node *NodeRedirect) Context() NodeContext

func (*NodeRedirect) String

func (node *NodeRedirect) String() string

type NodeRoot

type NodeRoot struct {
	Tomes map[string]*NodeDirective
	NodeContext
	NodeChildren
}

func (*NodeRoot) Context

func (node *NodeRoot) Context() NodeContext

func (*NodeRoot) String

func (node *NodeRoot) String() string

type NodeString

type NodeString struct {
	Segments SegmentedString
	NodeContext
}

func NewSimpleNodeString

func NewSimpleNodeString(contents string) *NodeString

func (*NodeString) Context

func (node *NodeString) Context() NodeContext

func (*NodeString) Eval

func (node *NodeString) Eval(locals Locals) (string, error)

func (*NodeString) String

func (node *NodeString) String() string

type NodeWhitespace

type NodeWhitespace struct {
	IsLineBreak bool
	NodeContext
}

func (*NodeWhitespace) Context

func (node *NodeWhitespace) Context() NodeContext

func (*NodeWhitespace) String

func (node *NodeWhitespace) String() string

type Parser

type Parser struct {
	Parent *Parser
	File   File
	Result *NodeRoot
	Hooks  []Hook
	// contains filtered or unexported fields
}

func New

func New(file File) *Parser

func (*Parser) Run

func (parser *Parser) Run() *liberrors.DetailedError

type SegmentedString

type SegmentedString []StringSegment

func (SegmentedString) String

func (segments SegmentedString) String() string

type StringModifier

type StringModifier struct {
	Name ModifierName
	Args []*NodeString
	Call func(Locals, string) string
}

func GetModifier

func GetModifier(name ModifierName, args []*NodeString) (StringModifier, error)

func SortNotModifierToEnd

func SortNotModifierToEnd(modifiers []StringModifier) []StringModifier

func (StringModifier) MarshalJSON

func (modifier StringModifier) MarshalJSON() ([]byte, error)

func (StringModifier) String

func (modifier StringModifier) String() string

type StringSegment

type StringSegment interface {
	Segment() string
	Eval(Locals) (string, error)
}

type VariableStringSegment

type VariableStringSegment struct {
	Name       string
	Modifiers  []StringModifier
	IsOptional bool
}

func (*VariableStringSegment) Eval

func (segment *VariableStringSegment) Eval(locals Locals) (string, error)

func (*VariableStringSegment) Segment

func (segment *VariableStringSegment) Segment() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL