myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Gemeinschaft » .NET-Komponenten und C#-Snippets » Regex-basierter Tokenizer
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Regex-basierter Tokenizer

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
TheBrainiac TheBrainiac ist männlich
myCSharp.de-Mitglied

avatar-3152.png


Dabei seit: 17.12.2006
Beiträge: 795
Entwicklungsumgebung: VS 2010 Prof.
Herkunft: /dev/null


TheBrainiac ist offline

Regex-basierter Tokenizer

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi @ All!

Nach längerer Schaffenspause habe ich mal wieder die Zeit gefunden, ein kleines Projekt zu entwickeln. Entstanden ist diese Idee bei einem Java-Projekts während meinem Studium. Den Tokenizer habe ich auch erst in Java umgesetzt und jetzt nach C# portiert, da ich ihn euch nicht vorenthalten will großes Grinsen .

Was kann der Tokenizer?
Er kann beliebige Eingabe-Strings in Tokens zerlegen, wobei die Regeln für die Zerlegung Regex-basiert sind.

Wie konfiguriere ich den Tokenizer?
Dafür gibt es zwei Möglichkeiten:

1. "Zu Fuß":
Angenommen, wir wollen folgendes Snippet farbig hervorheben:

C#-Code:
void Test() {
    Console.WriteLine("THIS IS SPARTA!!!");
}

Dafür müssen wir es nur mit folgendem Code in Tokens zerlegen:

C#-Code:
var tokenizer = new Tokenizer();

tokenizer.Add("STRING", @"""[^""]*""", 4);
tokenizer.Add("KEYWORD", @"\bvoid\b", 3);
tokenizer.Add("IDENTIFIER", @"\w+", 2);
tokenizer.Add("OPERATOR", @"[(){};.]", 1);
tokenizer.Add("WHITESPACE", @"\s+", 0, true);

var tokens = tokenizer.Tokenize(input);

Nun können einfach wir anhand der Tokens den Text z.b. in einer RichTextBox farbig hervorheben.

2. Per Regel-Datei:
Angenommen, wir wollen folgendes Mathe-Skript in Tokens zerlegen, um es anschließend Parsen zu können:

Code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
const PI = 3.14159265358979323846;

function f(x) = sqrt(x ^ 3);

var a = PI*12;

print f(a);

a = a / 4;

print f(a);

Dafür reicht folgende kleine Regel-Datei:

Code:
1:
2:
3:
4:
5:
DIGIT       "\d+(\.\d+)?"                     5
OPERATOR    "[()-+*/%=;^]"                    4
KEYWORD     "\b(var|const|function|print)\b"  3
IDENTIFIER  "\w+"                             2
WHITESPACE* "\s+"                             1

Mithilfe dieser Regel-Datei lässt sich nun ganz einfach ein Tokenizer erzeugen:

C#-Code:
var tokenizer = Tokenizer.CreateFrom(File.ReadAllText("myRuleFile.txt"));

var tokens = tokenizer.Tokenize(input);

Die Tokens können wir nun zum Parsen verwenden.

Wie sind die Regel aufgebaut?
Eine Regel hat 4 Eigenschaften:
  • Name: Gibt den Namen der Regel an.
  • Pattern: Das Pattern, das matchen muss, um ein Token mit der aktuellen Regel erzeugen zu können.
  • Weight: Das "Gewicht" der Regel - Regeln mit höherem Gewicht werden zuerst angewendet.
  • Ignore: Gibt an, ob mit dieser Regel erzeugte Tokens ignoriert werden sollen. Wird in einer Regel-Date mit einem * hinter dem Namen angegeben
Wie sind die Tokens aufgebaut?
Ein Token enthält den gematchten String, den Namen der Regel, mit der es gefunden wurde sowie die Position, an der es gefunden wurde.

Ich hoffe, jemand kann das gebrauchen, mir hat er (bzw. die Java-Version) dicke Bonuspunkte eingebracht cool .

Gruß, Christian.

// Edit: Downloads V1: 3


Dateianhang:
unknown BrainiacsCode.Tokenizer.zip (33,50 KB, 397 mal heruntergeladen)

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von TheBrainiac am 31.03.2011 14:07.

30.03.2011 17:55 Beiträge des Benutzers | zu Buddylist hinzufügen
der-schlingel der-schlingel ist männlich
myCSharp.de-Mitglied

avatar-3239.jpg


Dabei seit: 13.10.2007
Beiträge: 799
Entwicklungsumgebung: VS 2005/ 2008 Pro
Herkunft: Österreich/Wien


der-schlingel ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

[offtopic]Die Java-Version? Wieso nicht gleich den StreamTokenizer verwenden?[/offtopic]

Was ganz nett wäre wenn wie bei lex Methoden an die einzelnen Tokens gebunden werden können.
30.03.2011 22:15 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
TheBrainiac TheBrainiac ist männlich
myCSharp.de-Mitglied

avatar-3152.png


Dabei seit: 17.12.2006
Beiträge: 795
Entwicklungsumgebung: VS 2010 Prof.
Herkunft: /dev/null

Themenstarter Thema begonnen von TheBrainiac

TheBrainiac ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

[offtopic]

Zitat von der-schlingel:
Die Java-Version? Wieso nicht gleich den StreamTokenizer verwenden?

Weil wir eine Scheme-ähnliche Sprache verarbeiten wollten. Da sind mehr als nur die normalen Zeichen in Identifiern erlaubt, z.b. foo-bar?!=<> ist hier ein vailder Identifier.[/offtopic]


Zitat von der-schlingel:
Was ganz nett wäre wenn wie bei lex Methoden an die einzelnen Tokens gebunden werden können.

Wie meinst du das?

Gruß, Christian.
30.03.2011 23:54 Beiträge des Benutzers | zu Buddylist hinzufügen
der-schlingel der-schlingel ist männlich
myCSharp.de-Mitglied

avatar-3239.jpg


Dabei seit: 13.10.2007
Beiträge: 799
Entwicklungsumgebung: VS 2005/ 2008 Pro
Herkunft: Österreich/Wien


der-schlingel ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

siehe einfach  Wiki-Page zu lex

Es ist möglich gleich ein bisserl an den Strings herum zu spielen und zwar sofort wenn der Token identifiziert wurde.
31.03.2011 12:58 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
TheBrainiac TheBrainiac ist männlich
myCSharp.de-Mitglied

avatar-3152.png


Dabei seit: 17.12.2006
Beiträge: 795
Entwicklungsumgebung: VS 2010 Prof.
Herkunft: /dev/null

Themenstarter Thema begonnen von TheBrainiac

TheBrainiac ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

So, hab das mal eben angepasst.

Nun ist es möglich, das Token selbst zu erstellen:

C#-Code:
tokenizer.Add("STRING", @"""[^""]*""", 4, (type, content, position) => {
    var processed = content.Substring(1, content.Length - 2);

    return new Token(type, content, position, processed);
});
tokenizer.Add("NUMBER", @"\d+", 3, (type, content, position) => new Token(type, content, position, Int32.Parse(content)));

Das Token hat nun eine Eigenschaft mehr, nämlich State. Hierdrin kann nun ein beliebiges Objekt gespeichert werden.

Habe den Download oben erneuert.

Gruß, Christian.
31.03.2011 14:06 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 9 Jahre.
Der letzte Beitrag ist älter als 9 Jahre.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 27.05.2020 07:23