Cyjb.Compilers.Design
1.0.20
See the version list below for details.
dotnet add package Cyjb.Compilers.Design --version 1.0.20
NuGet\Install-Package Cyjb.Compilers.Design -Version 1.0.20
<PackageReference Include="Cyjb.Compilers.Design" Version="1.0.20"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add Cyjb.Compilers.Design --version 1.0.20
#r "nuget: Cyjb.Compilers.Design, 1.0.20"
// Install Cyjb.Compilers.Design as a Cake Addin #addin nuget:?package=Cyjb.Compilers.Design&version=1.0.20 // Install Cyjb.Compilers.Design as a Cake Tool #tool nuget:?package=Cyjb.Compilers.Design&version=1.0.20
Cyjb.Compilers.Design
允许通过设计时 T4 模板生成词法分析器和语法分析器的实现。
使用方式
通过 nuget 依赖运行时 Cyjb.Compilers.Runtime。
通过 nuget 依赖生成器 Cyjb.Compilers.Design,注意请如下指定引用配置,可以正常编译项目并避免产生运行时引用。
<ItemGroup>
<PackageReference Include="Cyjb.Compilers.Design" Version="1.0.5">
<GeneratePathProperty>True</GeneratePathProperty>
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>compile; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
- 编写词法分析器的控制器类,例如:
using Cyjb.Compilers.Lexers;
enum Calc { Id, Add, Sub, Mul, Div, Pow, LBrace, RBrace }
[LexerSymbol("\\+", Kind = Calc.Add)]
[LexerSymbol("\\-", Kind = Calc.Sub)]
[LexerSymbol("\\*", Kind = Calc.Mul)]
[LexerSymbol("\\/", Kind = Calc.Div)]
[LexerSymbol("\\^", Kind = Calc.Pow)]
[LexerSymbol("\\(", Kind = Calc.LBrace)]
[LexerSymbol("\\)", Kind = Calc.RBrace)]
[LexerSymbol("\\s")]
// 必须是部分类,且继承自 LexerController<Calc>
public partial class CalcLexer : LexerController<Calc>
{
/// <summary>
/// 数字的终结符定义。
/// </summary>
[LexerSymbol("[0-9]+", Kind = Calc.Id)]
public void DigitAction()
{
Value = int.Parse(Text);
Accept();
}
}
或者语法分析器的控制器类,例如:
using Cyjb.Compilers.Parsers;
[ParserLeftAssociate(Calc.Add, Calc.Sub)]
[ParserLeftAssociate(Calc.Mul, Calc.Div)]
[ParserRightAssociate(Calc.Pow)]
[ParserNonAssociate(Calc.Id)]
// 必须是部分类,且继承自 ParserController<Calc>
public partial class CalcParser : ParserController<Calc>
{
[ParserProduction(Calc.E, Calc.Id)]
private object? IdAction()
{
return this[0].Value;
}
[ParserProduction(Calc.E, Calc.E, Calc.Add, Calc.E)]
[ParserProduction(Calc.E, Calc.E, Calc.Sub, Calc.E)]
[ParserProduction(Calc.E, Calc.E, Calc.Mul, Calc.E)]
[ParserProduction(Calc.E, Calc.E, Calc.Div, Calc.E)]
[ParserProduction(Calc.E, Calc.E, Calc.Pow, Calc.E)]
private object? BinaryAction()
{
double left = (double)this[0].Value!;
double right = (double)this[2].Value!;
return this[1].Kind switch
{
Calc.Add => left + right,
Calc.Sub => left - right,
Calc.Mul => left * right,
Calc.Div => left / right,
Calc.Pow => Math.Pow(left, right),
_ => throw CommonExceptions.Unreachable(),
};
}
[ParserProduction(Calc.E, Calc.LBrace, Calc.E, Calc.RBrace)]
private object? BraceAction()
{
return this[1].Value;
}
}
- 添加与词法分析器同名的 tt 文件,内容如下:
<#@ include file="$(PkgCyjb_Compilers_Design)\content\CompilerTemplate.t4" #>
运行 T4 模板后即可生成同名的 .designed.cs
文件,包含了词法或语法分析器的实现。
通过 CalcLexer.Factory
或 CalcParser.Factory
即可访问创建词法/语法分析器的工厂类。
词法分析功能
词法分析器使用 LexerSymbol 特性声明终结符,使用的正则表达式的定义与 C# 正则表达式一致,但不包含定位点、捕获、Lookaround、反向引用、替换构造和替代功能。
正则表达式支持通过 /
指定向前看符号,支持指定匹配的上下文,并在执行动作时根据需要切换上下文。
如果前缀可以与多个正则表达式匹配,那么:
- 总是选择最长的前缀。
- 如果最长的可能前缀与多个正则表达式匹配,总是选择先定义的正则表达式。
支持使用 LexerContext 或 LexerInclusiveContext 特性声明上下文或包含型上下文,在声明符号时可以通过 <ContextName>foo
指定生效的上下文。
支持使用 LexerRegex 特性声明公共正则表达式,在声明符号时可以通过 foo{RegexName}bar
引用公共正则表达式。
支持使用 LexerRejectable 特性开启 Reject 动作的支持。
语法分析功能
语法分析器使用 LALR 语法分析实现,使用 ParserProduction 特性声明产生式,并且可以通过 SymbolOption 的 Optional
、ZeroOrMore
和 OneOrMore
支持简单的子产生式,其功能类似于正则表达式中的 A?
、A*
和 A+
。
支持使用 ParserNonAssociate、ParserLeftAssociate 和 ParserRightAssociate 声明符号的结合性。
默认使用首个出现的非终结符作为起始符号,也支持使用 ParserStart 指定起始符号。起始符号可以指定多个,并通过在语法分析器的 Parse
方法的参数来选择希望使用的起始符号。
还可以使用 ParseOption 指定起始符号的扫描方式。
欢迎访问我的博客获取更多信息。
C# 词法分析器系列博文
- C# 词法分析器(一)词法分析介绍
- C# 词法分析器(二)输入缓冲和代码定位
- C# 词法分析器(三)正则表达式
- C# 词法分析器(四)构造 NFA
- C# 词法分析器(五)转换 DFA
- C# 词法分析器(六)构造词法分析器
- C# 词法分析器(七)总结
C# 语法法分析器系列博文
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- Cyjb.Compilers.Runtime (>= 1.0.20)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.22 | 118 | 6/4/2024 |
1.0.21 | 115 | 6/4/2024 |
1.0.20 | 131 | 3/23/2024 |
1.0.19 | 135 | 3/20/2024 |
1.0.18 | 129 | 3/15/2024 |
1.0.17 | 115 | 3/14/2024 |
1.0.16 | 153 | 1/15/2024 |
1.0.15 | 247 | 3/10/2023 |
1.0.14 | 233 | 3/3/2023 |
1.0.13 | 242 | 2/9/2023 |
1.0.12 | 329 | 1/28/2023 |
1.0.11 | 286 | 1/25/2023 |
1.0.10 | 291 | 1/24/2023 |
1.0.9 | 267 | 1/23/2023 |
1.0.8 | 295 | 1/16/2023 |
1.0.7 | 340 | 12/4/2022 |
1.0.6 | 426 | 11/1/2022 |
1.0.5 | 477 | 10/25/2022 |
1.0.4 | 470 | 9/7/2022 |
1.0.3 | 461 | 8/27/2022 |
1.0.2 | 472 | 8/27/2022 |
1.0.1 | 474 | 8/18/2022 |
1.0.0 | 452 | 8/18/2022 |