Nccc 1.0.0

a parser parser

Install-Package Nccc -Version 1.0.0
dotnet add package Nccc --version 1.0.0
<PackageReference Include="Nccc" Version="1.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Nccc --version 1.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

Nccc

.Net Compiler Compiler Combinator

Make Making Parser Easy

一个简单易用的语法生成器。采用Parsec的编程方式实现。语法生成式的设计参考了王垠的设计和PEG的思想,基本上采用的S表达式的结构。

Parsec的意思是Parser Combinators。其思想是基于一些基础parser,使用parser组合子组合成复杂的parser。

这些基础parser都是一些简单的parser,简单到非常容易编程实现。
比如匹配字符串A的parser(记为&#39;A&#39;),匹配一个数字的parser(记为&lt;number&gt;)等。

Parser组合子类似正则表达式中的操作符。
比如将parser串成序列的序列操作@..,或操作@or,星号操作(零个或多个)@*

使用基础parser和组合子可以合成较为复杂的parser:

  • (@.. &#39;A&#39; &#39;B&#39;)匹配字符串A和字符串B序列。如A B
  • (@or &#39;A&#39; &#39;B&#39;)匹配字符串A或字符串B
  • (@? &#39;A&#39;)匹配空或者字符串A
  • (@* &#39;A&#39;)匹配零个或多个A。如AA A A A
  • (@* (@or &#39;A&#39; &#39;B&#39;))匹配由'A'和'B'组成的序列。如B BA AA BA B A A
  • (@or &#39;A&#39; &lt;number&gt;)匹配由'A'或者一个数字。如A1.1
  • (@* (@or &#39;A&#39; &lt;number&gt;))匹配由'A'和数字组成的序列。如A A1.1 2A 23A 1.2 A A

一个例子: 算术表达式

语法:

; 定义add为root parser,即最后得到的parser
:: add

; 设置参数
@set-delims '(' ')' '[' ']' '{' '}' '+' '-' '*' '/' '^'

; 下面开始组合

add = (@or add:(mul '+' add)
           sub:(mul'-' add)
           mul)

mul = (@or mul:(pow '*' mul)
           div:(pow '/' mul)
           pow)

pow = (@or pow:(primary '^' pow)
           primary)

primary = (@or par:('(' add ')')
               par:('[' add ']')
               par:('{' add '}')
               neg:('-' pow)
               num:<number>)

加载Parser:

private NcParser _parser = NcParser.LoadFromAssembly(Assembly.GetExecutingAssembly(), "Nccc.Tests.Calculator.calculator.grammer");

Parse:

var pr = _parser.ScanAndParse("(5.1+2)*3+-2^3^2");
Console.WriteLine(pr.ToSExp().ToPrettyString());

输出Parsing结果(打印成S表达式):

(((parser add))
 (success? True)
 (nodes
  ((add[(1,1)-(1,17)]
    (mul[(1,1)-(1,10)]
     (par[(1,1)-(1,8)]
      (add[(1,2)-(1,7)]
       (num[(1,2)-(1,5)] 5.1)
       (num[(1,6)-(1,7)] 2)))
     (num[(1,9)-(1,10)] 3))
    (neg[(1,11)-(1,17)]
     (pow[(1,12)-(1,17)]
      (num[(1,12)-(1,13)] 2)
      (pow[(1,14)-(1,17)]
       (num[(1,14)-(1,15)] 3)
       (num[(1,16)-(1,17)] 2)))))))

更多资料

文档

Nccc

.Net Compiler Compiler Combinator

Make Making Parser Easy

一个简单易用的语法生成器。采用Parsec的编程方式实现。语法生成式的设计参考了王垠的设计和PEG的思想,基本上采用的S表达式的结构。

Parsec的意思是Parser Combinators。其思想是基于一些基础parser,使用parser组合子组合成复杂的parser。

这些基础parser都是一些简单的parser,简单到非常容易编程实现。
比如匹配字符串A的parser(记为&#39;A&#39;),匹配一个数字的parser(记为&lt;number&gt;)等。

Parser组合子类似正则表达式中的操作符。
比如将parser串成序列的序列操作@..,或操作@or,星号操作(零个或多个)@*

使用基础parser和组合子可以合成较为复杂的parser:

  • (@.. &#39;A&#39; &#39;B&#39;)匹配字符串A和字符串B序列。如A B
  • (@or &#39;A&#39; &#39;B&#39;)匹配字符串A或字符串B
  • (@? &#39;A&#39;)匹配空或者字符串A
  • (@* &#39;A&#39;)匹配零个或多个A。如AA A A A
  • (@* (@or &#39;A&#39; &#39;B&#39;))匹配由'A'和'B'组成的序列。如B BA AA BA B A A
  • (@or &#39;A&#39; &lt;number&gt;)匹配由'A'或者一个数字。如A1.1
  • (@* (@or &#39;A&#39; &lt;number&gt;))匹配由'A'和数字组成的序列。如A A1.1 2A 23A 1.2 A A

一个例子: 算术表达式

语法:

; 定义add为root parser,即最后得到的parser
:: add

; 设置参数
@set-delims '(' ')' '[' ']' '{' '}' '+' '-' '*' '/' '^'

; 下面开始组合

add = (@or add:(mul '+' add)
           sub:(mul'-' add)
           mul)

mul = (@or mul:(pow '*' mul)
           div:(pow '/' mul)
           pow)

pow = (@or pow:(primary '^' pow)
           primary)

primary = (@or par:('(' add ')')
               par:('[' add ']')
               par:('{' add '}')
               neg:('-' pow)
               num:<number>)

加载Parser:

private NcParser _parser = NcParser.LoadFromAssembly(Assembly.GetExecutingAssembly(), "Nccc.Tests.Calculator.calculator.grammer");

Parse:

var pr = _parser.ScanAndParse("(5.1+2)*3+-2^3^2");
Console.WriteLine(pr.ToSExp().ToPrettyString());

输出Parsing结果(打印成S表达式):

(((parser add))
 (success? True)
 (nodes
  ((add[(1,1)-(1,17)]
    (mul[(1,1)-(1,10)]
     (par[(1,1)-(1,8)]
      (add[(1,2)-(1,7)]
       (num[(1,2)-(1,5)] 5.1)
       (num[(1,6)-(1,7)] 2)))
     (num[(1,9)-(1,10)] 3))
    (neg[(1,11)-(1,17)]
     (pow[(1,12)-(1,17)]
      (num[(1,12)-(1,13)] 2)
      (pow[(1,14)-(1,17)]
       (num[(1,14)-(1,15)] 3)
       (num[(1,16)-(1,17)] 2)))))))

更多资料

文档

  • .NETStandard 2.0

    • No dependencies.

GitHub repositories (0)

This package is not used by any popular GitHub repositories.

Version History

Version Downloads Last updated
1.0.0 111 11/28/2019
0.6.0 154 8/8/2019
0.5.0 135 8/8/2019
0.4.0 186 6/28/2019
0.3.0 211 12/29/2018