Lexikalische Analyse mit FLEX
-
Kennt sich hier jemand mit dem Tool Flex aus?
Folgendes Codefragment funktioniert nicht korrekt bzw. ich habe das falsch definiert.
Und zwar ab Zeile 51-57 gibt es Probleme. Und zwar wird nur der Teile Zeile 55-57 ausgeführt.
Das obere wird nicht beachtet.
Wenn ich nur das Obere(Zeile 51-53) im Quellcode, also ihne Zeile 55-57 habe, dann funktioniert auch das eigentlich korrekt und es wird das Erwartete ausgegeben.Zum eigentlichen Ziel: ich möchte aus einer xhtml datei aus einem validen a-tag das Attribut href=""... und den Linktext extrahieren und ausgeben. Für den Linktext gilt dass das href-Attribut in dem a-tag enthalten ist und alle weitere Attribute sollen einfach ignoriert werden.
Ganz unten stehtich die entspechende Test HTML Datei.
%option noyywrap yylineno nounput noinput never-interactive LETTER [b-z] WS [[:space:]] SLASH [/] LINKTEXT ([!#-;|=-~|\n|äü]*{WS}*)* ALPHA [a-zA-Z][a-zA-Z0-9]*{WS}* EQ [=] QUOTES ["] ATTR {ALPHA}*{EQ}{QUOTES}{ALPHA}*{QUOTES}{WS}* HREFATTR "href="{QUOTES}{LINKTEXT}{QUOTES}{WS}* ATAGS "<a"{WS}*{ATTR}*{HREFATTR}{ATTR}*">"{LINKTEXT}"</a"[ \n\t\r]*">" %start atag %start LINK %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #define MYEOF EOF #define TOKEN_URL 257 #define TOKEN_TEXT 258 #ifndef YYSTYPE #define YYSTYPE yystype typedef char* yystype; #endif YYSTYPE yylval; %} %% {WS}* <<EOF>> return MYEOF; . {} <INITIAL>"<a"{WS}*{ATTR}*{HREFATTR}{ATTR}*> BEGIN LINK; <LINK>{LINKTEXT} {yylval=strdup(yytext);return TOKEN_TEXT;} <LINK>"</a"[ \n\t\r]*">" BEGIN INITIAL; <INITIAL>"<a" BEGIN atag; <atag>{HREFATTR} {yylval=strdup(yytext);return TOKEN_URL;} <atag>">" BEGIN INITIAL; %%
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Aufgabe 4</title> </head> <body> <h1><a name="Ueberschrift">Praktische Informatik III</a></h1> <p>Zu ignorierender text am Anfang</p> <p><a href="http://www2.informatik.hu-berlin.de/sam" name="Werbung">Lehrstuhlseiten - sollten ausgegeben werden.</a ></p> <p>Zu ignorierender Text in der Mitte</p> <p><a name="Keine URL sondern nur einfacher Anker">Dieser Text soll ignoriert werden, da der Anker keine URL enthält</a ></p> <p>Zu ignorierender Text in der Mitte</p> <p><a name="Grundwissen" href="http://www.userfriendly.org">Userfriendly - sollte jeder Informatiker kennen (und daher sollte dieser Text auch ausgegeben werden :-)</a ></p> <p>Zu ignorierender Text am Ende</p> </body> </html>
-
und daran ist jetzt genau was C?
-
@Wade1234 sagte in Lexikalische Analyse mit FLEX:
und daran ist jetzt genau was C?
die zeilen 21 bis 31
-
Das meiste ist natürlich lex-Code .
Ich dachte es könnte in die Rubrik C passen.
-
Wenn du noch eine
main
dazuliefern würdest, wäre das hilfreich.
-
Dieses C Programm ruft the lexer auf.
Diese C Datei darf nicht verändert werden.#include <stdio.h> #include <stdlib.h> #include "urlscanner.h" yystype yylval; int main(int argc, char* argv[]) { int token; if (argc != 2) yyin = stdin; else { yyin = fopen(argv[1], "r"); if (yyin == 0) { fprintf(stderr, "Fehler: Konnte Datei %s nicht zum lesen oeffnen.\n", argv[1]); exit(-1); } } while ((token = yylex()) != MYEOF) { if (token == TOKEN_URL) { printf("Line: %3d\tURL: %s\n", yylineno, yylval); } else if (token == TOKEN_TEXT) { printf("Line: %3d\tTEXT: %s\n", yylineno, yylval); } else { printf("Error\n"); } } return 0; }
-
#include <stdio.h> #include <string.h> char*s= "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">" "<html>" "<head>" "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">" "<title>Aufgabe 4</title>" "</head>" "<body>" "<h1><a name=\"Ueberschrift\">Praktische Informatik III</a></h1>" "<p>Zu ignorierender text am Anfang</p>" "" "<p><a href=\"http://www2.informatik.hu-berlin.de/sam\" name=\"Werbung\">Lehrstuhlseiten - sollten ausgegeben werden.</a" "></p>" "<p>Zu ignorierender Text in der Mitte</p>" "<p><a name=\"Keine URL sondern nur einfacher Anker\">Dieser Text soll ignoriert werden, da der Anker keine URL enthält</a ></p>" "" "<p>Zu ignorierender Text in der Mitte</p>" "<p><a name=\"Grundwissen\" href=\"http://www.userfriendly.org\">Userfriendly - sollte jeder Informatiker kennen (und daher sollte dieser Text auch ausgegeben werden :-)</a ></p>" "" "<p>Zu ignorierender Text am Ende</p>" "</body>" "</html>"; int main() { FILE *f=fmemopen(s,strlen(s),"r"); char a[1000],b[1000],c[1000],d[1000]; while( fscanf(f,"%999s",a)==1 ) if(strstr(a,"<a")==a+strlen(a)-2) if(fscanf(f,"%999[^>]>",b)==1) if(strstr(b,"href=")) if(1==sscanf(strchr(strstr(b,"href="),'\"')+1,"%[^\"]\"",c)) { if(fscanf(f,"%999[^<]<",d)==1) printf("%s\n\t%s\n",c,d); } fclose(f); return 0; }
https://onlinegdb.com/B1ViDPsZU
Feature: wenn der Tagtext leer ist, wird href auch gleich ignoriert.
-
Die Zeilen werden "ausgeführt" (du bist dir aber im klaren, dass eine flex-Spezifikation kein Programm ist?). Die Regel mit
<atag>{HREFATTR}
matcht nie, weil eina
-tag mithref
-Attribut immer auch schon von der anderen Regel aufgefangen wird.Das gesagte gilt, wenn man die offensichtliche Korrektur durchführt und die catch-all-Regel nach unten verlegt. flex warnt sonst auch, dass eine Regel nie matchen wird.
-
Hallo, danke für die Tipps.
Habe das jetzt etwas geändert und ich bekomme fast die korrekte Ausgabe.
Es soll ja nur die a-tags mit url also href=... und den Linktext dazu .
Allerdings gibt er auch die a-tags wo kein href-Attribut vorhanden ist und das soll es nicht.Habe eine zweite Umgebung hinzugefügt <LINK>.
%% {WS}* <<EOF>> return MYEOF; <INITIAL>"<a" BEGIN atag; <atag>{ATTR}* <atag>{HREFATTR} {yylval=strdup(yytext);return TOKEN_URL;} <atag>{ATTR}* <atag>">" BEGIN LINK; <LINK>{LINKTEXT} {yylval=strdup(yytext);return TOKEN_TEXT;} <LINK>"</a"[ \n\t\r]*">" BEGIN INITIAL; . {} %%
-
Hallo,
so funktioniert es nun.
Also Problem gelöst und vielen Dank für die Hilfestellung.
Grüße
%option noyywrap yylineno nounput noinput never-interactive LETTER [b-z] WS [[:space:]] SLASH [/] LINKTEXT ([!#-;|=-~|\n|äü]*{WS}*)* ALPHA [a-zA-Z][a-zA-Z0-9]*{WS}* EQ [=] QUOTES ["] ATTR {ALPHA}*{EQ}{QUOTES}{ALPHA}*{QUOTES}{WS}* HREFATTR "href="{QUOTES}{LINKTEXT}{QUOTES}{WS}* ATAGS "<a"{WS}*{ATTR}*{HREFATTR}{ATTR}*">"{LINKTEXT}"</a"[ \n\t\r]*">" %start atag %start LINK %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #define MYEOF EOF #define TOKEN_URL 257 #define TOKEN_TEXT 258 #ifndef YYSTYPE #define YYSTYPE yystype typedef char* yystype; #endif YYSTYPE yylval; bool is_href; %} %% <<EOF>> return MYEOF; <INITIAL>"<a" BEGIN atag; <atag>{HREFATTR} {is_href = true;yylval=strdup(yytext);return TOKEN_URL;} <atag>">" BEGIN LINK; <LINK>{LINKTEXT} {if(is_href){yylval=strdup(yytext);return TOKEN_TEXT;}} <LINK>"</a"[ \n\t\r]*">" {is_href = false;BEGIN INITIAL;} {WS}* . {} %%