/* NLCalculator.jj Simple interpreter of mathematical expressions given in natural language. By Davide Fossati, February 2007 */ options { LOOKAHEAD = 6; CHOICE_AMBIGUITY_CHECK = 7; OTHER_AMBIGUITY_CHECK = 2; FORCE_LA_CHECK = true; IGNORE_CASE = true; } PARSER_BEGIN(NLCalculator) public class NLCalculator { public static void main(String args[]) { NLCalculator interpreter = new NLCalculator(System.in); System.out.println("Welcome to the Natural Language Calculator!"); System.out.println("Written by Davide Fossati, February 2007."); System.out.println("-------------------------------------------"); System.out.println("I'm waiting for commands. Type 'quit' or 'exit' to quit."); boolean exit = false; while (exit == false) { try { exit = interpreter.Start(); } catch (ParseException pe) { System.out.println("Sorry, I couldn't understand your command."); interpreter.ReInit(System.in); exit = false; } } } } PARSER_END(NLCalculator) SKIP : { " " | "\t" } TOKEN : { | | } boolean Start() : {} { Command() { return false; } | ( ("exit" | "quit") | ) { return true; } } void Command() : {} { Tell() | Yell() } void Tell() : { double value; int n; } { "tell" "me" value = Expression() { System.out.println("The result is " + value); } } void Yell() : { double value; int n; } { "yell" value = Expression() { System.out.println("THE RESULT IS " + value + "!!!"); } } double Number() : { Token t; double x; } { t = { return Double.parseDouble(t.image); } | "zero" { return 0; } | x = LessThanAMillion() { return x; } } int LessThanAMillion() : { int x = 0; int thousand = 0; } { thousand = LessThanAThousand() "thousand" ( x = LessThanAThousand() )? { return 1000 * thousand + x; } | x = LessThanAThousand() { return x; } } int LessThanAThousand() : { int x = 0; int hundred = 0; } { hundred = LessThanAHundred() "hundred" ( x = LessThanAHundred() )? { return 100 * hundred + x; } | x = LessThanAHundred() { return x; } } int LessThanAHundred() : { int x = 0; int tenth = 0; } { x = Unit() { return x; } | x = TenToNineteen() { return x; } | tenth = Tenth() ( x = Unit() )? { return tenth + x; } } int Unit() : {} { "one" { return 1; } | "two" { return 2; } | "three" { return 3; } | "four" { return 4; } | "five" { return 5; } | "six" { return 6; } | "seven" { return 7; } | "eight" { return 8; } | "nine" { return 9; } } int TenToNineteen() : {} { "ten" { return 10; } | "eleven" { return 11; } | "twelve" { return 12; } | "thirteen" { return 13; } | "fourteen" { return 14; } | "fifteen" { return 15; } | "sixteen" { return 16; } | "seventeen" { return 17; } | "eighteen" { return 18; } | "nineteen" { return 19; } } int Tenth(): {} { "twenty" { return 20; } | "thirty" { return 30; } | "forty" { return 40; } | "fifty" { return 50; } | "sixty" { return 60; } | "seventy" { return 70; } | "eighty" { return 80; } | "ninety" { return 90; } } double Expression() : { double value; } { value = Number() { return value; } | value = UnaryOperation() { return value; } | value = BinaryOperation() { return value; } } double BinaryOperation() : { double value; } { value = Sum() { return value; } | value = Difference() { return value; } | value = Product() { return value; } | value = Ratio() { return value; } } double UnaryOperation() : { double value; } { value = Opposite() { return value; } | value = Inverse() { return value; } | value = Square() { return value; } | value = SquareRoot() { return value; } } double Sum() : { double x, y; } { "the" "sum" "of" x = Expression() "and" y = Expression() { return x + y; } } double Difference() : { double x, y; } { "the" "difference" "between" x = Expression() "and" y = Expression() { return x - y; } } double Product() : { double x, y; } { "the" "product" "of" x = Expression() "and" y = Expression() { return x * y; } } double Ratio() : { double x, y; } { "the" "ratio" "of" x = Expression() "over" y = Expression() { return x / y; } } double Opposite() : { double x; } { ("the" "opposite" "of" | "negative") x = Expression() { return -x; } } double Inverse() : { double x; } { "the" "inverse" "of" x = Expression() { return 1 / x; } } double Square() : { double x; } { "the" "square" "of" x = Expression() { return x * x; } } double SquareRoot() : { double x; } { "the" "square" "root" "of" x = Expression() { return Math.sqrt(x); } }