我不熟悉词法分析,如果标题不够清晰,我很抱歉。
基本上,我使用Jison来解析一些文本,并试图让lexer理解缩进。这里有一点值得商榷:
(\r\n|\r|\n)+\s* %{
parser.indentCount = parser.indentCount || [0];
var indentation = yytext.replace(/^(\r\n|\r|\n)+/, '').length;
if (indentation > parser.indentCount[0]) {
parser.indentCount.unshift(indentation);
return 'INDENT';
}
var tokens = [];
while (indentation < parser.indentCount[0]) {
tokens.push('DEDENT');
parser.indentCount.shift();
}
if (tokens.length) {
return tokens;
}
if (!indentation.length) {
return 'NEWLINE';
}
%}
到目前为止,几乎所有这些都像预期的那样工作。一个问题是我试图返回一个DEDENT
令牌数组的行。看来Jison只是将该数组转换成一个字符串,这导致我得到一个解析错误,如期待......,得到了DEDENT,DEDENT
。
我希望我能做的是手动将一些DEDENT
令牌推到堆栈上。也许有一个像这样的函数。pushToken('DEDENT')
或类似的东西。但是Jison的文档不是很好,我需要一些帮助。
有什么想法吗?
编辑:
在查看了生成的解析器代码后,我似乎已经能够破解这个问题。以下是似乎有效的方法...
if (tokens.length) {
var args = arguments;
tokens.slice(1).forEach(function () {
lexer.performAction.apply(this, args);
}.bind(this));
return 'DEDENT';
}
这会诱使lexer对堆栈中的每个DEDENT
使用完全相同的输入执行另一个操作,从而允许它添加正确的DEDENT。然而,感觉很恶心,我担心可能会有不可预见的问题。
如果有人对更好的方法有任何想法,我仍然会喜欢它。
几天后,我终于想出了一个更好的答案。下面是它的样子:
(\r\n|\r|\n)+[ \t]* %{
parser.indentCount = parser.indentCount || [0];
parser.forceDedent = parser.forceDedent || 0;
if (parser.forceDedent) {
parser.forceDedent -= 1;
this.unput(yytext);
return 'DEDENT';
}
var indentation = yytext.replace(/^(\r\n|\r|\n)+/, '').length;
if (indentation > parser.indentCount[0]) {
parser.indentCount.unshift(indentation);
return 'INDENT';
}
var dedents = [];
while (indentation < parser.indentCount[0]) {
dedents.push('DEDENT');
parser.indentCount.shift();
}
if (dedents.length) {
parser.forceDedent = dedents.length - 1;
this.unput(yytext);
return 'DEDENT';
}
return `NEWLINE`;
%}
首先,我修改了捕获正则表达式,以确保在一系列非换行符空格之后不会无意中捕获额外的换行符。
接下来,我们要确保有两个“全局”变量<代码>缩进计数将跟踪我们当前的缩进长度forcedDent
将强制我们返回DEDENT
,如果它的值大于0。
接下来,我们有一个条件来测试forceDedent
上的真实值。如果我们有一个,我们将把它递减1,并使用unput
函数来确保我们至少在同一个模式上迭代一次,但是对于这个迭代,我们将返回一个DEDENT
。
如果我们没有返回,我们将得到当前缩进的长度。
如果当前缩进大于最近的缩进,我们将在indentCount
变量上跟踪它,并返回INDENT
。
如果我们还没有回来,是时候准备可能的情况了。我们会组成一个阵列来跟踪他们。
当我们检测到dedent时,用户可能试图同时关闭一个或多个块。因此,我们需要在用户关闭时包含一个DEDENT
。我们设置了一个循环,只要当前缩进小于我们最近的缩进,我们就会在列表中添加一个DEDENT
,并从indentCount
中删除一个项目。
如果我们追踪到任何Dedent,我们需要确保lexer返回所有Dedent。因为lexer一次只能返回1个令牌,所以我们将在这里返回1,但我们还将设置forceDedent
变量,以确保我们也返回其余的令牌。为了确保我们再次迭代这个模式,并且可以插入这些dedent,我们将使用unput
函数。
在任何其他情况下,我们只返回一个换行符
。
下面的问题来自于CodingBat:给定一个数组,是否可以选择一组整数,使其与给定的目标相加? 站点作者提供了以下解决方案: 假设我想尝试下面的例子,其中nums=[2,4,8]并调用groupSum(0,nums,10)。 我看到将调用和。 调用和 调用和 等等。 在处理代码时,我看到了以下调用: 我看到应该返回true,因为第一行: ,但我对其他调用感到困惑,如。由于,从第一行开始,它应该清楚
问题内容: 在Java中是否可以从方法返回两个或多个值到main?如果是这样,有可能吗?如果没有,我们怎么办? 问题答案: 你可以使用Java返回Class的对象。 如果要返回多个相关的值,则将它们封装到一个类中,然后返回该类的对象是有意义的。 如果要返回不相关的值,则可以使用Java的内置容器类(例如Map,List,Set等)。有关更多详细信息,请检查java.util包的JavaDoc。
我正在尝试使用FastAPI MongoDB创建一个API,它可以从请求中返回多个值。MongoDB充满了数据,使用mongoengine,我可以在向特定endpoint发送请求时查阅一个或所有数据。我现在要做的是从endpoint接收一个或多个数据,例如: 当查询endpoint< code > http://127 . 0 . 0 . 1:8000/rice 时,我得到一个JSON响应,其中包
我试图使用这个查询返回一个节点对象和一个计算字段。理论上,这应该会返回一个散列,我可以访问每个人,计算并导入velocity模板。
问题内容: 我用Java写了一个函数,我希望这个函数返回多个值。除了使用数组和结构外,还有没有办法返回多个值? 我的代码: 问题答案: 在Java中,当您希望函数返回多个值时,必须 将这些值嵌入到您返回的对象中 或更改传递给函数的对象 在您的情况下,您显然需要定义一个可以包含,和的类: 然后将您的功能更改为
问题内容: 选项:使用元组 考虑下面这个简单的例子: 但是,随着返回值的数量增加,这很快就会成为问题。如果要返回四个或五个值怎么办?当然,你可以继续修改它们,但是很容易忘记哪个值在哪里。在任何想要接收它们的地方打开它们的包装也是很丑陋的。 选项:使用字典 下一步的逻辑步骤似乎是引入某种“记录符号”。在Python中,一种明显的方法是使用dict。 考虑以下: (请注意,y0,y1和y2只是抽象标识