我希望为我们与内部工具一起使用的简单DSL创建一个词法分析器和解析器。将有几个内置符号(这是正确的术语吗?),它们将使用1到10个参数之间的任意值。例如:

foo(bar1;bar2)


在运行时还将添加始终具有零参数的符号。例:

testy1()


这些将串在一起并从CSV文件中读取。组装线需要:

foo(bar1:bar2)testy1()


我很难在网上找到可以轻松地解释词汇表和解析此类函数调用的资源。有人可以指出我的正确方向,还是提供建议?

最佳答案

我用PegJS编写了一个小型解析器,该解析器能够解析函数调用中的简单表达式。 PEG避免了歧义,因此可以很好地工作。

Start
  = Expr

/* Expressions */

Expr
  = FuncCall
  / Literal

RestExpr
  = _ ( "," / ":" ) _ e:Expr {
    return e;
  }

/* Function call */

FuncCall
  = func:Ident _ "(" _ x:Expr? xs:RestExpr* _ ")" {
    return {
      type: "FuncCall",
      func: func.value,
      params: x ? [x].concat(xs) : []
    };
  }

/* Literals */

Literal
  = Number
  / Ident

Number
  = val:[0-9]+ {
    return {
      type: "Number",
      value: parseInt(val.join(""))
    };
  }

/* Identifier */

Ident
  = x:IdentStart xs:IdentRest* {
  return {
    type: "Ident",
    value: [x].concat(xs).join("")
  };
}

IdentStart
  = [a-z_]i

IdentRest
  = [a-z0-9_]i
_
  = [ \s\t\r\n]*


您可以在此处测试解析器:http://pegjs.org/online

一个输入示例是foo(1, bar(2), baz(3)),其中输出是:

{
   "type": "FuncCall",
   "func": "foo",
   "params": [
      {
         "type": "Number",
         "value": 1
      },
      {
         "type": "FuncCall",
         "func": "bar",
         "params": [
            {
               "type": "Number",
               "value": 2
            }
         ]
      },
      {
         "type": "FuncCall",
         "func": "baz",
         "params": [
            {
               "type": "Number",
               "value": 3
            }
         ]
      }
   ]
}


显然这不是最好的方法,但是我相信peg-sharp可以用C#做​​得很好:https://code.google.com/p/peg-sharp/

10-08 09:46