In C++ Identifiers klassifizieren (Typ/Variablenname)
-
manni66 schrieb:
const int i;
Das geht, Schlüsselwörter kann ich erkennen.
int* j;
int& k;Stimmt, * und & dürfen beliebig gemischt dazwischen stehen.
-
-
int i,j;
-
keincompilerbauer schrieb:
int* j;
int& k;Stimmt, * und & dürfen beliebig gemischt dazwischen stehen.
// 1. typedef int A; A * B; // Deklaration // 2. int A, B; A * B; // AusdruckC++ ist voll von solchen Mehrdeutigkeiten.
-
struct { ... } var;
-
keincompilerbauer schrieb:
Dann kommt natürlich hinzu, dass nach class/struct immer ein Typ folgt.
struct Typ class Typwohl eher aus c zeiten aber ist in c++ afaik auch erlaubt:
typedef struct { // ... } Foo; typedef struct { // ... } * Bar;natürlich dann auch typendeduktion:
auto Foo = 5; decltype(Foo) Bar; auto Baz = [](){};und natürlich funktions- und methodenzeiger (bin mir nicht schlüssig ob das schon abgedeckt ist bislang):
int (*Foo)(int); int (MyClass::*Bar)(int) const;unbenannte typen:
enum { Value = 42 }; class { int a; } Foo; union { int a; int b; } Bar;mehrfachdeklarationen:
int a, * b; int const* c, d;edit:
keincompilerbauer schrieb:
Meine Idee ist, dass wenn zwei Identifiers nebeneinander stehen, dass das dann eine Variablendeklaration sein muss und das erste ein Typ ist und das zweite der Variablenname.
bin mir nicht sicher ob das hier abgedeckt ist:
int Foo(); // Funktionsdeklaration int Bar(1); // Instanziierungoder templates:
template<typename T = int> struct MyClass1 { }; MyClass1<> Foo; MyClass<bool> Bar; template<int I> struct MyClass2 { }; MyClass2<42> Baz;template<class T> struct Foo { }; template<template<class> class T> struct Bar { }; Bar<Foo> Baz;struct Bar { typedef int A; }; struct Baz { typedef char A; }; template<typename T> struct Foo { typedef typename T::A B; }; Foo<Bar>::B C;edit:
template<class T, int> struct Bar { typedef char Type; }; template<int V> struct Bar<int, V> { typedef void Type; }; template<template<class, int> class T = Bar> struct Foo : T<int, 42> { typedef T<int, 42> Base; typedef typename Base::Type Type; }; Foo<>::Type const* const& Baz = 0;sorry, gerade so freude daran mir sinnlosen quatsch auszudenken, ich hör schon auf...
-
Eben darum: libclang...
-
Hi es kamen jetzt eine ganze Menge Beispiele, aber keiner hat Deine erste Regel verletzt. Allerdings mußt Du Deine Regel etwas anpassen. Das gilt nämlich nur für den Anfang eines Statements und natü+rlich nur dann, wenn der Präproessor schon seine Arbeit verichtet hat.
Also bei zwei Identifiers am Anfang eines Statements OHNE Operator dazwischen, also nur white Spaces, ist muß der erste eine Typ sein.
Allerdings dürftest Du damit nur die wenigsten Typen finden. Denn fast immer befindet sich noch ein Schlüssewort davor. Darüber hinaus gibt es ja auch Schlüsselworte, die Typen bezeichnen. Da Du sowieso alle Schlüsselworte kennen mußt, um nicht versehentlich ein Schlüsselwort als Bezeichner zu behandeln, kannst Du die wichtigsten natürlich auch gleich korrekt behandeln.
Da wären als erstes natürlich die eingebauten Typen:
bool, char, int, float, doubleDann natürlich die Typmodifiers
short, long, signed, unsigned, constund zum schluß die zusammengestzen Typen:
struct, union, classebenfalls nicht zu schwer sollte sein
enumWichtig ist halt auch, daß Du erkennen können mußt, WO die Statements anfangen. Dazu suchst Du alle geschweiften Klammern und Strichpunkte, die NICHT in einem Kommentar, literal oder einem for-statement sind.
Jetzt habe ich genug geschrieben und ich habe bestimmt irgendwas vergessen. Wenn Du das immer noch machen willst, viel Spaß, ist bestimmt sehr interessant.
mfg Martin
-
mgaeckler schrieb:
Wichtig ist halt auch, daß Du erkennen können mußt, WO die Statements anfangen. Dazu suchst Du alle geschweiften Klammern und Strichpunkte, die NICHT in einem Kommentar, literal oder einem for-statement sind.
Das mit dem Anfang eines Statements kannst Du vergessen. Wenn Du zwei Bezeichner nur mit white spaces getrennt im Quelltext findest, dann muß der erste ein Typ sein. egal wo auch immer er steht. Allerdings solltest Du dann auch unbedingt :: erkennen können, damit Du den Typ nicht unvollständig liest.
Wenn Operatoren dazwischen stehen, wird's kompliziert.
A * B;
kann eine Multiplikation oder eine Deklaration sein, wie schon ein anderer vorher geschrieben haben. Ich schreibe es nur der Vollständigkeit halber

mfg Martin
Dies ist keine Doktorarbeit, daher mache ich's wie Gutenberg. Ich entschuldige mich schon mal beim Autor, des zitierten Textes, aber das Beispiel find ich zu gut.
-
Das Problem haben sicher schon K&R beim Entwurf des ersten C-Compilers bemerkt.
-
Bashar schrieb:
Das Problem haben sicher schon K&R beim Entwurf des ersten C-Compilers bemerkt.
Erst nachdem sie typedef implementiert haben.