Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 201
Jay Bazuzi Avatar asked Dec 07 '25 00:12

Jay Bazuzi


1 Answers

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
like image 184
Keith Hill Avatar answered Dec 08 '25 15:12

Keith Hill