0

Donc j'essayais de construire un petit scanner lexical qui atomise le texte et détermine le type de chaque jeton. La sortie doit être un fichier texte portant le numéro de ligne d'un jeton &, tapez à chaque ligne. Si le jeton n'est accepté par aucun élément RE, il doit signaler une erreur significative indiquant le numéro de ligne du jeton, le jeton et l'erreur. J'ai utilisé la bibliothèque regexp en C++, et maintenant j'essaie d'impliquer la fonction d'itérateur sur le code ci-dessous mais je ne savais pas comment l'utiliser ici.C++ en utilisant la fonction d'itération pour le compilateur

#include <iostream> 
#include <string> 
#include <regex> 
#include <sstream> 
#include <fstream> 
using namespace std; 

int main() 
{ 
    ofstream myfile; 
    myfile.open("mytext1.txt"); 
    myfile << " int 33.2 + bla 059 3 " << endl; 
    myfile << " void nn + fbla 09 3 " << endl; 
    myfile << " int float + bsla 09 3.2 " << endl; 
    myfile.close(); 

    string s; 
    regex keywords("int|if|else|while|float|return|void|breack|for"); 
    regex id("[[:alpha:]]+[[:d:]]*[[:alpha:]]*", regex_constants::icase); 
    regex integer("[[:d:]]+"); 
    regex floatt("[[:d:]]+[.]+[[:d:]]+"); 
    regex symbolls("[&&]|[||]|[<=]|[>=]|[==]|[<]|[>]|[!=]|[=]|[(]|[)]|[{]|[}]|[;]|[,]|[.]|[+]|[-]|[*]|[/]|[/*]|[*/]"); 
    regex comment("//[[:w:]]*"); 
    ifstream myfile2("mytext1.txt"); 

    //int linenum= 1; 
    if (myfile2.is_open()) 
    { 
     while (getline(myfile2, s, ' ')) 
     { 
      cout << s << ","; 
      //cout <<linenum<< s << ","; 

      bool match = regex_match(s, floatt); 
      if (match) cout << "float number" << endl; 
      match = regex_match(s, integer); 
      if (match)cout << "integer number" << endl; 
      match = regex_match(s, keywords); 
      if (match){ cout << "keywords" << endl; goto a; 
     } 
      match = regex_match(s, id); 
      if (match)cout << "identifer" << endl; 
     a: match = regex_match(s, comment); 
      if (match)cout << "comment" << endl; 
      match = regex_match(s, symbolls); 
      if (match)cout << "symbolls" << endl;} 

    } myfile2.close(); 

    system("pause"); 
    return 0; 
} 

Répondre

0

Les symboles regex ne fait pas ce que vous pensez.

Problèmes:
- Metachars comme littéraux doivent être échappé.
- Les classes de caractères sans quantificateurs ne correspondent qu'à un seul caractère.
- Les alternances sont hiérarchisées de gauche à droite (par exemple a|aw correspondra uniquement à a we). La solution est de mettre le plus long en premier aw|a.

Conseil utile: Évitez d'utiliser posix si vous n'avez pas à le faire.

En ce qui concerne la fonction regex_match(), en C++, l'expression régulière doit généralement correspondre à la ligne complète. Pour rechercher des sous-chaînes, utilisez regex_search().

Généralement, il est assez complexe d'écrire un analyseur car chaque caractère doit être séquentiellement analysé. A tout moment, chaque jeton doit mettre la logique dans un état qui ne doit accepter que certains caractères ou d'autres jetons.

De toute façon, bonne chance.
Vous trouverez ci-dessous quelques expressions regex trafiquées de vos originaux.

keywords "int|if|else|while|float|return|void|breack|for" 
    ----------- 
     int 
    | if 
    | else 
    | while 
    | float 
    | return 
    | void 
    | breack 
    | for 

    id "[a-zA-Z]+[0-9]*[a-zA-Z]*" 
    ----------- 
    [a-zA-Z]+ [0-9]* [a-zA-Z]* 

    integer "[0-9]+" 
    ----------- 
    [0-9]+ 

    floatt "[0-9]+[.]+[0-9]+" 
    ----------- 
    [0-9]+ [.]+ [0-9]+ 

    symbols "[&]{2}|[|]{2}|<=|>=|[=]{2}|!=|/\\*|\\*/|[<>(){};,.+*/=-]" 
    ----------- 
     [&]{2} 
    | [|]{2} 
    | <= 
    | >= 
    | [=]{2} 
    | != 
    | /\* 
    | \*/ 
    | [<>(){};,.+*/=-] 


    comment 
    ----------- 
    // [a-zA-Z0-9_]*