2

以下类型显然非常大,因此手动编写代码将其转换为可读形式将是乏味的。我想知道以可读形式显示树的最简单方法。

type Element =
| Nil
| Token of Token
| Expression of Element * Element
| ExpressionNoIn of Element * Element
| AssignmentExpression of Element * AssignmentOperator * Element
| AssignmentExpressionNoIn of Element * AssignmentOperator * Element
| ConditionalExpression of Element * Element * Element
| ConditionalExpressionNoIn of Element * Element * Element
| LogicalORExpression of Element * Element
| LogicalORExpressionNoIn of Element * Element
| LogicalANDExpression of Element * Element
| LogicalANDExpressionNoIn of Element * Element
| BitwiseORExpression of Element * Element
| BitwiseORExpressionNoIn of Element * Element
| BitwiseXORExpression of Element * Element
| BitwiseXORExpressionNoIn of Element * Element
| BitwiseANDExpression of Element * Element
| BitwiseANDExpressionNoIn of Element * Element
| EqualityExpression of Element * EqualityOperator * Element
| EqualityExpressionNoIn of Element * EqualityOperator * Element
| RelationalExpression of Element * RelationalOperator * Element
| RelationalExpressionNoIn of Element * RelationalOperator * Element
| ShiftExpression of Element * BitwiseShiftOperator * Element
| AdditiveExpression of Element * AdditiveOperator * Element
| MultiplicativeExpression of Element * MultiplicativeOperator * Element
| UnaryExpression of UnaryOperator * Element
| PostfixExpression of Element * PostfixOperator
| MemberExpression of Element * Element
| Arguments of Element * Element
| ArgumentList of Element
| CallExpression of Element * Element
| NewExpression of NewOperator * Element
| LeftHandSideExpression of Element
| PrimaryExpression of Element
| ObjectLiteral of Element
| PropertyNameAndValueList of Element * Element
| PropertyAssignment of Element * Element * Element 
| PropertyName of Element
| PropertySetParameterList of Element
| ArrayLiteral of Element * Element
| Elision of Element * Element
| ElementList of Element * Element * Element     
| Statement of Element
| Block of Element
| StatementList of Element * Element
| VariableStatement of Element
| VariableDeclarationList of Element * Element
| VariableDeclarationListNoIn of Element * Element
| VariableDeclaration of Element * Element
| VariableDeclarationNoIn of Element * Element
| Initialiser of Element
| InitialiserNoIn of Element
| EmptyStatement
| ExpressionStatement of Element
| IfStatement of Element * Element * Element 
| IterationStatement of Element * Element * Element * Element
| ContinueStatement of Element
| BreakStatement of Element
| ReturnStatement of Element
| WithStatement of Element * Element
| SwitchStatement of Element * Element
| CaseBlock of Element * Element * Element
| CaseClauses of Element * Element
| CaseClause of Element * Element
| DefaultClause of Element
| LabelledStatement of Element * Element
| ThrowStatement of Element
| TryStatement of Element * Element * Element
| Catch of Element * Element
| Finally of Element
| DebuggerStatement    
| FunctionDeclaration of Element * Element * Element
| FunctionExpression of Element * Element * Element
| FormalParameterList of Element * Element
| FunctionBody of Element    
| SourceElement of Element
| SourceElements of Element * Element
| Program of Element

这是如何显示的示例。(这与我前一段时间制作的有点不同。)

