用于 PEG 语法的 PEG 解析器

PEG parser for PEG grammars

我正在寻找一个库,给定 PEG 语法输入,例如:

Expression
  = A B

A 
  = [0-9]

B
  = [a-z]

将输出机器可读的版本,例如:

{  
  "expression":{  
    "components":[  
      {  
        "type": "subexpression",
        "subexpressionName": "A"
      },
      {  
        "type": "subexpression",
        "subexpressionName": "B"
      }
    ]
  },
  "subexpressions":[  
    {  
      "name": "A",
      "components":[  
        {  
          "type": "regex",
          "regexString": "[0-9]"
        }
      ]
    },
    {  
      "name": "B",
      "components":[  
        {  
          "type": "regex",
          "regexString": "[a-z]"
        }
      ]
    }
  ]
}

有人知道这样的图书馆吗? Javascript 首选图书馆,但任何图书馆都会有所帮助。

感谢上面 Ira 的评论,我进行了更深入的研究,找到了我需要的东西。

我正在使用的库是 pegjs,它可以很容易地得到解析的语法 JSON。

var pegjs = require('pegjs');

var exampleGrammar = ''+
'Expression  \n'+
'  = A B     \n'+
'            \n'+
'A           \n'+
'  = [0-9]   \n'+
'            \n'+
'B           \n'+
'  = [a-z]   ';

var parsed = pegjs.parser.parse(exampleGrammar);
console.log(JSON.stringify(parsed));

以及它给出的输出,如果有人感兴趣的话:

{  
  "type":"grammar",
  "initializer":null,
  "rules":[  
    {  
      "type":"rule",
      "name":"Expression",
      "expression":{  
        "type":"sequence",
        "elements":[  
          {  
            "type":"rule_ref",
            "name":"A",
            "location":{  
              "start":{  
                "offset":16,
                "line":2,
                "column":5
              },
              "end":{  
                "offset":17,
                "line":2,
                "column":6
              }
            }
          },
          {  
            "type":"rule_ref",
            "name":"B",
            "location":{  
              "start":{  
                "offset":18,
                "line":2,
                "column":7
              },
              "end":{  
                "offset":19,
                "line":2,
                "column":8
              }
            }
          }
        ],
        "location":{  
          "start":{  
            "offset":16,
            "line":2,
            "column":5
          },
          "end":{  
            "offset":19,
            "line":2,
            "column":8
          }
        }
      },
      "location":{  
        "start":{  
          "offset":0,
          "line":1,
          "column":1
        },
        "end":{  
          "offset":25,
          "line":3,
          "column":1
        }
      }
    },
    {  
      "type":"rule",
      "name":"A",
      "expression":{  
        "type":"class",
        "parts":[  
          [  
            "0",
            "9"
          ]
        ],
        "inverted":false,
        "ignoreCase":false,
        "rawText":"[0-9]",
        "location":{  
          "start":{  
            "offset":55,
            "line":5,
            "column":5
          },
          "end":{  
            "offset":60,
            "line":5,
            "column":10
          }
        }
      },
      "location":{  
        "start":{  
          "offset":38,
          "line":4,
          "column":1
        },
        "end":{  
          "offset":64,
          "line":6,
          "column":1
        }
      }
    },
    {  
      "type":"rule",
      "name":"B",
      "expression":{  
        "type":"class",
        "parts":[  
          [  
            "a",
            "z"
          ]
        ],
        "inverted":false,
        "ignoreCase":false,
        "rawText":"[a-z]",
        "location":{  
          "start":{  
            "offset":94,
            "line":8,
            "column":5
          },
          "end":{  
            "offset":99,
            "line":8,
            "column":10
          }
        }
      },
      "location":{  
        "start":{  
          "offset":77,
          "line":7,
          "column":1
        },
        "end":{  
          "offset":103,
          "line":9,
          "column":1
        }
      }
    }
  ],
  "location":{  
    "start":{  
      "offset":0,
      "line":1,
      "column":1
    },
    "end":{  
      "offset":103,
      "line":9,
      "column":1
    }
  }
}