我在Pegjs写我的语言,像往常一样,我的语言有一些关键字,例如true
,false
,if
,else
和today
例如。现在,我想声明一个变量,但显然,变量名不能是保留的关键字之一。它可以是任何alpha后跟一个字母数字,但语言关键字除外。
我做了以下(在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
定义中的非允许关键字?< / p>
您可以想象为什么我的解决方案容易出错。我尝试了几件事,但他们没有用。
感谢您的帮助!
答案 0 :(得分: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并不提前解析器位置,否则认为匹配失败。