项目作者: node-bash

项目描述 :
The BashTree Spec.
高级语言:
项目地址: git://github.com/node-bash/bash-tree.git
创建时间: 2017-11-01T12:26:10Z
项目社区:https://github.com/node-bash/bash-tree

开源协议:MIT License

下载


The BashTree Spec

Node Objects

  1. interface Node {
  2. type: string
  3. loc: SourceLocation | null
  4. }
  1. interface SourceLocation {
  2. source: string | null
  3. start: Position
  4. end: Position
  5. }
  1. interface Position {
  2. line: number // 1-indexed
  3. column: number // 0-indexed
  4. }

Identifier

  1. interface Identifier : Node {
  2. type: "Identifier"
  3. name: string
  4. }

Program

  1. interface Program : Node {
  2. type: "Program"
  3. body: BlockStatement
  4. }

The whole bash program tree

BlockStatement

  1. interface BlockStatement : Node {
  2. type: "BlockStatement"
  3. body: [ Statement ]
  4. }

Redirection

#

TestOperation

  1. interface TestOperation {
  2. type: "TestOperation"
  3. operator: FileTestOperator | TestOperator
  4. left: Expression | null
  5. right: Expression
  6. }
  1. enum FileTestOperator {
  2. // TODO
  3. "-e"
  4. }
  1. enum TestOperator {
  2. // TODO
  3. "-eq"
  4. }

HereDocument

  1. interface HereDocument {
  2. type: "HereDocument"
  3. limitString: string
  4. // TODO: maybe substitution should be down at runtime, not at compiling
  5. documents: [ Literal | Substitution ]
  6. suppressLeadingTabs: boolean
  7. enableSubstitution: boolean
  8. }

ArithmeticOperation

UnaryOperation

  1. interface UnaryOperation : ArithmeticOperation {
  2. type: "UnaryOperation"
  3. operator: UnaryOperator
  4. prefix: boolean
  5. argument: Identifier
  6. }
  1. enum UnaryOperator {
  2. "-"
  3. }

UpdateOperation

  1. interface UpdateOperation : ArithmeticOperation {
  2. type: "UpdateOperation"
  3. operator: UpdateOperator
  4. argument: Identifier
  5. prefix: boolean
  6. }
  1. enum UpdateOperator {
  2. "++" | "--"
  3. }

BinaryOperation

  1. interface BinaryOperation : ArithmeticOperation {
  2. type: "BinaryOperation"
  3. operator: BinaryOperator
  4. left: Identifier
  5. }
  1. enum BinaryOperator {
  2. // TODO: more
  3. "+" | "-" | "*" | "/" |
  4. "**" | "%" |
  5. "+=" | "-=" | "*=" | "/=" | "%=" |
  6. "<<" | "<<=" | ">>" | ">>=" | "&" | "&=" | "|" | "|=" | "~" | "^" | "^="
  7. ">" | "<"
  8. }

ConditionalOperation

  1. // Ternary
  2. interface ConditionalOperation : ArithmeticOperation {
  3. type: "TernaryOperation"
  4. test: ArithmeticOperation
  5. alternate: Literal | ArithmeticOperation
  6. consequent: Literal | ArithmeticOperation
  7. }

LogicalOperation

  1. interface LogicalOperation : ArithmeticOperation {
  2. type: "LogicalOperation"
  3. operator: LogicalOperator
  4. left: ArithmeticOperation || null
  5. right: ArithmeticOperation
  6. }
  1. enum LogicalOperator {
  2. "||" | "&&" || "!"
  3. }

Statement

  1. interface Statement : Node {}

A statement is a thing that can stand alone.

SubShell

  1. interface SubShell : Statement {
  2. type: "SubShell"
  3. body: BlockStatement
  4. }

ArithmeticStatement

  1. // (( ))
  2. interface ArithmeticStatement : Statement {
  3. type: "ArithmeticStatement"
  4. operation: ArithmeticOperation
  5. }

Control Flow

Choice

IfStatement

  1. interface IfStatement : Statement {
  2. type: "IfStatement"
  3. test: ArithmeticStatement | Command | TestConstruct
  4. consequent: BlockStatement
  5. alternate: Statement | null
  6. kind: "elif" | "else if" | null
  7. }

CaseStatement

FunctionDeclaration

  1. interface FunctionDeclaration : Statement {
  2. type: "FunctionDeclaration"
  3. id: Identifier
  4. body: [ Statement ]
  5. }

A function declaration

VariableAssignment

  1. interface VariableAssignment : Statement {
  2. type: "VariableAssignment"
  3. // a=1 | a[1]=1
  4. left: Identifier | ArrayMemberConstruct
  5. right: Expression
  6. }

