Documentation ¶
Overview ¶
Package syntax implements parsing and formatting of shell programs. It supports both POSIX Shell and Bash.
Example ¶
package main import ( "os" "strings" "mvdan.cc/sh/syntax" ) func main() { in := strings.NewReader("{ foo; bar; }") f, err := syntax.NewParser().Parse(in, "") if err != nil { return } syntax.NewPrinter().Print(os.Stdout, f) }
Output: { foo bar }
Index ¶
- Constants
- func BinaryNextLine(p *Printer)
- func Indent(spaces uint) func(*Printer)
- func KeepComments(p *Parser)
- func KeepPadding(p *Printer)
- func Simplify(n Node) bool
- func SwitchCaseIndent(p *Printer)
- func ValidName(val string) bool
- func Variant(l LangVariant) func(*Parser)
- func Walk(node Node, f func(Node) bool)
- type ArithmCmd
- type ArithmExp
- type ArithmExpr
- type ArrayElem
- type ArrayExpr
- type Assign
- type BinAritOperator
- type BinCmdOperator
- type BinTestOperator
- type BinaryArithm
- type BinaryCmd
- type BinaryTest
- type Block
- type CStyleLoop
- type CallExpr
- type CaseClause
- type CaseItem
- type CaseOperator
- type CmdSubst
- type Command
- type Comment
- type CoprocClause
- type DblQuoted
- type DeclClause
- type Expansion
- type ExtGlob
- type File
- type ForClause
- type FuncDecl
- type GlobOperator
- type IfClause
- type LangVariant
- type LetClause
- type Lit
- type Loop
- type Node
- type ParExpOperator
- type ParamExp
- type ParenArithm
- type ParenTest
- type ParseError
- type Parser
- type Pos
- type Printer
- type ProcOperator
- type ProcSubst
- type RedirOperator
- type Redirect
- type Replace
- type SglQuoted
- type Slice
- type Stmt
- type StmtList
- type Subshell
- type TestClause
- type TestExpr
- type TimeClause
- type UnAritOperator
- type UnTestOperator
- type UnaryArithm
- type UnaryTest
- type WhileClause
- type Word
- type WordIter
- type WordPart
Examples ¶
Constants ¶
const ( RdrOut = RedirOperator(rdrOut) + iota AppOut RdrIn RdrInOut DplIn DplOut ClbOut Hdoc DashHdoc WordHdoc RdrAll AppAll )
const ( CmdIn = ProcOperator(cmdIn) + iota CmdOut )
const ( GlobQuest = GlobOperator(globQuest) + iota GlobStar GlobPlus GlobAt GlobExcl )
const ( AndStmt = BinCmdOperator(andAnd) + iota OrStmt Pipe PipeAll )
const ( Break = CaseOperator(dblSemicolon) + iota Fallthrough Resume ResumeKorn )
const ( SubstPlus = ParExpOperator(plus) + iota SubstColPlus SubstMinus SubstColMinus SubstQuest SubstColQuest SubstAssgn SubstColAssgn RemSmallSuffix RemLargeSuffix RemSmallPrefix RemLargePrefix UpperFirst UpperAll LowerFirst LowerAll OtherParamOps )
const ( Not = UnAritOperator(exclMark) + iota Inc Dec Plus = UnAritOperator(plus) Minus = UnAritOperator(minus) )
const ( Add = BinAritOperator(plus) Sub = BinAritOperator(minus) Mul = BinAritOperator(star) Quo = BinAritOperator(slash) Rem = BinAritOperator(perc) Pow = BinAritOperator(power) Eql = BinAritOperator(equal) Gtr = BinAritOperator(rdrOut) Lss = BinAritOperator(rdrIn) Neq = BinAritOperator(nequal) Leq = BinAritOperator(lequal) Geq = BinAritOperator(gequal) And = BinAritOperator(and) Or = BinAritOperator(or) Xor = BinAritOperator(caret) Shr = BinAritOperator(appOut) Shl = BinAritOperator(hdoc) AndArit = BinAritOperator(andAnd) OrArit = BinAritOperator(orOr) Comma = BinAritOperator(comma) Quest = BinAritOperator(quest) Colon = BinAritOperator(colon) Assgn = BinAritOperator(assgn) AddAssgn = BinAritOperator(addAssgn) SubAssgn = BinAritOperator(subAssgn) MulAssgn = BinAritOperator(mulAssgn) QuoAssgn = BinAritOperator(quoAssgn) RemAssgn = BinAritOperator(remAssgn) AndAssgn = BinAritOperator(andAssgn) OrAssgn = BinAritOperator(orAssgn) XorAssgn = BinAritOperator(xorAssgn) ShlAssgn = BinAritOperator(shlAssgn) ShrAssgn = BinAritOperator(shrAssgn) )
const ( TsExists = UnTestOperator(tsExists) + iota TsRegFile TsDirect TsCharSp TsBlckSp TsNmPipe TsSocket TsSmbLink TsSticky TsGIDSet TsUIDSet TsGrpOwn TsUsrOwn TsModif TsRead TsWrite TsExec TsNoEmpty TsFdTerm TsEmpStr TsNempStr TsOptSet TsVarSet TsRefVar TsNot = UnTestOperator(exclMark) )
const ( TsReMatch = BinTestOperator(tsReMatch) + iota TsNewer TsOlder TsDevIno TsEql TsNeq TsLeq TsGeq TsLss TsGtr AndTest = BinTestOperator(andAnd) OrTest = BinTestOperator(orOr) TsMatch = BinTestOperator(equal) TsNoMatch = BinTestOperator(nequal) TsBefore = BinTestOperator(rdrIn) TsAfter = BinTestOperator(rdrOut) )
Variables ¶
This section is empty.
Functions ¶
func BinaryNextLine ¶
func BinaryNextLine(p *Printer)
BinaryNextLine will make binary operators appear on the next line when a binary command, such as a pipe, spans multiple lines. A backslash will be used.
func Indent ¶
Indent sets the number of spaces used for indentation. If set to 0, tabs will be used instead.
func KeepComments ¶
func KeepComments(p *Parser)
KeepComments makes the parser parse comments and attach them to nodes, as opposed to discarding them.
func KeepPadding ¶
func KeepPadding(p *Printer)
KeepPadding will keep most nodes and tokens in the same column that they were in the original source. This allows the user to decide how to align and pad their code with spaces.
Note that this feature is best-effort and will only keep the alignment stable, so it may need some human help the first time it is run.
func Simplify ¶
Simplify simplifies a given program and returns whether any changes were made.
The changes currently applied are:
Remove clearly useless parentheses $(( (expr) )) Remove dollars from vars in exprs (($var)) Remove duplicate subshells $( (stmts) ) Remove redundant quotes [[ "$var" == str ]] Merge negations with unary operators [[ ! -n $var ]] Use single quotes to shorten literals "\$foo"
This function is EXPERIMENTAL; it may change or disappear at any point until this notice is removed.
func SwitchCaseIndent ¶
func SwitchCaseIndent(p *Printer)
SwitchCaseIndent will make switch cases be indented. As such, switch case bodies will be two levels deeper than the switch itself.
func Variant ¶
func Variant(l LangVariant) func(*Parser)
Variant changes the shell language variant that the parser will accept.
func Walk ¶
Walk traverses an AST in depth-first order: It starts by calling f(node); node must not be nil. If f returns true, Walk invokes f recursively for each of the non-nil children of node, followed by f(nil).
Example ¶
package main import ( "os" "strings" "mvdan.cc/sh/syntax" ) func main() { in := strings.NewReader(`echo $foo "and $bar"`) f, err := syntax.NewParser().Parse(in, "") if err != nil { return } syntax.Walk(f, func(node syntax.Node) bool { switch x := node.(type) { case *syntax.ParamExp: x.Param.Value = strings.ToUpper(x.Param.Value) } return true }) syntax.NewPrinter().Print(os.Stdout, f) }
Output: echo $FOO "and $BAR"
Types ¶
type ArithmCmd ¶
type ArithmCmd struct {
Left, Right Pos
Unsigned bool // mksh's ((# expr))
X ArithmExpr
}
ArithmCmd represents an arithmetic command.
This node will only appear in LangBash and LangMirBSDKorn.
type ArithmExp ¶
type ArithmExp struct {
Left, Right Pos
Bracket bool // deprecated $[expr] form
Unsigned bool // mksh's $((# expr))
X ArithmExpr
}
ArithmExp represents an arithmetic expansion.
type ArithmExpr ¶
type ArithmExpr interface { Node // contains filtered or unexported methods }
ArithmExpr represents all nodes that form arithmetic expressions.
These are *BinaryArithm, *UnaryArithm, *ParenArithm, and *Word.
type ArrayElem ¶
type ArrayElem struct { Index ArithmExpr // [i]=, ["k"]= Value *Word Comments []Comment }
ArrayElem represents a Bash array element.
type ArrayExpr ¶
ArrayExpr represents a Bash array expression.
This node will only appear with LangBash.
type Assign ¶
type Assign struct { Append bool // += Naked bool // without '=' Name *Lit Index ArithmExpr // [i], ["k"] Value *Word // =val Array *ArrayExpr // =(arr) }
Assign represents an assignment to a variable.
Here and elsewhere, Index can either mean an index into an indexed or an associative array. In the former, it's just an arithmetic expression. In the latter, it will be a word with a single DblQuoted part.
If Index is non-nil, the value will be a word and not an array as nested arrays are not allowed.
If Naked is true, it's part of a DeclClause and doesn't contain a value. In that context, if the name wasn't a literal, it will be in Value instead of Name.
type BinAritOperator ¶
type BinAritOperator token
func (BinAritOperator) String ¶
func (o BinAritOperator) String() string
type BinCmdOperator ¶
type BinCmdOperator token
func (BinCmdOperator) String ¶
func (o BinCmdOperator) String() string
type BinTestOperator ¶
type BinTestOperator token
func (BinTestOperator) String ¶
func (o BinTestOperator) String() string
type BinaryArithm ¶
type BinaryArithm struct { OpPos Pos Op BinAritOperator X, Y ArithmExpr }
BinaryArithm represents a binary expression between two arithmetic expression.
If Op is any assign operator, X will be a word with a single *Lit whose value is a valid name.
Ternary operators like "a ? b : c" are fit into this structure. Thus, if Op == Quest, Y will be a *BinaryArithm with Op == Colon. Op can only be Colon in that scenario.
func (*BinaryArithm) End ¶
func (b *BinaryArithm) End() Pos
func (*BinaryArithm) Pos ¶
func (b *BinaryArithm) Pos() Pos
type BinaryCmd ¶
type BinaryCmd struct { OpPos Pos Op BinCmdOperator X, Y *Stmt }
BinaryCmd represents a binary expression between two statements.
type BinaryTest ¶
type BinaryTest struct { OpPos Pos Op BinTestOperator X, Y TestExpr }
BinaryTest represents a binary expression between two arithmetic expression.
func (*BinaryTest) End ¶
func (b *BinaryTest) End() Pos
func (*BinaryTest) Pos ¶
func (b *BinaryTest) Pos() Pos
type CStyleLoop ¶
type CStyleLoop struct {
Lparen, Rparen Pos
Init, Cond, Post ArithmExpr
}
CStyleLoop represents the behaviour of a for clause similar to the C language.
This node will only appear with LangBash.
func (*CStyleLoop) End ¶
func (c *CStyleLoop) End() Pos
func (*CStyleLoop) Pos ¶
func (c *CStyleLoop) Pos() Pos
type CallExpr ¶
CallExpr represents a command execution or function call, otherwise known as a simple command.
If Args is empty, Assigns apply to the shell environment. Otherwise, they only apply to the call.
type CaseClause ¶
CaseClause represents a case (switch) clause.
func (*CaseClause) End ¶
func (c *CaseClause) End() Pos
func (*CaseClause) Pos ¶
func (c *CaseClause) Pos() Pos
type CaseItem ¶
type CaseItem struct { Op CaseOperator OpPos Pos Comments []Comment Patterns []*Word StmtList }
CaseItem represents a pattern list (case) within a CaseClause.
type CaseOperator ¶
type CaseOperator token
func (CaseOperator) String ¶
func (o CaseOperator) String() string
type CmdSubst ¶
type CmdSubst struct {
Left, Right Pos
StmtList
TempFile bool // mksh's ${ foo;}
ReplyVar bool // mksh's ${|foo;}
}
CmdSubst represents a command substitution.
type Command ¶
type Command interface { Node // contains filtered or unexported methods }
Command represents all nodes that are simple or compound commands, including function declarations.
These are *CallExpr, *IfClause, *WhileClause, *ForClause, *CaseClause, *Block, *Subshell, *BinaryCmd, *FuncDecl, *ArithmCmd, *TestClause, *DeclClause, *LetClause, *TimeClause, and *CoprocClause.
type CoprocClause ¶
CoprocClause represents a Bash coproc clause.
This node will only appear with LangBash.
func (*CoprocClause) End ¶
func (c *CoprocClause) End() Pos
func (*CoprocClause) Pos ¶
func (c *CoprocClause) Pos() Pos
type DeclClause ¶
type DeclClause struct { // Variant is one of "declare", "local", "export", "readonly", // "typeset", or "nameref". Variant *Lit Opts []*Word Assigns []*Assign }
DeclClause represents a Bash declare clause.
This node will only appear with LangBash.
func (*DeclClause) End ¶
func (d *DeclClause) End() Pos
func (*DeclClause) Pos ¶
func (d *DeclClause) Pos() Pos
type Expansion ¶
type Expansion struct { Op ParExpOperator Word *Word }
Expansion represents string manipulation in a ParamExp other than those covered by Replace.
type ExtGlob ¶
type ExtGlob struct { OpPos Pos Op GlobOperator Pattern *Lit }
ExtGlob represents a Bash extended globbing expression. Note that these are parsed independently of whether shopt has been called or not.
This node will only appear in LangBash and LangMirBSDKorn.
type FuncDecl ¶
type FuncDecl struct { Position Pos RsrvWord bool // non-posix "function f()" style Name *Lit Body *Stmt }
FuncDecl represents the declaration of a function.
type GlobOperator ¶
type GlobOperator token
func (GlobOperator) String ¶
func (o GlobOperator) String() string
type IfClause ¶
type IfClause struct { Elif bool IfPos Pos // pos of "elif" if Elif == true ThenPos Pos ElsePos Pos // pos of "elif" if FollowedByElif() == true FiPos Pos // empty if Elif == true Cond StmtList Then StmtList Else StmtList }
IfClause represents an if statement.
func (*IfClause) FollowedByElif ¶
FollowedByElif reports whether this IfClause is followed by an "elif" IfClause in its Else branch. This is true if Else.Stmts has exactly one statement with an IfClause whose Elif field is true.
type LangVariant ¶
type LangVariant int
const ( LangBash LangVariant = iota LangPOSIX LangMirBSDKorn )
type LetClause ¶
type LetClause struct { Let Pos Exprs []ArithmExpr }
LetClause represents a Bash let clause.
This node will only appear in LangBash and LangMirBSDKorn.
type Loop ¶
type Loop interface { Node // contains filtered or unexported methods }
Loop holds either *WordIter or *CStyleLoop.
type Node ¶
type Node interface { // Pos returns the position of the first character of the node. // Comments are ignored. Pos() Pos // End returns the position of the character immediately after // the node. If the character is a newline, the line number // won't cross into the next line. Comments are ignored. End() Pos }
Node represents an AST node.
type ParExpOperator ¶
type ParExpOperator token
func (ParExpOperator) String ¶
func (o ParExpOperator) String() string
type ParamExp ¶
type ParamExp struct {
Dollar, Rbrace Pos
Short bool // $a instead of ${a}
Excl bool // ${!a}
Length bool // ${#a}
Width bool // ${%a}
Param *Lit
Index ArithmExpr // ${a[i]}, ${a["k"]}
Slice *Slice // ${a:x:y}
Repl *Replace // ${a/x/y}
Exp *Expansion // ${a:-b}, ${a#b}, etc
}
ParamExp represents a parameter expansion.
type ParenArithm ¶
type ParenArithm struct {
Lparen, Rparen Pos
X ArithmExpr
}
ParenArithm represents an expression within parentheses inside an ArithmExp.
func (*ParenArithm) End ¶
func (p *ParenArithm) End() Pos
func (*ParenArithm) Pos ¶
func (p *ParenArithm) Pos() Pos
type ParseError ¶
ParseError represents an error found when parsing a source file.
func (*ParseError) Error ¶
func (e *ParseError) Error() string
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser holds the internal state of the parsing mechanism of a program.
func (*Parser) Parse ¶
Parse reads and parses a shell program with an optional name. It returns the parsed program if no issues were encountered. Otherwise, an error is returned. Reads from r are buffered.
Parse can be called more than once, but not concurrently. That is, a Parser can be reused once it is done working.
type Pos ¶
type Pos struct {
// contains filtered or unexported fields
}
Pos is a position within a source file.
func (Pos) IsValid ¶ added in v0.6.0
IsValid reports whether the position is valid. All positions in nodes returned by Parse are valid.
type Printer ¶
type Printer struct {
// contains filtered or unexported fields
}
Printer holds the internal state of the printing mechanism of a program.
func NewPrinter ¶
NewPrinter allocates a new Printer and applies any number of options.
type ProcOperator ¶
type ProcOperator token
func (ProcOperator) String ¶
func (o ProcOperator) String() string
type ProcSubst ¶
type ProcSubst struct {
OpPos, Rparen Pos
Op ProcOperator
StmtList
}
ProcSubst represents a Bash process substitution.
This node will only appear with LangBash.
type RedirOperator ¶
type RedirOperator token
func (RedirOperator) String ¶
func (o RedirOperator) String() string
type Redirect ¶
type Redirect struct { OpPos Pos Op RedirOperator N *Lit // N> Word *Word // >word Hdoc *Word // here-document body }
Redirect represents an input/output redirection.
type Slice ¶
type Slice struct {
Offset, Length ArithmExpr
}
Slice represents character slicing inside a ParamExp.
This node will only appear in LangBash and LangMirBSDKorn.
type Stmt ¶
type Stmt struct { Comments []Comment Cmd Command Position Pos Semicolon Pos Negated bool // ! stmt Background bool // stmt & Coprocess bool // mksh's |& Redirs []*Redirect // stmt >a <b }
Stmt represents a statement. It is compromised of a command and other components that may come before or after it.
type StmtList ¶
StmtList is a list of statements with any number of trailing comments. Both lists can be empty.
type Subshell ¶
Subshell represents a series of commands that should be executed in a nested shell environment.
type TestClause ¶
TestClause represents a Bash extended test clause.
This node will only appear in LangBash and LangMirBSDKorn.
func (*TestClause) End ¶
func (t *TestClause) End() Pos
func (*TestClause) Pos ¶
func (t *TestClause) Pos() Pos
type TestExpr ¶
type TestExpr interface { Node // contains filtered or unexported methods }
TestExpr represents all nodes that form arithmetic expressions.
These are *BinaryTest, *UnaryTest, *ParenTest, and *Word.
type TimeClause ¶
TimeClause represents a Bash time clause.
This node will only appear in LangBash and LangMirBSDKorn.
func (*TimeClause) End ¶
func (c *TimeClause) End() Pos
func (*TimeClause) Pos ¶
func (c *TimeClause) Pos() Pos
type UnAritOperator ¶
type UnAritOperator token
func (UnAritOperator) String ¶
func (o UnAritOperator) String() string
type UnTestOperator ¶
type UnTestOperator token
func (UnTestOperator) String ¶
func (o UnTestOperator) String() string
type UnaryArithm ¶
type UnaryArithm struct { OpPos Pos Op UnAritOperator Post bool X ArithmExpr }
UnaryArithm represents an unary expression over a node, either before or after it.
If Op is Inc or Dec, X will be a word with a single *Lit whose value is a valid name.
func (*UnaryArithm) End ¶
func (u *UnaryArithm) End() Pos
func (*UnaryArithm) Pos ¶
func (u *UnaryArithm) Pos() Pos
type UnaryTest ¶
type UnaryTest struct { OpPos Pos Op UnTestOperator X TestExpr }
UnaryTest represents an unary expression over a node, either before or after it.
type WhileClause ¶
WhileClause represents a while or an until clause.
func (*WhileClause) End ¶
func (w *WhileClause) End() Pos
func (*WhileClause) Pos ¶
func (w *WhileClause) Pos() Pos
type Word ¶
type Word struct {
Parts []WordPart
}
Word represents a non-empty list of nodes that are contiguous to each other. The word is delimeted by word boundaries.