0

我正在用 Pegjs 编写我的语言,并且像往常一样,我的语言有一些关键字,例如true, false, if,elsetoday例如。现在,我想声明一个变量,但显然,变量名不能是保留关键字之一。它可以是任何字母,后跟字母数字,语言关键字除外。

我做了以下(可在Pegjs Online中测试):

variable = c:(alpha alphanum*)
{
 var keywords = ["true", "false", "if", "else", "today"];

  var res = c[0]
  for (var i = 0; i<c[1].length; i++) {
    res=res+c[1][i]
  }

  if(keywords.indexOf(res)>=0) {
    return error('\'' + res + '\'' + ' is a keyword and cannot be used as a variable name.');
  }

  return { 'dataType' : 'variable', 'dataValue' : res };
}

alpha = [a-zA-Z]
alphanum = [a-zA-Z0-9_]

boolean = v: ("true" / "false")
{
  return { 'dataType' : 'boolean', 'dataValue': v};
}

现在true是非法的,但true1不是。这可以。但是,由于我已经boolean在我的语言的其他地方定义了结构,是否不能重用该定义而不是手动重新定义我的variable定义中不允许的关键字?

你可以想象为什么我的解决方案容易出错。我尝试了几件事,但没有奏效。

谢谢你的帮助!

4

1 回答 1

1

简单的答案:

(在http://peg.arcanis.fr/2VbQ5G/上查看此代码)

    variable = ! keyword (alpha alphanum*)
    {
      return { 'dataType' : 'variable', 'dataValue': text()};
    }

    keyword = "true" / "false" / "if" / "else" / "today"

    alpha = [a-zA-Z]
    alphanum = [a-zA-Z0-9_]

    boolean = ("true" / "false")
    {
      return { 'dataType' : 'boolean', 'dataValue': text()};
    }

注意:这会丢失有用的错误报告。如果有机会,我会尝试提出一个保留它的答案。

下面代码的重要部分位于variable规则的开头:! keyword. 这是最简单的方法,因为解析器正在向前看 1 个令牌。如果它找到的不是关键字,那么它允许规则尝试匹配令牌。另一方面,如果它关键字,则! keyword表达式(并且通过扩展,整个variable规则失败。

引用 David Majda 的文档

!表达

尝试匹配表达式。如果匹配不成功,只返回 undefined 并且不推进解析器位置,否则认为匹配失败。

于 2015-01-12T16:04:39.127 回答