Java Output
File Organization
Important: Java requires exactly ONE public class per .java file, and the filename must match the public class name.
Generated Files
- Lexer Only: Generates
Lexer.javacontainingpublic class Lexer - Parser Only: Generates
Parser.javacontainingpublic class Parser - Both Together: Generate as separate files and compile together
# Generate both
openlexer gen-lexer --lexer calc.l -L java -o output/
openlexer gen-parser --parser calc.y -L java -o output/
# Compile both
javac output/Lexer.java output/Parser.java
# Run (Parser auto-detects Lexer.class)
java -cp output Parser "3 + 4 * 2"
Lexer Interface
public class Lexer {
// Token constants
public static final int TOKEN_EOF = 0;
public static final int TOKEN_ERROR = 1;
public static final int TOKEN_NUMBER = 2;
public static final int TOKEN_PLUS = 3;
// ...
// Token class for lexer-parser integration
public static class Token {
public final int type; // Token type ID
public final String text; // Matched lexeme
public final int pos; // Position in input
public Token(int type, String text, int pos) {
this.type = type;
this.text = text;
this.pos = pos;
}
}
// Constructor
public Lexer(String input);
// Get next token (returns Token object)
public Token nextToken();
// Get token name
public static String tokenName(int type);
}
Parser Interface
public class Parser {
// Parse input string (auto-detects external Lexer if available)
public static int parse(String input);
// Main method for testing
public static void main(String[] args);
}
Automatic Lexer Detection
The generated Parser automatically detects if a compiled Lexer.class is available:
- With external Lexer: Uses reflection to call
Lexer.nextToken()- Output:
[Using external Lexer.class]
- Output:
- Without external Lexer: Falls back to inline lexer
- Output:
[Using inline lexer]
- Output:
This allows the Parser to work standalone OR with a separate Lexer.
Integration Example
Method 1: Using Generated Test Drivers
# Lexer only
javac Lexer.java
java Lexer "3 + 4 * 2"
# Parser with external Lexer
javac Lexer.java Parser.java
java Parser "3 + 4 * 2"
# Output: [Using external Lexer.class]
# Parser standalone (no Lexer.class)
javac Parser.java
java Parser "3 + 4 * 2"
# Output: [Using inline lexer]
Method 2: Custom Integration
public class Main {
public static void main(String[] args) {
if (args.length < 1) {
System.err.println("Usage: java Main <expression>");
System.exit(1);
}
String input = args[0];
// Tokenize with Lexer
Lexer lexer = new Lexer(input);
Lexer.Token token;
System.out.println("Tokens:");
while ((token = lexer.nextToken()).type != Lexer.TOKEN_EOF) {
System.out.printf(" %s: \"%s\"\n",
Lexer.tokenName(token.type), token.text);
}
// Parse
int result = Parser.parse(input);
System.out.println("Result: " + result);
}
}
Compilation and Execution
# Compile all files
javac Lexer.java Parser.java Main.java
# Run
java Main "3 + 4 * 2"
Semantic Values
The lexer's getValue() returns an Object. Cast as needed:
public int nextToken() {
// In NUMBER rule:
this.value = Integer.parseInt(this.text);
return NUMBER;
}
In parser actions, values are accessed through the semantic stack.
Error Handling
public class ParseException extends Exception {
private int line;
private int column;
private String token;
public ParseException(String message, int line, int column, String token) {
super(message);
this.line = line;
this.column = column;
this.token = token;
}
// Getters...
}
Reading from Files
String content = new String(Files.readAllBytes(Paths.get(filename)));
Lexer lexer = new Lexer(content);
Reading from InputStream
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
Lexer lexer = new Lexer(sb.toString());
Package Declaration
The generated code does not include a package declaration by default. Add one manually or modify the output if needed.
Java Version Compatibility
The generated code is compatible with Java 8 and later. No external dependencies are required.