Welcome to MSDN Blogs Sign in | Join | Help

PowerShell Grammar

A number of people have asked about the PowerShell grammar.  Here is a draft write up (I've also included it as an attachement) that George Xie and Bruce Payette are working on.

 

Grammar of PowerShell (formerly known as Monad)  is separated into parsing rules and tokenizing rules. Parsing rules in turn can be separated into 4 layers |

 

1.      Statement list: this includes statement list and statement blocks.

2.      Statement: this includes different statements

3.      Expression:

4.      Value

 

 

1. Statement List

 

<statementListRule> = <statementRule> [ <statementSeparatorToken> <statementRule> ]*

 

# this is a variation of statement list used mainly in script blocks.

<statementBlockRule> = '{' <statementListRule> '}'

 

2. Statement

 

# an aggregation rule for all statements.

<statementRule> = <ifStatementRule> |

                    <switchStatementRule> |

                    <foreachStatementRule> |

                    <forWhileStatementRule> |

                    <doWhileStatementRule> |

                    <functionDeclarationRule> |

                    <parameterDeclarationRule> |

                    <flowControlStatementRule> |

                    <trapStatementRule> |

                    <finallyStatementRule> |

                    <pipelineRule>

 

2.1 Pipeline

 

# A pipeline can look like

#   get-childitem -recurse -filter *.cs | sort name

#   2+2 |3 |4 | sort  # sort a literal array in a pipeline...

#   . profile.msh | count-object    # . source a script

#   & "c:\a path\with spaces.doc"   # execute a path with spaces in it

#   get-childitem | sort-object > c:/tmp/junk.txt  # use i/o redirection...

<pipelineRule> = <assignmentStatement> | <firstPipelineElement> [ '|' <cmdletCall> ]*

 

<assignmentStatementRule> = <lvalueExpression>

                            <AssignmentOperatorToken> <pipelineRule>

 

<lvalueExpression> := <lvalue> [? |? <lvalue>]*

 

<lvalue> :=  <simpleLvalue> <propertyOrArrayReferenceOperator>*

 

<simpleLvalue> := <AttributeSpecificationToken>* <variableToken>

 

<firstPipelineElement> = <expressionRule> | <cmdletCall>

 

<cmdletCall> = [ '&' | '.' | <empty> ] [ <name> | <expressionRule> ]

    [ <parameterToken> |

        <parameterArgumentToken> |

        <postfixOperatorRule> |

        <redirectionRule> ]*

 

<redirectionRule> = <redirectionOperatorToken> <propertyOrArrayReferenceRule>

 

2.2 If statement

 

<ifStatementRule> = 'if' '(' <pipelineRule> ')' <statementBlockRule>  [

                        'elseif' '(' <pipelineRule> ')' <statementBlockRule>

                    ]* [

                        'else' <statementBlockRule>

                    ]{0 |1}

             

2.3 Switch statement

 

# The syntax for a switch statement looks like:

#     switch -regex -casesensitive (get-childitem | sort length)

#     {

#         "^5"                  { "length for $_ started with 5" ; continue}

#         { $_.length > 20000 } { "length of $_ is greated than 20000" }

#         default               { "Didn't match anything else..." }

#     }

# Note that there can only be 1 default clause in a switch statement

<switchStatementRule> = 'switch' ['-regex' | '-wildcard' | '-exact' ]{0 |1}

                      ['-casesensitive']{0 |1}

                      ['-file' <propertyOrArrayReferenceRule> | '(' <pipelineRule> ')' ]

                      '{' [

                               [

                               'default' |

                               <ParameterArgumentToken> |

                               <propertyOrArrayReferenceRule> |

                               <statementBlockRule>

                               ]

                               <statementBlockRule>

                        ]+ '}'

 

2.4 Foreach statement

 

# Foreach statement looks like

#   foreach ($i in get-childitem | sort-object length) {

#       write-host $i ; $sum += $i.length }

<foreachStatementRule> = <LoopLabelToken>{0 |1} 'foreach'

                        '(' <variableToken>  'in' <pipelineRule> ')'

                            <statementBlockRule>

                           

2.5 Forwhile statement

 

# A while statement looks like

#   while ($i -lt 100) {

#       write-host $i

#       $i += 1

#   }

#

# A for statement looks like

#   for ($i=0; $i -lt 10; $i += 1) {

#   while ($i -lt 100) {

#       write-host $i

#       $i += 1

#   }

#

<forWhileStatementRule> =

        <LoopLabelToken>{0 |1} 'while' '(' <pipelineRule> ')' <statementBlockRule> |

        <LoopLabelToken>{0 |1} 'for' '(' <pipelineRule>{0 |1} ';'

             <pipelineRule>{0 |1} ';' <pipelineRule>{0 |1} ')' <statementBlockRule>

            

2.5 Dowhile statement

 

# A do/while statement looks like

#   do

#   {

#       write-host $i

#       $i += 1

#   } while ($i -lt 100)

#

# A do/until statement looks like

#   do

#   {

#       write-host $i

#       $i += 1

#   } until ($i -ge 100)

#

<doWhileStatementRule> =

        <LoopLabelToken>{0 |1} 'do' <statementBlockRule> ['while' | 'until'] '(' <pipelineRule> ')'

       

2.6 Trap statement

 

# A trap statement looks like

#   trap { ... }

# or

#   trap [system.nullreferenceexception] { ... }

#

<trapStatementRule> = 'trap' <AttributeSpecificationToken>{0 |1}

                    <statementBlockRule>

 

2.7 Finally statement                   

 

# A finally statement looks like

#   finally { ... }

#

<finallyStatementRule> = 'finally' <statementBlockRule>

 

2.8 flow control statement

 

# Flow control statements look like

#   break

#   break label

#   break $labelArray[2].name

#   return

#   return 13

#   return get-content | sort | pick-object -head 10

 

<flowControlStatementRule> =

    ['break' | 'continue'] [<propertyNameToken> | <propertyOrArrayReferenceRule>]{0 |1} |

    'return' <pipelineRule>

 

2.9 Function declaration   

 

# a function definition looks like

#   function foo { ... }

# or

#   filter foo { ... }

<functionDeclarationRule> = <FunctionDeclarationToken>

    <ParameterArgumentToken> [ '(' <parameterDeclarationExpressionRule> ')' ] <cmdletBodyRule>

 

# The following rule defines the grammar for a cmdlet (function/script/scriptblock) body

<cmdletBodyRule> =  '{' [ '(' <parameterDeclarationExpressionRule> ')' ] (

    [ 'begin' <statementBlock> | 'process' <statementBlock> | 'end' <statementBlock> ]* |

    <statementList> '}'

 

2.10 Parameter declaration

 

# a parameter definition looks like

#   param argumentList

<parameterDeclarationRule> =

    <ParameterDeclarationToken> '(' <parameterDeclarationExpressionRule> ')'

   

<parameterDeclarationExpressionRule> = <parameterWithIntializer> [ <CommaToken> <parameterWithIntializer> ]*

 

<parameterWithIntializer> = <simpleLvalue> [ '='  <expressionRule> ]

 

3. Expression

 

<expressionRule> = <logicalExpressionRule>

 

<logicalExpressionRule> = <bitwiseExpressionRule>

                        [<LogicalOperatorToken> <bitwiseExpressionRule>]*

 

<bitwiseExpressionRule> = <comparisonExpressionRule>

                        [ <BitwiseOperatorToken> <comparisonExpressionRule> ]*

                       

<comparisonExpressionRule> = <addExpressionRule>

                            [ <ComparisonOperatorToken> <addExpressionRule> ]*

                           

<addExpressionRule> = <multiplyExpressionRule>

                    [ <AdditionOperatorToken> <multiplyExpressionRule> ]*

                   

<multiplyExpressionRule> = <formatExpressionRule>

                        [ <MultiplyOperatorToken> <formatExpressionRule> ]

                       

<formatExpressionRule> = <rangeExpressionRule>

                        [ <FormatOperatorToken> <rangeExpressionRule> ]*

                       

<rangeExpressionRule> = <arrayLiteralRule>

                    [ <RangeOperatorToken> <arrayLiteralRule> ]*

 

<arrayLiteralRule> = <postfixOperatorRule> [ <CommaToken> <postfixOperatorRule> ]*

                   

<postfixOperatorRule> =     <lvalueExpression> <PrePostfixOperatorToken> |

                            <propertyOrArrayReferenceRule>

 

<propertyOrArrayReferenceRule> = <valueRule> <propertyOrArrayReferenceOperator>*

 

<propertyOrArrayReferenceOperator> = '[' <expressionRule> ']' ] |

                                     '.' [

                                         <PropertyNameToken> <parseCallRule>{0 |1} |

                                         <valueRule>

                                     ]

                           

<parseCallRule> = '(' <arrayLiteralRule> ')'

 

4. Value                                    

 

<valueRule> =   '(' <assignmentStatementRule> ')' |

                '$(' <statementListRule> ')' |

                '@(' <statementListRule> ')' |

                <cmdletBodyRule> |

                '@{' <hashLiteralRule> '}' |

Published Wednesday, May 10, 2006 2:51 AM by PowerShellTeam

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# paraesthesia

Wednesday, May 10, 2006 11:35 AM by paraesthesia

# re: PowerShell Grammar

Thank you :) Look forward to syntax support for Powershell in xacc.ide soon!
Thursday, May 11, 2006 2:24 PM by leppie

# Powershell grammar

Thursday, May 11, 2006 2:30 PM by xacc.ide

# CrittendenIV&#8217;s Worklog &raquo;

Friday, May 12, 2006 10:28 AM by CrittendenIV’s Worklog »

# re: PowerShell Grammar

Will there be something analogous to /dev/stdout and /dev/stdin ?
Friday, May 26, 2006 3:24 AM by whileloop

# PowerShell links

Here&amp;rsquo;s some great links on the new Windows PowerShell scripting language.
Verb Names
Grammar
Wednesday, May 31, 2006 11:45 AM by Rod Trent at myITforum.com

# re: PowerShell Grammar

This post looks a bit incomplete (valueRule trails off), and there is no attachment as suggested.

Is this information somewhere else?

Wednesday, February 07, 2007 7:29 AM by Adrian Milliner

# ps1.soapyfrog.com &raquo; Slow week

Friday, February 09, 2007 4:45 AM by ps1.soapyfrog.com » Slow week

# [INFO] Grammaire PowerShell | hilpers

Thursday, January 22, 2009 10:51 AM by [INFO] Grammaire PowerShell | hilpers

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker