# Escape Sequenzen \?...



## guitargod (22. Mai 2010)

Hallo,
Ich habe eine Frage, die sich mit Escape-Sequenzen im Datentyp Char beschäftigt:

Für eine Uni-Lehrveranstaltung bin ich gerade mit dem bauen eines Compilers beschäftigt.
Nun Lese ich also ein SrcFile ein, und habe dass intern als String vorliegen.

Schließlich wird die lexikalische Analyse gemacht ... es wird also Char für Char durchgegangen, und je nachdem ob es Zahl/Buchstabe etc. ist, intern weiterverarbeitet...

Mein Problem: Ich soll bei der Analyse auch Escape-Sequenzen, wie '\?' oder '\a' erkennen können.
D.H. wenn im Quelltext \? oder \a (und eineige weitere, die Java nicht erkennt) vorkommen, soll ich das auch als \? und \a erkennen.

Allerdings: wenn ich aus dem String, der den Quellcode enthält, die einzelnen Chars herauslese, dann wird \? als \\? gelesen. D.h. ich bekommen anstelle eines Chars mit Inhalt '\?', zwei Chars: '\\' und '?'.
Ich möchte aber \? als ganzes erkennen.

Ich hoffe ich konnte halbwegs klar machen was passiert...

Kann mir jemand helfen, ob mein Vorhaben überhaupt möglich ist? Oder muss ich die Sache anders rangehen, um die von mir gewünschten Chars zu erkennen...?

Wäre sehr, sehr dankbar für ein paar hilfreiche Tips!

Freundliche Grüße
Phil


----------



## guitargod (22. Mai 2010)

Hi,
ich vergaß zu erwähnen...da ja '\\' und '?' erkannt werden, hilft mir leider auch die Abfrage auf Backslash+Unicode-Darstellung des Fragezeichens nix...außerdem ist '\\' eine andere Escape-Sequenz, die ich auch erkennen sollte...


----------



## Ark (22. Mai 2010)

Die Menge der Escape-Sequenzen ist hoffentlich präfixfrei!? Ansonsten: Zeig doch mal Code! Ich vermute ja, dass ein simples Missverständnis vorliegt.

Ark


----------



## guitargod (22. Mai 2010)

Hi,
aaaalso:

erstmal lese ich das File hier ein:


```
public String ReadFile(String fileName) {
	
		  String s = null; 
	        StringBuffer datei = new StringBuffer();
		try{
	      
	        BufferedReader in = new BufferedReader(new FileReader(fileName)); 
	        while((s = in.readLine()) != null){ 
	           datei.append(s + System.getProperty("line.separator")); 
	           //System.out.println(s);
	        } 
	        in.close(); 
		}
		catch(Exception e){
			e.printStackTrace();
		}
		return datei.toString();
```


Anschließend hab ich einen String vorliegen.
Mit folgendem Code hol ich mir aus dem String Zeichen für Zeichen:


```
private char getNextChar(){
			return result code.charAt(currentCharId);
                        currentCharId++;
}
```

Danach folg nun die Überprüfung, was ich vorliegen hab. Z.b: Ziffer, Buchstabe, oder eben Escapezeichen usw.
Diese Methode wird einfach für jedes Zeichen aufgerufen (allerdings werden einige Escape-Sequenzen hier schon rot unterwellt...) Interessant wirds dann ab Zeile 45!


