Jay Bazuzi
Jay Bazuzi

Reputation: 46526

Why does PowerShell parse `$true -or $false` as `CommandElement`s?

In PowerShell, look at how statements with logical operators parsed:

> $ast = [System.Management.Automation.Language.Parser]::ParseInput( "($true) -and ($false)", [ref]$null, [ref]$null)
> $ast.EndBlock.Statements[0].PipelineElements[0].GetType().Name
CommandExpressionAst
> $ast.EndBlock.Statements[0].PipelineElements[0].Expression


Operator      : And
Left          : (True)
Right         : (False)
ErrorPosition : -and
StaticType    : System.Boolean
Extent        : (True) -and (False)
Parent        : (True) -and (False)

As expected, the AST sees this as a binary expression. However, if you remove the parentheses, it parses as a command.

> $true -or $false
True

> $ast = [System.Management.Automation.Language.Parser]::ParseInput( "$true -or $false", [ref]$null, [ref]$null)
> $ast.EndBlock.Statements[0].PipelineElements[0].Gettype().Name
CommandAst

> $ast.EndBlock.Statements[0].PipelineElements[0].CommandElements


StringConstantType : BareWord
Value              : True
StaticType         : System.String
Extent             : True
Parent             : True -or False

ParameterName : or
Argument      :
ErrorPosition : -or
Extent        : -or
Parent        : True -or False

StringConstantType : BareWord
Value              : False
StaticType         : System.String
Extent             : False
Parent             : True -or False

I studied the language grammar in the official PowerShell Language Specification, and I'm not seeing it - why is this a command, not an expression?

Upvotes: 3

Views: 3086

Answers (1)

Keith Hill
Keith Hill

Reputation: 201682

I'm guessing that you don't want PowerShell to evaluate the string before you pass it to ParseInput. In that case, use single quotes:

27> $ast = [System.Management.Automation.Language.Parser]::ParseInput( '$true -or $false', [ref]$null, [ref]$null)
28> $ast.EndBlock.Statements[0].PipelineElements[0].Expression


Operator      : Or
Left          : $true
Right         : $false
ErrorPosition : -or
StaticType    : System.Boolean
Extent        : $true -or $false
Parent        : $true -or $false

Upvotes: 3

Related Questions