VariableDeclaration (?)

  1. interface VariableDeclaration : Statement {
  2. type: "VariableDeclaration"
  3. id: Identifier
  4. // declare -a a=1
  5. kind: "a" | "i" | "r" | "local"
  6. init: Expression | null
  7. }

Actually declare -a a=foo is a command, but it is better to be treated as a Statement due to its complication.

Command

  1. interface Command : Statement {
  2. type: "Command"
  3. name: string
  4. argv: Arguments
  5. }

Arguments

  1. interface Arguments {
  2. type: "Arguments"
  3. args: [ Expression ]
  4. }

The length of the arguments depends on the result of substitution

Construct

  1. interface Construct : Node {}

ArrayMemberConstruct

  1. interface MemberConstruct : Construct {
  2. type: "ArrayMemberConstruct"
  3. array: Identifier
  4. property: Literal
  5. }

TestConstruct

  1. interface TestConstruct {
  2. type: "TestConstruct"
  3. condition: Expression |
  4. // [] | [[]]
  5. kind: "test" | "extended"
  6. }

Expansion

BraceExpansion

  1. interface BraceExpansion : Expansion {
  2. type: "BraceExpansion"
  3. expansions: [ Literal ]
  4. prefix: Literal | Expansion
  5. suffix: Literal
  6. }

ExtendedBraceExpansion

  1. // {a..z}
  2. interface ExtendedBraceExpansion : Expansion {
  3. type: "ExtendedBraceExpansion"
  4. start: Literal
  5. end: Literal
  6. // foo{a..z} | {1..9}{a..z}
  7. prefix: Literal | Expansion
  8. suffix: Literal
  9. }

Expression

  1. interface Expression : Node {}

An expression is what can be assigned to identifiers or as the item of arguments.

Literal

  1. interface Literal : Expression {
  2. type: "Literal"
  3. // 'a'
  4. value: string
  5. // '"a"'
  6. raw: string
  7. }

ArrayExpression

  1. interface ArrayExpression : Expression {
  2. type: "ArrayExpression"
  3. elements: Arguments
  4. }

Substitution

CommandSubstitution

  1. interface CommandSubstitution : Expression {
  2. type: "CommandSubstitution"
  3. command: Command
  4. // `command -r` | $(command -r)
  5. kind: "backtick" | "bracket"
  6. }

StringSubstitution

  1. // "$a"
  2. interface StringSubstitution : Expression {
  3. type: "StringSubstitution"
  4. contents: [ Literal | VariableSubstitution ]
  5. }

VariableSubstitution

  1. // ${a:-default}
  2. interface VariableSubstitution : Expression {
  3. type: "VariableSubstitution"
  4. kind: "brace" | "no-brace"
  5. // null for positional variables
  6. id: Identifier | null
  7. pattern: VariableDirective | null
  8. }

ArithmeticSubstitution

  1. // $(( 2 + 3))
  2. interface ArithmeticSubstitution : Expression {
  3. type: "ArithmeticSubstitution"
  4. content: ArithmeticStatement
  5. }

ProcessSubstitution

  1. interface ProcessSubstitution : Expression {
  2. type: "ProcessSubstitution"
  3. command: Command
  4. // >() | <()
  5. kind: "in" | "out"
  6. }

VariableDirective

MemberAccessDirective

  1. interface MemberAccessDirective : VariableDirective {
  2. type: "MemberAccessDirective"
  3. property: Literal
  4. }

GetterDirective

  1. // value[kind]arg
  2. interface GetterDirective : VariableDirective {
  3. type: "GetterDirective"
  4. kind: "-" | ":-" | "=" | ":=" | "+" | ":+" | "?" | ":?"
  5. arg: Literal | Expression
  6. }

LengthDirective

  1. // #value[property]
  2. interface LengthDirective : VariableDirective {
  3. type: "LengthDirective"
  4. property: "*" | "@" | null
  5. }

CropDirective

  1. // value[kind]pattern
  2. interface CropDirective : VariableDirective {
  3. type: "CropDirective"
  4. pattern: Literal | Expression
  5. kind: "#" | "##" | "%" | "%%"
  6. }

SliceDirective

  1. // value:start[:end]
  2. interface SliceDirective : VariableDirective {
  3. type: "SliceDirective"
  4. start: Literal
  5. end: Literal | null
  6. }

ReplaceDirective

  1. // value/[kind]pattern/replacement
  2. interface ReplaceDirective : VariableDirective {
  3. type: "ReplaceDirective"
  4. pattern: Literal
  5. replacement: Literal
  6. kind: "/" | "#" | "%" | null
  7. }

SearchDirective

  1. // !value[kind]
  2. interface SearchDirective : VariableDirective {
  3. type: "SearchDirective"
  4. // the same
  5. kind: "*" | "@"
  6. }