```
public int getType (char Symbol){
		//1 - nondigit
		switch(Symbol){
		case 'a': return m2mc.nondigit; 
		case 'b': return m2mc.nondigit;
		case 'c': return m2mc.nondigit;
		case 'd': return m2mc.nondigit;
		//usw
		case 'Y': return m2mc.nondigit;
		case 'Z': return m2mc.nondigit;
		case '0': return m2mc.digit;
		case '1': return m2mc.digit;
	       //usw
		case '9': return m2mc.digit;
		case '\'': return m2mc.q_ident;
		case '!' : return m2mc.q_char;
		case '#' : return m2mc.q_char;
		case '$' : return m2mc.q_char;
		case '%' : return m2mc.q_char;
		case '&' : return m2mc.q_char;
		case '(' : return m2mc.q_char;
		case ')' : return m2mc.q_char;
		case '*' : return m2mc.q_char;
		case '+' : return m2mc.q_char;
		case ',' : return m2mc.q_char;
		case '-' : return m2mc.q_char;
		case '.' : return m2mc.q_char;
		case '/' : return m2mc.q_char;
		case ':' : return m2mc.q_char;
		case ';' : return m2mc.q_char;
		case '<' : return m2mc.q_char;
		case '>' : return m2mc.q_char;
		case '=' : return m2mc.q_char;
		case '?' : return m2mc.q_char;
		case '@' : return m2mc.q_char;
		case '[' : return m2mc.q_char;
		case ']' : return m2mc.q_char;
		case '^' : return m2mc.q_char;
		case '{' : return m2mc.q_char;
		case '}' : return m2mc.q_char;
		case '|' : return m2mc.q_char;
		case '~' : return m2mc.q_char;
		case ' ' : return m2mc.q_char;

//ab hier wirds interessant
		case '\'' : return m2mc.s_escape;
		case '\"' : return m2mc.s_escape;
		case '\?' : return m2mc.s_escape;
		case '\\' : return m2mc.s_escape;
		case '\a' : return m2mc.s_escape;
		case '\b' : return m2mc.s_escape;
		case '\f' : return m2mc.s_escape;
		case '\n' : return m2mc.s_escape;
		case '\r' : return m2mc.s_escape;
		case '\t' : return m2mc.s_escape;
		case '\v' : return m2mc.s_escape;
		case '\"' : return m2mc.string;
		default: return m2mc.unknown;
		}
```

Freundliche Grüße


----------



## Ark (22. Mai 2010)

Wie erwartet: ein Missverständnis. 

```
case '\a' : return m2mc.s_escape;
```
Das [c]\a[/c] ist ein(!) Zeichen, und nicht etwa [c]\[/c] gefolgt von [c]a[/c].

Nebenbei: Wozu ist getType() eigentlich gut?

Wenn du eine Maschine hast, die den Code von getType() generiert, okay. Aber du musst nicht jeden Einzelfall aufschreiben. Man kann sich auch kürzer fassen (und lokale Variablen beginnen mit Kleinbuchstaben!):


```
public int getType (char symbol){
		//1 - nondigit
		if(symbol >= 'a' && symbol <= 'z') return m2mc.nondigit;
		if(symbol >= 'A' && symbol <= 'Z') return m2mc.nondigit;
		if(symbol >= '0' && symbol <= '9') return m2mc.digit;
		// usw.
```

Wenn du Escape-Sequenzen in der Eingabe erkennen willst, musst du zwei (oder halt so viele wie nötig) Zeichen lesen (du hast übrigens irgendwie doppelte case-Labels in deinem Code, die habe ich gerade mal ignoriert):

```
// [...] ... dein alter Code ...

//ab hier wirds interessant
		case '\\' : // das ist das vorangestellte \
			switch(naechstes_Zeichen){ // irgendwie daherzaubern
				case '?' : // fall-through ausnutzen
				case '\\' :
				case 'a' :
				case 'b' :
				case 'f' :
				case 'n' :
				case 'r' :
				case 't' :
				case 'v' : return m2mc.s_escape;
				default: return m2mc.unknown;
			}
		default: return m2mc.unknown;
}
```
Ark


----------



## guitargod (22. Mai 2010)

Was soll ich noch viel sagen, außer *DANKE*! Hat mir sehr geholfen!


----------



## faetzminator (22. Mai 2010)

Wär da nicht evtl. ein Regex Pattern sinnvoll, irgendwie [c](\\\\)*(\\a)[/c] ([c]$1[/c]) für "\a" bzw. nicht "\\a" und trotzdem "\\\a" aber ohne "\\\\a" etc.  ?


----------



## guitargod (23. Mai 2010)

faetzminator hat gesagt.:


> Wär da nicht evtl. ein Regex Pattern sinnvoll, irgendwie [c](\\\\)*(\\a)[/c] ([c]$1[/c]) für "\a" bzw. nicht "\\a" und trotzdem "\\\a" aber ohne "\\\\a" etc.  ?



da ich's jetzt schon hinbekommen hab, lass ich's mal. Für's nächste mal aber ein guter Tip! Danke!


----------

