/* FormatParser.java */ /* This parser parses Fortran format strings. */ options { STATIC = true; DEBUG_PARSER = false; DEBUG_TOKEN_MANAGER = false; DEBUG_LOOKAHEAD = false; } PARSER_BEGIN(FormatParser) class FormatParser { } PARSER_END(FormatParser) SKIP : { <(" ")+> } TOKEN : { } // An unsigned integer, for repetition factors, field widths, etc. TOKEN : { } // A string literal inside a format. We haven't implemented // embedded quotes yet. int Integer(): { Token t; } { t= { return (Integer.valueOf(t.image)).intValue(); } } FormatElement FormatIOElement(): { FormatElement fe; int w, d; } { ( "A" w=Integer() { fe=new FormatA(w); } | "I" w=Integer() { fe=new FormatI(w); } | "F" w=Integer() "." d=Integer() { fe=new FormatF(w,d); } | "E" w=Integer() "." d=Integer() { fe=new FormatE(w,d); } ) { return fe; } } // This represents a format element that transfers one // data item. FormatElement FormatNonIOElement(): {} { "X" { return new FormatX(); } } // This represents a format element that doesn't transfer // any data items. FormatElement FormatElement(): { FormatElement fe; } { ( fe=FormatIOElement() | fe=FormatNonIOElement() ) { return fe; } } FormatSlash FormatSlash(): {} { "/" { return new FormatSlash(); } } // These are a special case. Unlike other format elements, // Fortran permits several slashes to be concatenated without // commas to separate them, and you can't use a repetition // factor on them. FormatString FormatString(): { Token t; String s; } { ( t= ) { s = t.image; s = s.substring(1,s.length()-1); // Remove the quotes. return new FormatString(s); } } // Another special case that can't be repeated, and can be // concatenated to other elements without commas. void OptionalFormatSlashesOrStrings( Format f ): { FormatUniv fs; } { ( (fs=FormatSlash() | fs=FormatString()) { f.addElement(fs); } )* } FormatRepeatedItem FormatRepeatedItem(): { int r=1; FormatUniv fu; } { [ r=Integer() ] ( "(" fu=Format() ")" | fu=FormatElement() ) { return new FormatRepeatedItem( r, fu ); } } void FormatGroup( Format f ): { FormatRepeatedItem fri; } { ( OptionalFormatSlashesOrStrings( f ) [ fri = FormatRepeatedItem() { f.addElement(fri); } OptionalFormatSlashesOrStrings( f ) ] ) } // This rather messy syntax allows us to have slashes and/or // strings either side of a format element or repeated group // without needing to separate them from each other or the element // with commas. // It also means that we can have empty format groups and format // groups that don't transfer any data elements. So for example, // the format ,/, is valid under this grammar. Format Format(): { FormatRepeatedItem fri; Format f = new Format(); } { ( FormatGroup(f) ) ( "," ( FormatGroup(f) ) )* { return f; } }