You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blockly中串联自定义块仅首个生成C++代码问题排查

问题

我在Google Blockly中自定义了可生成C++代码的块,单独使用时功能正常,但将这些块串联使用时,仅首个块能生成代码,后续连接的块完全无法生成代码。

相关代码如下:

const toolbox = {
...
}

const cppGenerator = new Blockly.Generator('cppGenerator');

Blockly.Blocks['start_of_file'] = {
    init: function() {
        this.appendDummyInput()
            .appendField("File name:")
            .appendField(new Blockly.FieldTextInput("main"), "filename");
        this.appendDummyInput()
            .appendField("Description: ")
            .appendField(new Blockly.FieldTextInput("The main file"), "description");
        this.setNextStatement(true, null);
        this.setColour(230);
        this.setTooltip("");
        this.setHelpUrl("");
    }
};

Blockly.Blocks['include'] = {
    init: function() {
        this.appendDummyInput()
            .appendField("use the")
            .appendField(new Blockly.FieldTextInput("iostream"), "header")
            .appendField("header");
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setColour(230);
        this.setTooltip("");
        this.setHelpUrl("");
    }
};

cppGenerator.forBlock['start_of_file'] = function(block, generator) {
    var filename = block.getFieldValue('filename');
    if (filename.slice(-4) != ".cpp") {
        filename += ".cpp"
    }

    var description = block.getFieldValue('description');

    console.log(block)

    return `// ${filename}
// ${description}`;
}

cppGenerator.forBlock['include'] = function(block, generator) {
    var header = block.getFieldValue('header');

    return `#include <${header}>`
}

const workspace = Blockly.inject('blocklyDiv', { toolbox: toolbox });

function updateCode(event) {
    const code = cppGenerator.workspaceToCode(workspace);
    document.getElementById('textarea').value = code;
}
// workspace.addChangeListener(Blockly.Events.disableOrphans);
workspace.addChangeListener(updateCode);

当前效果:
当前效果

预期效果:
预期效果

原因分析

Blockly生成器默认只会处理当前块的代码,不会自动遍历后续连接的块。如果你的块设置了setNextStatement(true),就需要在生成器函数中主动调用generator.statementToCode(block, 'NEXT')来获取后续块的代码,并将其与当前块的代码拼接。

解决方案

修改两个块的生成器函数,添加获取后续语句的逻辑:

cppGenerator.forBlock['start_of_file'] = function(block, generator) {
    var filename = block.getFieldValue('filename');
    if (filename.slice(-4) != ".cpp") {
        filename += ".cpp"
    }

    var description = block.getFieldValue('description');
    // 获取后续块的代码
    const nextCode = generator.statementToCode(block, 'NEXT');
    
    return `// ${filename}
// ${description}
${nextCode}`;
}

cppGenerator.forBlock['include'] = function(block, generator) {
    var header = block.getFieldValue('header');
    // 获取后续块的代码
    const nextCode = generator.statementToCode(block, 'NEXT');
    
    return `#include <${header}>
${nextCode}`;
}
说明
  • generator.statementToCode(block, 'NEXT')会递归处理当前块之后连接的所有块,生成对应的代码
  • 将后续代码与当前块代码拼接时,注意添加换行符保证代码格式正确
  • 修改后,串联的块就能依次生成对应的C++代码

内容的提问来源于stack exchange,提问作者FortCraftCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 11:55:15