मैं फ्लेक्स में बहुत लंबे पैटर्न को परिभाषित कर रहा हूं, कई या मामलों के साथ। मैं सोच रहा था कि क्या कोड पठनीयता में सुधार के लिए कई लाइनों पर परिभाषा लिखने का एक तरीका है। कुछ इस तरह
%option noyywrap
1 %{
...
14 %}
15
16 DIGIT [0-9]
17 ID [a-z][a-z0-9]*
18 LOOP_KWD for|while|
19 his|her //THIS IS WHAT I WOULD LIKE
20 SELECT_KWD if|else
21 STRING ".*"
22 COMP_OP <|>|==]
29
30 %%
31
32 {DIGIT}+ {
33 printf("INT_NUM<%s>", yytext);
34 }
35
36 {include} {
37 printf("PREPROCESSOR_INCLUDE");
38 }
39 {LOOP_KWD} {
40 printf("LOOP_KWD<%s>", yytext);
41 }
42 {SELECT_KWD} {
43 printf("SELECT_KWD<%s>", yytext);
44 }
जब मैं इसे चलाने की कोशिश करता हूं तो यह देता है:
flex -o tokenize.c my_first_token.l
my_first_token.l:40: unrecognised rule
make: *** [all] Error 1
उत्तर:
जवाब के लिए 0 № 1वास्तविक समस्या 18-19 की तर्ज पर LOOP_KWD की बहुस्तरीय परिभाषा है, और सरल उत्तर यह है कि आप ऐसा नहीं कर सकते हैं।
अधिक जटिल उत्तर यह है कि प्रत्येक कीवर्डका अपना नियम होना चाहिए। नहीं तो पार्सर "t काम कर सकता है। इसलिए आपको" नहीं करना चाहिए। या फिर सभी नियमों के साथ कीवर्ड को पहचानने में परेशान न करें, और IDENTIFIER नियम में केवल लुकअप टेबल का उपयोग करें।
जवाब के लिए 0 № 2
lex
तथा flex
पैटर्न परिभाषाओं में निरंतरता लाइनों को स्वीकार नहीं करते, लेकिन नियम अनुभाग में लाइन-ब्रेक की अनुमति देते हैं। आप उस नियम को कुछ इस तरह बदल सकते हैं
for|
while|
his|
her {
printf("LOOP_KWD<%s>", yytext);
}
हालाँकि मुझे लुकिंग टेबल का उपयोग करना बेहतर लगता है, केवल लेक्सर का संबंध सिंटैक्स से है। आपके लिए एक पैटर्न है {ID}
जिसका उपयोग किया जा सकता है, उदा।
{ID} {
int n;
for (n = 0; table[n] != 0; ++n) {
if (!strcmp(yytext, table[n])) {
printf("keyword<%s>", yytext);
break;
}
}
}
और तालिका (पाठ्यक्रम के कोड-अनुभाग में):
const char *table[] = { "for", "while", "his", "her", 0 };
पैटर्न का उपयोग करना {ID}
सुस्पष्ट खोजशब्दों के बजाय सहज मैचों की समस्या को हल करता है, जैसे, "यह" मिलान "उसका", "आगे" मिलान "के लिए", आदि।