package org.noreply.fancydress.directory.parser; import java_cup.runtime.*; parser code {: /* FIXME */ /* Change the method report_error so it will display the line and column of where the error occurred in the input as well as the reason for the error which is passed into the method in the String 'message'. */ public void report_error(String message, Object info) { /* Create a StringBuffer called 'm' with the string 'Error' in it. */ StringBuffer m = new StringBuffer("Error"); /* Check if the information passed to the method is the same type as the type java_cup.runtime.Symbol. */ if (info instanceof java_cup.runtime.Symbol) { /* Declare a java_cup.runtime.Symbol object 's' with the information in the object info that is being typecasted as a java_cup.runtime.Symbol object. */ java_cup.runtime.Symbol s = ((java_cup.runtime.Symbol) info); /* Check if the line number in the input is greater or equal to zero. */ if (s.left >= 0) { /* Add to the end of the StringBuffer error message the line number of the error in the input. */ m.append(" in line "+(s.left+1)); /* Check if the column number in the input is greater or equal to zero. */ if (s.right >= 0) /* Add to the end of the StringBuffer error message the column number of the error in the input. */ m.append(", column "+(s.right+1)); } } /* Add to the end of the StringBuffer error message created in this method the message that was passed into this method. */ m.append(" : "+message); /* Print the contents of the StringBuffer 'm', which contains an error message, out on a line. */ System.err.println(m); } /* Change the method report_fatal_error so when it reports a fatal error it will display the line and column number of where the fatal error occurred in the input as well as the reason for the fatal error which is passed into the method in the object 'message' and then exit.*/ public void report_fatal_error(String message, Object info) { report_error(message, info); System.exit(1); } :}; terminal NL, CR; terminal String SPACE, IDENTIFIER, LEFT_BRACKET, RIGHT_BRACKET, COLON; non terminal DirectoryEntry Entry; non terminal DirectorySection Section; non terminal DirectoryMessage Message; non terminal String Header; non terminal String OptValue, Value, NonSpaceValueChar, ValueChar, NonSpaceValue; non terminal String OptSpace; non terminal String EndOfLine, OptSpaceEndOfLine; start with Message; Message ::= Section:s {: RESULT = new DirectoryMessage(s); :} | Message:m Section:s {: m.addSection(s); RESULT = m; :} ; Section ::= Header:h {: RESULT = new DirectorySection(h); :} | Section:s Entry:e {: s.addEntry(e); RESULT = s; :} ; Header ::= LEFT_BRACKET IDENTIFIER:i RIGHT_BRACKET OptSpace EndOfLine {: RESULT = i; :} ; Entry ::= IDENTIFIER:i COLON SPACE OptValue:v EndOfLine {: RESULT = new DirectoryEntry(i, v.trim()); :} ; OptValue ::= Value:v OptSpace {: RESULT = v; :} | {: RESULT = new String(""); :} ; Value ::= NonSpaceValue:v {: RESULT = v; :} | Value:v1 SPACE:c NonSpaceValue:v2 {: RESULT = new String(v1+c+v2); :} ; NonSpaceValue ::= NonSpaceValueChar:c {: RESULT = c; :} | NonSpaceValue:v NonSpaceValueChar:c {: RESULT = new String(v+c); :} ; NonSpaceValueChar ::= IDENTIFIER:c {: RESULT = c; :} | COLON:c {: RESULT = c; :} | LEFT_BRACKET:c {: RESULT = c; :} | RIGHT_BRACKET:c {: RESULT = c; :} ; OptSpace ::= SPACE | ; EndOfLine ::= NL | CR | CR NL ;