package de.unisiegen.gtitool.core.entities; import java.util.ArrayList; import de.unisiegen.gtitool.core.entities.regex.Regex; import de.unisiegen.gtitool.core.exceptions.alphabet.AlphabetException; import de.unisiegen.gtitool.core.exceptions.alphabet.AlphabetReservedSymbolException; import de.unisiegen.gtitool.core.parser.style.PrettyString; import de.unisiegen.gtitool.core.parser.style.PrettyToken; import de.unisiegen.gtitool.core.parser.style.Style; import de.unisiegen.gtitool.core.storage.Element; import de.unisiegen.gtitool.core.storage.exceptions.StoreException; /** * An {@link Alphabet} for {@link Regex}es that checks if Symbols are reserved * for Regex */ public class DefaultRegexAlphabet extends DefaultAlphabet { /** * The reserved {@link Symbol}s */ public static final Symbol [] RESERVED_SYMBOLS = { new DefaultSymbol ( "!" ), new DefaultSymbol ( "?" ), new DefaultSymbol ( "*" ), new DefaultSymbol ( "+" ), new DefaultSymbol ( "ยท" ), new DefaultSymbol ( "#" ), new DefaultSymbol ( "(" ), new DefaultSymbol ( ")" ), new DefaultSymbol ( "'" ) }; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ /** * The serial version uid. */ private static final long serialVersionUID = -7159328187623780150L; /** * Checks the {@link Symbol}s in the {@link ArrayList} for Classes * * @param list The {@link ArrayList} containing the {@link Symbol}s to check * @return {@link ArrayList} with the first class, if there is one, else there * is only one Element in the {@link ArrayList} */ public static ArrayList < Symbol > checkForClass ( ArrayList < Symbol > list ) { int dist = 1; int counter = 0; ArrayList < Symbol > s = new ArrayList < Symbol > (); // Epsilon if ( ( list == null ) || ( list.get ( counter ).getName () == null ) ) { s.add ( new DefaultSymbol () ); return s; } Symbol firstSymbol = list.get ( counter ); if ( firstSymbol.getName ().length () > 1 ) { dist = 2; } s.add ( firstSymbol ); while ( dist == 1 ) { Symbol s1 = list.get ( counter ); Symbol s2 = null; char c1 = s1.getName ().charAt ( 0 ); char c2 = 0; if ( counter + 1 != list.size () ) { s2 = list.get ( ++counter ); c2 = s2.getName ().charAt ( 0 ); } dist = c2 - c1; if ( dist == 1 ) { s.add ( s2 ); } } return s; } /** * Creates new {@link DefaultRegexAlphabet} with an {@link Element} * * @param e The {@link Element} * @throws StoreException When {@link Element} is not okay. * @throws AlphabetException When a reserved {@link Symbol} is in it. */ public DefaultRegexAlphabet ( Element e ) throws AlphabetException, StoreException { super ( e ); } /** * Creates new {@link DefaultRegexAlphabet} * * @param symbols The {@link Symbol}s of the Alphabet * @throws AlphabetException When a reserved {@link Symbol} is in it */ public DefaultRegexAlphabet ( Iterable < Symbol > symbols ) throws AlphabetException { super ( symbols ); } /** * Creates new {@link DefaultRegexAlphabet} * * @param symbols The {@link Symbol}s of the Alphabet * @throws AlphabetException When a reserved symbol is in it */ public DefaultRegexAlphabet ( Symbol ... symbols ) throws AlphabetException { super ( symbols ); } /** * Adds a {@link Symbol} to the Alphabet * * @param symbol The {@link Symbol} to add to the Alphabet * @throws AlphabetException When symbol is reserved */ @Override public void add ( Symbol symbol ) throws AlphabetException { checkReservedSymbols ( symbol ); super.add ( symbol ); } /** * Checks {@link DefaultRegexAlphabet} for {@link Symbol}s that are reserved * * @param symbol The {@link Symbol} to check * @throws AlphabetException Is thrown when symbol is reserved */ private void checkReservedSymbols ( Symbol symbol ) throws AlphabetException { ArrayList < Symbol > list = new ArrayList < Symbol > (); for ( Symbol reserved : RESERVED_SYMBOLS ) { if ( reserved.equals ( symbol ) ) { list.add ( symbol ); throw new AlphabetReservedSymbolException ( this, list ); } } } /** * {@inheritDoc} * * @see Alphabet#contains(Symbol) */ @Override public boolean contains ( Symbol symbol ) { if ( symbol.getName ().length () == 0 ) { return true; } return this.symbolSet.contains ( symbol ); } /** * Returns a {@link PrettyString} with Classes * * @return {@link PrettyString} with Classes */ public PrettyString toClassPrettyString () { PrettyString string = new PrettyString (); string.add ( new PrettyToken ( "{", Style.NONE ) ); //$NON-NLS-1$ boolean first = true; ArrayList < Symbol > t = new ArrayList < Symbol > (); t.addAll ( get () ); while ( !t.isEmpty () ) { ArrayList < Symbol > a = checkForClass ( t ); if ( !first ) { string.add ( new PrettyToken ( ", ", Style.NONE ) ); //$NON-NLS-1$ } first = false; if ( a.size () == 1 ) { string.add ( a.get ( 0 ) ); } else if ( a.size () == 2 ) { string.add ( a.get ( 0 ) ); string.add ( new PrettyToken ( ", ", Style.NONE ) ); //$NON-NLS-1$ string.add ( a.get ( 1 ) ); } else { string.add ( new PrettyToken ( "[", Style.NONE ) ); //$NON-NLS-1$ string.add ( a.get ( 0 ) ); string.add ( new PrettyToken ( "-", Style.NONE ) ); //$NON-NLS-1$ string.add ( a.get ( a.size () - 1 ) ); string.add ( new PrettyToken ( "]", Style.NONE ) ); //$NON-NLS-1$ } t.removeAll ( a ); } string.add ( new PrettyToken ( "}", Style.NONE ) ); //$NON-NLS-1$ return string; } }