/* * * Copyright 2012 lexergen. * This file is part of lexergen. * * lexergen is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * lexergen is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with lexergen. If not, see <http://www.gnu.org/licenses/>. * * lexergen: * A tool to chunk source code into tokens for further processing in a compiler chain. * * Projectgroup: bi, bii * * Authors: Johannes Dahlke * * Module: Softwareprojekt Übersetzerbau 2012 * * Created: Apr. 2012 * Version: 1.0 * */ package de.fuberlin.bii.regextodfaconverter.directconverter.regex; import java.util.ArrayList; import java.util.List; import de.fuberlin.bii.regextodfaconverter.Regex; import de.fuberlin.bii.regextodfaconverter.directconverter.lrparser.grammar.Terminal; import de.fuberlin.bii.regextodfaconverter.directconverter.regex.operatortree.RegularExpressionElement; import de.fuberlin.bii.utils.TriState; /** * Zeichensatz für reguläre Ausdrücke. * * @author Johannes Dahlke * */ public class RegexCharSet { /** * Aternative */ public static final char REGEX_ALTERNATIVE = '|'; /** * Ziechen zum Maskieren von Sonderzeichen. */ public static final char REGEX_MASK = '\\'; /** * Kennzeichnet den Beginn einer Zeichenklasse. */ public static final char REGEX_CLASS_BEGIN = '['; /** * Kennzeichnet das Ende einer Zeichenklasse. */ public static final char REGEX_CLASS_END = ']'; /** * Kennzeichnet den Beginn einer Wiederholung. */ public static final char REGEX_REPETITION_BEGIN = '{'; /** * Kennzeichnet das Ende einer Wiederholung. */ public static final char REGEX_REPETITION_END = '}'; /** * Kennzeichnet den Beginn einer Gruppe. */ public static final char REGEX_GROUP_BEGIN = '('; /** * Kennzeichnet das Ende einer Gruppe. */ public static final char REGEX_GROUP_END = ')'; /** * Kleenesche Hülle. */ public static final char REGEX_KLEENE_CLOSURE = '*'; /** * Positive Hülle. */ public static final char REGEX_POSITIVE_CLOSURE = '+'; /** * Optionales Vorkommen des davor stehenden Zeichens. */ public static final char REGEX_OPTION = '?'; /** * Ein beliebiges Zeichen. */ public static final char REGEX_JOKER = '.'; /** * Anfangsmarker. */ public static final char REGEX_START_MARKER = '^'; /** * Negation einer Zeichenklasse. */ public static final char REGEX_CLASS_SIGNUM = '^'; /** * Endmarker. */ public static final char REGEX_END_MARKER = '$'; /** * Zum Notieren eines Wertebereichs innerhalb einer Zeichenklasse. * */ public static final char REGEX_RANGE = '-'; /** * Treener für die Angabe von Wiederholungen. */ public static final char REGEX_QUANTIFIER_SEPARATOR = ','; /** * Das leere Wort. */ public static final char EMPTY_STRING = 0x00; /** * Das Ende der Eingabe. */ public static final char TERMINATOR = 0x03; // ETX = End Of Text /** * Definiert das erste Zeichen des Alphabets aus dem ASCII Zeichensatz. * * Zeichen 0x00 - 0x03 sind geschützt. */ private static char FIRST_ASCII_CHAR = 0x04; /** * Definiert das letzte Zeichen des Alphabets aus dem ASCII Zeichensatz. */ private static char LAST_ASCII_CHAR = 0xFF; /** * Liefert das Zeichen mit dem niedrigsten Ordinalwert * aus der Menge der für reguläre Ausdrücke zugelassenen Zeichen. * * @return das niederwertigste zulässige Zeichen. */ public static char getFirstAsciiChar() { return FIRST_ASCII_CHAR; } /** * Liefert das Zeichen mit dem höchsten Ordinalwert * aus der Menge der für reguläre Ausdrücke zugelassenen Zeichen. * * @return das höchstwertigste zulässige Zeichen. */ public static char getLastAsciiChar() { return LAST_ASCII_CHAR; } /** * Liefert den gesamten Wertebereich. * @return */ public static List<Character> getCompleteDomain() { List<Character> result = new ArrayList<Character>(); for ( int c = getFirstAsciiChar(); c <= getLastAsciiChar(); c++) { result.add( (char) c); } return result; } /** * Liefert eine Liste der Metazeichen in Abhängigkeit des Kontext. * @param context * @return */ public static List<Character> getMetaCharsOfContext( RegexSection context) { List<Character> result = new ArrayList<Character>(); for ( int c = getFirstAsciiChar(); c <= getLastAsciiChar(); c++) { if ( isSpecialChar( (char) c, context).isntFalse()) result.add( (char) c); } return result; } /** * Liefert eine Liste der Ungeschützten Zeichen bezüglich des angegebenen Kontextes. * @param context * @return */ public static List<Character> getUnguardedCharsOfContext( RegexSection context) { List<Character> result = new ArrayList<Character>(); for ( int c = getFirstAsciiChar(); c <= getLastAsciiChar(); c++) { if ( isSpecialChar( (char) c, context).isFalse()) result.add( (char) c); } return result; } /** * Prüft, ob ein Zeichen ein Zeichen mit besonderer Bedeutung bezüglich regulärer Ausdrücke ist. * @param theCharacter * @return */ public static TriState isSpecialChar( char theCharacter, RegexSection context) { switch ( theCharacter) { case REGEX_MASK: return defineAndGetStateByContext( context, TriState.TRUE, TriState.FALSE, TriState.TRUE); case REGEX_GROUP_BEGIN: return defineAndGetStateByContext( context, TriState.TRUE, TriState.FALSE, TriState.FALSE); case REGEX_GROUP_END: return defineAndGetStateByContext( context, TriState.TRUE, TriState.FALSE, TriState.FALSE); case REGEX_CLASS_BEGIN: return defineAndGetStateByContext( context, TriState.TRUE, TriState.FALSE, TriState.FALSE); case REGEX_CLASS_END: return defineAndGetStateByContext( context, TriState.TRUE, TriState.FALSE, TriState.TRUE); case REGEX_ALTERNATIVE: return defineAndGetStateByContext( context, TriState.TRUE, TriState.FALSE, TriState.FALSE); case REGEX_REPETITION_BEGIN: return defineAndGetStateByContext( context, TriState.TRUE, TriState.FALSE, TriState.FALSE); case REGEX_REPETITION_END: return defineAndGetStateByContext( context, TriState.TRUE, TriState.FALSE, TriState.FALSE); case REGEX_KLEENE_CLOSURE: return defineAndGetStateByContext( context, TriState.TRUE, TriState.FALSE, TriState.FALSE); case REGEX_POSITIVE_CLOSURE: return defineAndGetStateByContext( context, TriState.TRUE, TriState.FALSE, TriState.FALSE); case REGEX_OPTION: return defineAndGetStateByContext( context, TriState.TRUE, TriState.FALSE, TriState.FALSE); case REGEX_JOKER: return defineAndGetStateByContext( context, TriState.TRUE, TriState.FALSE, TriState.FALSE); //case REGEX_CLASS_SIGNUM: case REGEX_START_MARKER: return defineAndGetStateByContext( context, TriState.TRUE, TriState.FALSE, TriState.AMBIGUOUS); case REGEX_END_MARKER: return defineAndGetStateByContext( context, TriState.TRUE, TriState.FALSE, TriState.FALSE); case REGEX_RANGE: return defineAndGetStateByContext( context, TriState.FALSE, TriState.FALSE, TriState.AMBIGUOUS); default: return defineAndGetStateByContext( context, TriState.FALSE, TriState.FALSE, TriState.FALSE); } } private static TriState defineAndGetStateByContext( RegexSection context, TriState stateOfMainContext, TriState stateOfQuantifierContext, TriState stateOfClassContext) { if ( context == RegexSection.MAIN) return stateOfMainContext; if ( context == RegexSection.QUANTIFIER) return stateOfQuantifierContext; // default case // if ( context == RegexSection.CHARACTER_CLASS) return stateOfClassContext; } /** * Gibt an, ob es sich bei dem gegebenen Zeichen um ein Sonderzeichen bezüglich des {@link RegexSection#MAIN} Kontextes handelt. * @param theCharacter * @return */ public static TriState isSpecialChar( char theCharacter) { return isSpecialChar( theCharacter, RegexSection.MAIN); } /** * Ermittelt, ob ein Zeichen zu dem grundlegenden Regex Zeichensatz gehört. * @param theCharacter * @return */ public static boolean isElementOfBasicCharset( char theCharacter) { switch ( theCharacter) { case REGEX_MASK: case REGEX_ALTERNATIVE: case REGEX_KLEENE_CLOSURE: return true; default: return false; } } /** * Prüft, ob es sich um einen Regex-Operator der nicht erweiterten regulären Ausdrücke handelt. * @param theChar * @return */ public static boolean isBasicOperator( char theChar) { switch ( theChar) { case REGEX_ALTERNATIVE: case REGEX_KLEENE_CLOSURE: return true; default: return false; } } /** * Prüft, ob es sich um ein leeres Wort handelt. * @param theCharacter * @return */ public static boolean isEmptyString( char theCharacter) { return EMPTY_STRING == theCharacter; } }