【问题标题】:Pegjs: Don't allow reserved keywords as a variable namePegjs:不允许保留关键字作为变量名
【发布时间】:2015-03-09 23:00:11
【问题描述】:

我正在用 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 定义中的非允许关键字?

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

感谢您的帮助!

【问题讨论】:

  • 我确信这是一个有趣的问题,因为必须(至少应该)有一种更好的方式来构建我的语法。可能 PEGJS 的“受众”有限?

标签: javascript pegjs


【解决方案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 的documentation

!表达

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

【讨论】:

    猜你喜欢
    • 2020-06-15
    • 1970-01-01
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    相关资源
    最近更新 更多