![]() |
VOOZH | about |
dotnet add package ClosedXML.Parser --version 2.0.0
NuGet\Install-Package ClosedXML.Parser -Version 2.0.0
<PackageReference Include="ClosedXML.Parser" Version="2.0.0" />
<PackageVersion Include="ClosedXML.Parser" Version="2.0.0" />Directory.Packages.props
<PackageReference Include="ClosedXML.Parser" />Project file
paket add ClosedXML.Parser --version 2.0.0
#r "nuget: ClosedXML.Parser, 2.0.0"
#:package ClosedXML.Parser@2.0.0
#addin nuget:?package=ClosedXML.Parser&version=2.0.0Install as a Cake Addin
#tool nuget:?package=ClosedXML.Parser&version=2.0.0Install as a Cake Tool
ClosedParser is a project to parse OOXML grammar to create an abstract syntax tree that can be later evaluated.
Official source for the grammar is MS-XML, chapter 2.2.2 Formulas. The provided grammar is not usable for parser generators, it's full of ambiguities and the rules don't take into account operator precedence.
IAstFactory interface.FormulaParser<TScalarValue, TNode>.CellFormulaA1("Sum(A1, 2)", astFactory)FormulaParser<TScalarValue, TNode>.CellFormulaR1C1("Sum(R1C1, 2)", astFactory)There is a visualizer to display AST in a browser at https://parser.closedxml.io
SUM(R5) can mean return sum of cell R5 in A1 notation, but return sum of all cells on row 5 in R1C1 notation.Project uses ANTLR4 grammar file as the source of truth and a lexer. There is also ANTLR parser is not used, but is used as a basis of recursive descent parser (ANTLR takes up 8 seconds vs RDS 700ms for parsing of enron dataset).
ANTLR4 one of few maintained parser generators with C# target.
The project has a low priority, XLParser mostly works, but in the long term, replacement is likely.
ENRON dataset parsed using recursive descent parser and DFA lexer in Release mode:
2μs per formula should be something like 6000 instructions (under unrealistic assumption 1 instruction per 1 Hz), so basically fast enough.
The primary goal is to parse formulas stored in file, not user supplied formulas. The formulas displayed in the GUI is not the same as formula stored in the file. Several examples:
_xlfn.IFS, but user sees IFS[#This Row]Therefore:
[5])[1]!'Some name in external wb'). They are out of scope of the project.ClosedXML is currently using XLParser and transforming the concrete syntax tree to abstract syntax tree.
prefix hints.ANTLR lexer takes up about 3.2 seconds for Enron dataset. With ANTLR parsing, it takes up 11 seconds. I want that 7+ seconds in performance and no allocation, so RDS that takes up 700 ms.
Use vscode-antlr4 plugin for debugging the grammar.
A1_REFERENCE C5 to row 5, column 3) has a separate test class in Lexers directory with a {TokenPascalName}TokenTests.csRules directory. It should contain all possible combinatins of a rule and comparing it with the AST nodes.DataSetTests.cs. Each test tries to parse formula and ensures that ANTLR can parse it RDS can and can't parse a formula when ANTLR can't. There is no check of the output, just that formulas can be parsed. Data are contained in a data directory in CSV format with a one column.Rolex is a DFA based lexer released under MIT license (see Rolex: Unicode Enabled Lexer Generator in C#). ANTLR is still the source of truth, but it is used to generate Rolex grammar and then DFA for a lexer.
It is rather complicated, but two times faster than ANTLR lexer (1.9 us vs 3.676 us per formula).
Prepare rolex grammars
/* at the beginning of Local A1 References section. It comments out A1_REFERENCE and all its fragments/* at the beinning of Local R1C1 References section. It contains a different tokens for A1_REFERENCE and its fragmentsFix Rolex generator
pc.Advance() to FFA.cs _ParseEscapePart and _ParseRangeEscapePart]Generate a DFA through Rolex
Rolex.exe ClosedXML.Parser\Rolex\LexerA1.rl /noshared /output ClosedXML.Parser\Rolex\RolexA1Dfa.cs /namespace ClosedXML.Parser.RolexRolex.exe ClosedXML.Parser\Rolex\LexerR1C1.rl /noshared /output ClosedXML.Parser\Rolex\RolexR1C1Dfa.cs /namespace ClosedXML.Parser.Rolex| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 was computed. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 is compatible. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 5 NuGet packages that depend on ClosedXML.Parser:
| Package | Downloads |
|---|---|
|
ClosedXML
See release notes https://github.com/ClosedXML/ClosedXML/releases/tag/0.105.0 ClosedXML is a .NET library for reading, manipulating and writing Excel 2007+ (.xlsx, .xlsm) files. It aims to provide an intuitive and user-friendly interface to dealing with the underlying OpenXML API. |
|
|
Phabrico
Offline editor for Phabricator documents and tasks |
|
|
QuadrumClosedXML
See release notes https://github.com/ClosedXML/ClosedXML/releases/tag/ ClosedXML is a .NET library for reading, manipulating and writing Excel 2007+ (.xlsx, .xlsm) files. It aims to provide an intuitive and user-friendly interface to dealing with the underlying OpenXML API. |
|
|
AutomatR.ExcelLite
ExcelLite Activities for AutomatR Studio |
|
|
MarkItDown
It is a WIP .Net Core implementation of the original markitdown Python library. |
Showing the top 2 popular GitHub repositories that depend on ClosedXML.Parser:
| Repository | Stars |
|---|---|
|
ClosedXML/ClosedXML
ClosedXML is a .NET library for reading, manipulating and writing Excel 2007+ (.xlsx, .xlsm) files. It aims to provide an intuitive and user-friendly interface to dealing with the underlying OpenXML API.
|
|
|
Topkill/tianruoocr
天若OCR开源6.0版本,续更开源5.0版,全新版本,全新出发
|
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.0 | 27,415,071 | 4/3/2025 |
| 1.3.0 | 247,903 | 10/18/2024 |
| 1.2.0 | 30,055,923 | 1/17/2024 |
| 1.1.0 | 19,054 | 1/11/2024 |
| 1.0.0 | 23,519 | 1/7/2024 |
| 1.0.0-beta4 | 586,701 | 7/31/2023 |
| 1.0.0-beta3 | 373 | 7/30/2023 |