<Expression>
  <AssignmentExpression>
    <ConditionalExpression>
      <LogicalORExpression>
        <LogicalORExpression>
          <LogicalANDExpression>
            <BitwiseORExpression>
              <BitwiseXORExpression>
                <BitwiseANDExpression>
                  <EqualityExpression>
                    <EqualityExpression>
                      <RelationalExpression>
                        <ShiftExpression>
                          <AdditiveExpression>
                            <MultiplicativeExpression>
                              <MultiplicativeExpression>
                                <UnaryExpression>
                                  <PostfixExpression>
                                    <LeftHandSideExpression>
                                      <NewExpression>
                                        <MemberExpression>
                                          <PrimaryExpression>
                                            <TokenNode Value="i" Line="9" Column="13" />
                                          </PrimaryExpression>
                                        </MemberExpression>
                                      </NewExpression>
                                    </LeftHandSideExpression>
                                  </PostfixExpression>
                                </UnaryExpression>
                              </MultiplicativeExpression>
                              <TokenNode Value="%" Line="9" Column="15" />
                              <UnaryExpression>
                                <PostfixExpression>
                                  <LeftHandSideExpression>
                                    <NewExpression>
                                      <MemberExpression>
                                        <PrimaryExpression>
                                          <TokenNode Value="3" Line="9" Column="17" />
                                        </PrimaryExpression>
                                      </MemberExpression>
                                    </NewExpression>
                                  </LeftHandSideExpression>
                                </PostfixExpression>
                              </UnaryExpression>
                            </MultiplicativeExpression>
                          </AdditiveExpression>
                        </ShiftExpression>
                      </RelationalExpression>
                    </EqualityExpression>
                    <TokenNode Value="===" Line="9" Column="19" />
                    <RelationalExpression>
                      <ShiftExpression>
                        <AdditiveExpression>
                          <MultiplicativeExpression>
                            <UnaryExpression>
                              <PostfixExpression>
                                <LeftHandSideExpression>
                                  <NewExpression>
                                    <MemberExpression>
                                      <PrimaryExpression>
                                        <TokenNode Value="0" Line="9" Column="23" />
                                      </PrimaryExpression>
                                    </MemberExpression>
                                  </NewExpression>
                                </LeftHandSideExpression>
                              </PostfixExpression>
                            </UnaryExpression>
                          </MultiplicativeExpression>
                        </AdditiveExpression>
                      </ShiftExpression>
                    </RelationalExpression>
                  </EqualityExpression>
                </BitwiseANDExpression>
              </BitwiseXORExpression>
            </BitwiseORExpression>
          </LogicalANDExpression>
        </LogicalORExpression>
        <TokenNode Value="||" Line="9" Column="25" />
        <LogicalANDExpression>
          <BitwiseORExpression>
            <BitwiseXORExpression>
              <BitwiseANDExpression>
                <EqualityExpression>
                  <EqualityExpression>
                    <RelationalExpression>
                      <ShiftExpression>
                        <AdditiveExpression>
                          <MultiplicativeExpression>
                            <MultiplicativeExpression>
                              <UnaryExpression>
                                <PostfixExpression>
                                  <LeftHandSideExpression>
                                    <NewExpression>
                                      <MemberExpression>
                                        <PrimaryExpression>
                                          <TokenNode Value="i" Line="9" Column="28" />
                                        </PrimaryExpression>
                                      </MemberExpression>
                                    </NewExpression>
                                  </LeftHandSideExpression>
                                </PostfixExpression>
                              </UnaryExpression>
                            </MultiplicativeExpression>
                            <TokenNode Value="%" Line="9" Column="30" />
                            <UnaryExpression>
                              <PostfixExpression>
                                <LeftHandSideExpression>
                                  <NewExpression>
                                    <MemberExpression>
                                      <PrimaryExpression>
                                        <TokenNode Value="5" Line="9" Column="32" />
                                      </PrimaryExpression>
                                    </MemberExpression>
                                  </NewExpression>
                                </LeftHandSideExpression>
                              </PostfixExpression>
                            </UnaryExpression>
                          </MultiplicativeExpression>
                        </AdditiveExpression>
                      </ShiftExpression>
                    </RelationalExpression>
                  </EqualityExpression>
                  <TokenNode Value="===" Line="9" Column="34" />
                  <RelationalExpression>
                    <ShiftExpression>
                      <AdditiveExpression>
                        <MultiplicativeExpression>
                          <UnaryExpression>
                            <PostfixExpression>
                              <LeftHandSideExpression>
                                <NewExpression>
                                  <MemberExpression>
                                    <PrimaryExpression>
                                      <TokenNode Value="0" Line="9" Column="38" />
                                    </PrimaryExpression>
                                  </MemberExpression>
                                </NewExpression>
                              </LeftHandSideExpression>
                            </PostfixExpression>
                          </UnaryExpression>
                        </MultiplicativeExpression>
                      </AdditiveExpression>
                    </ShiftExpression>
                  </RelationalExpression>
                </EqualityExpression>
              </BitwiseANDExpression>
            </BitwiseXORExpression>
          </BitwiseORExpression>
        </LogicalANDExpression>
      </LogicalORExpression>
    </ConditionalExpression>
  </AssignmentExpression>
</Expression>
4

1 回答 1

3

如果您想编写不需要列出所有联合情况的通用联合处理代码,那么您可能需要使用 F# 反射 API。这是一个简单的例子。

formatUnion函数使用 F# 反射。它假定类型参数'T是联合类型,并用于GetUnionFields获取包含当前案例名称和参数的元组。它打印当前案例名称并遍历所有参数。如果某些参数是类型的值'T(意味着它是递归联合),我们递归地打印有关该值的信息:

let rec formatUnion indent (value:'T) = //' 
  // Get name and arguments of the current union case
  let info, args = Reflection.FSharpValue.GetUnionFields(value, typeof<'T>) //'
  // Print current name (with some indentation)
  printfn "%s%s" indent info.Name
  for a in args do
    match box a with 
    | :? 'T as v ->  
      // Recursive use of the same union type..
      formatUnion (indent + "  ") v
    | _ -> ()

以下示例在一个非常简单的联合值上运行该函数:

type Element = | Nil | And of Element * Element | Or of Element * Element
formatUnion "" (And(Nil, Or(Nil, Nil)))

// Here is the expected output:
// And
//   Nil
//   Or
//     Nil
//     Nil

作为旁注,我认为您可以通过为BinaryOperatorand UnaryOperator(带有一个附加参数)而不是显式列出所有元素类型来在很大程度上简化您的有区别的联合。那么您可能可以直接实现该功能,因为它会非常简单。就像是:

type BinaryOperator = LogicalOr | LogicalAnd | BitwiseOr // ...
type UnaryOperator = Statement | Block | Initializer // ...

type Element = 
  | BinaryOperator of BinaryOperator * Element * Element
  | UnaryOperator of UnaryOperator * Element 
于 2010-09-28T23:54:15.137 回答