#!/usr/bin/env perl

use strict;
use Parse::RecDescent;

my $parser = Parse::RecDescent->new(q(
    VARIABLE : /[A-Z][a-zA-Z0-9]*/
    TOP: "top"
    BOTTOM: "bot"
    NEG: '!'
    CONJ: '&'
    DISJ: '|'
    IMPL: "->"
    EQUI: "<->"
    OP: CONJ | DISJ | IMPL | EQUI
    formula0 : VARIABLE 
             | TOP 
             | BOTTOM 
             | /[(]/ NEG formula0 /[)]/ 
             | /[(]/ formula0 OP formula0 /[)]/
    # The following rule only makes sure that the string ends after formula0.
    # Otherwise any string starting with a valid formula would be recognised.
    # The return statement returns the value associated to formula0,
    # by default the value associated to /\Z/ would be returned, which is
    # always false, so we could not tell whether there was a successful match.
    formula : formula0 /\Z/ {return $item[1]}
  ));

# Now read from standard input and try to parse each line.
while(<STDIN>) {
    if ($parser->formula($_)) {
	print "Valid formula.\n";
    } else {
	print "Not a valid formula.\n";
    }
}

