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

基于Jflex与Java版Bison的编译器:如何实现变量重声明/未声明错误检测

Solution for Variable Declaration Checks in Java Bison Parser

Let's break down how to implement checks for undeclared/redeclared variables in your Java Bison parser—you don't need to jump through hoops like passing tokens to external instances, because Java Bison lets you embed custom logic directly in the parser class.

Core Idea

Add a symbol table as a member variable to the generated parser class, then manipulate this table directly within your grammar rule actions to validate variable declarations and usage.

Step 1: Add a Symbol Table to Your Parser Class

Use the %code class block in your .y file to inject custom members and methods into the generated parser. This is how you'll track declared variables:

%code class {
    // Symbol table to track declared variables (global scope for simplicity)
    private java.util.Set<String> declaredVars = new java.util.HashSet<>();
    // Flag to track if any semantic error occurred
    private boolean hasSemanticError = false;

    // Helper method to report semantic errors
    private void reportSemanticError(String msg) {
        System.err.println("Semantic Error: " + msg);
        hasSemanticError = true;
    }
}

Step 2: Check for Redeclared Variables in Declaration Rules

When your parser matches a variable declaration rule, add the variable name to the symbol table—only if it doesn't already exist. For example, if your grammar has a rule for variable declarations:

declaration: TYPE IDENTIFIER '=' expression ';' {
    String varName = $2.text; // $2 refers to the IDENTIFIER token, .text gets its string value
    if (declaredVars.contains(varName)) {
        reportSemanticError("Variable '" + varName + "' is redeclared");
    } else {
        declaredVars.add(varName);
    }
};

Here, $2 is the token object for the variable name—Java Bison exposes the token's string content via the text property.

Step 3: Check for Undeclared Variables in Usage Rules

Whenever your parser encounters a variable being used (like in an assignment or expression), verify it exists in the symbol table:

assignment: IDENTIFIER '=' expression ';' {
    String varName = $1.text;
    if (!declaredVars.contains(varName)) {
        reportSemanticError("Variable '" + varName + "' is undeclared");
    }
};

This will catch cases like your example where test2 is assigned without being declared first.

Step 4: Update the Parser's Return Logic

Modify your main method to account for both syntax and semantic errors. Since Java Bison's default parse() only checks syntax errors, you'll want to combine that with your semantic error flag:

public static void main(String args[]) throws IOException { 
    EXAMPLELexer lexer = new EXAMPLELexer(System.in); 
    EXAMPLE parser = new EXAMPLE(lexer); 
    boolean syntaxValid = parser.parse();
    boolean semanticValid = !parser.hasSemanticError; // Access the flag we added

    if (syntaxValid && semanticValid) { 
        System.out.println("VALID FROM PARSER"); 
    } else { 
        System.out.println("ERROR FROM PARSER"); 
    } 
}

Key Notes

  • No need for %union: Java Bison doesn't support %union, but you don't need it—you can directly access token properties like text in rule actions.
  • Scope handling: If you need to support local scopes (e.g., variables inside functions), replace the HashSet with a stack of Set<String>—push a new set when entering a scope, pop it when exiting.
  • Token access: Make sure your token definition for IDENTIFIER is correctly set up in your JFlex .l file—Java Bison will generate the appropriate token class with the text property.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 16:22:46