如何将大型可区分联合树转换为可读形式?
下面的类型显然非常大,因此手动编写代码将其转换为可读的形式将是乏味的。我想知道以可读形式显示树的最简单方法。
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>
The following type is clearly quite large so manually writing the code to convert this to a readable form would be tedious. I would like to know the simplest way to display the tree in a readable form.
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
Here is an example of how this might be displayed. (It is a bit different as I produced it a while ago.)
<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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您想编写不需要列出所有联合案例的通用联合处理代码,那么您可能需要使用 F# 反射 API。这是一个简单的例子。
formatUnion
函数使用 F# 反射。它假定类型参数'T
是联合类型,并使用GetUnionFields
获取包含当前案例名称和参数的元组。它打印当前案例名称并迭代所有参数。如果某些参数是'T
类型的值(意味着它是递归联合),我们会递归地打印有关该值的信息:以下示例在一个非常简单的联合值上运行该函数
:旁注,我认为您可以通过使用
BinaryOperator
和UnaryOperator
(带有一个附加参数)来大大简化您的可区分联合,而不是显式列出所有元素类型。那么你可能可以直接实现该函数,因为它非常简单。像这样的东西:If you want to write generic union processing code that will not need to list all the union cases, then you'll probably need to use F# reflection API. Here is a simple example.
The
formatUnion
function uses F# reflection. It assumes that the type parameter'T
is a union type and usesGetUnionFields
to get a tuple containing the name of the current case and arguments. It prints the current case name and iterates over all the arguments. If some of the arguments is value of type'T
(meaning that it is recursive union), we recursively print information about the value:The following example runs the function on a very simple union value:
As a side-note, I think that you could largely simplify your discriminated union by having cases for
BinaryOperator
andUnaryOperator
(with one additional parameter) instead of listing all the element types explicitly. Then you could probably implement the function directly, because it would be quite simple. Something like: