Pegjs:不允许保留关键字作为变量名称

Pegjs: Don't allow reserved keywords as a variable name

本文关键字:变量名 关键字 不允许 保留 Pegjs      更新时间:2023-09-26

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

我做了以下操作(可在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定义中手动重新定义不允许的关键字?

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

感谢您的帮助!

简单的答案:

(请参阅 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,不要推进解析器位置,否则认为匹配失败。