一个由方法调用构成的简单DSL的词法分析器/语法分析器

3

我希望创建一个词法分析器和解析器,用于处理我们内部工具中使用的简单DSL。其中会有一些内置符号(是否是正确的术语?),它们将需要介于1到10个参数。例如:

foo(bar1;bar2)

还会在运行时添加一些符号,这些符号始终具有零参数。例如:

testy1()

这些将被串在一起并从CSV文件中读取。组装好的一行应该像这样:
foo(bar1:bar2)testy1()

我在网上找不到能够简单解释类似这样的词法分析和语法分析函数调用的资源。请问有人能给出好的方向或建议吗?


你可能认为这有些过头了,但我建议下载ANTLR并使用它的工具来完成这个任务,一旦你掌握了学习曲线,它会让你的工作变得更加容易。 - Ron Beyer
1
请查看我的SO答案,了解如何构建递归下降解析器:https://dev59.com/v3E95IYBdhLWcg3wlu6z#2336769 - Ira Baxter
我无法依赖于第三方库,否则ANTLR似乎是一个不错的选择。 - Ryan
1个回答

0

我用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
            }
         ]
      }
   ]
}

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接