I have to write a program that takes a user\'s chemical equation as an input, like 12 CO2 + 6 H2O -> 2 C6H12O6 + 12 O2, and watch if the amount of Atoms is on both sites the
The way a proper parser such as ANTLR works is to 1) convert the text into a stream of lexical tokens, then 2) parse the tokens with lookahead into a parse tree.
Lookahead is useful to know when to "end" a particular structural level of parsing.
For your requirements, you might be able to skip the distinction between lexing and parsing and just parse from the text directly -- however, an appreciation and use of lookahead would potentially be useful.
In particular a buffer to hold the upcoming (remaining) text, test matches (eg regex) against it, and consume matches from the front could be useful. This could be implemented either by modifying the remaining string or by advancing an index within it.
Given such a buffer, your pseudocode might look like:
class EquationParser {
protected ParseBuffer buffer;
// parse Equation;
// -- of form "Sum -> Sum".
// -- eg. "12 CO2 + 6 H2O -> 2 C6H12O6 + 12 O2"
public Equation parseEquation() {
Sum left = parseSum();
matchAndConsume("->");
Sum right = parseSum();
return new Equation( left, right);
}
// parse Sum;
// -- eg. "12 CO2 + 6 H2O"
public Sum parseSum() {
// parse 1 or more Product terms;
Sum result = new Sum();
result.add( parseProduct());
while (buffer.lookaheadMatch("\\+")) {
buffer.consumeMatch("\\+");
result.add( parseProduct());
}
return result;
}
// parse Product term;
// -- of form "N formula", or just "formula".
// -- eg. "12 CO2" or "CO2"
public Product parseProduct() {
int quantity = 1;
if (buffer.lookaheadMatch("\\d+")) {
quantity = Integer.parseInt( buffer.consumeMatch("\\d+"));
}
Formula formula = parseFormula();
return new Product( quantity, formula);
}
// parse Formula;
// -- eg. "C6H12O6" or "CO2"
public Formula parseFormula() {
Formula result = new Formula();
result.add( parseTerm());
while (buffer.lookaheadMatch("[A-Z][a-z]?\\d*")) {
result.add( parseTerm());
}
return result;
}
// parse Term;
// -- eg. "C6", "C", "Co6", or "Co6"
public Term parseTerm() {
// ... reader exercise to implement...
}
protected void matchAndConsume (String patt) {
if (! buffer.lookaheadMatch( patt))
throw ParseFailed("parse failed: expected "+patt);
buffer.consumeMatch( patt);
}
}
This is conceptual example code, not tested & does not include the buffer or complete parser -- it is the reader's job to flesh these out to a complete solution.