كيفية القيام تبديل متغير مع فليكس / ليكس وياك / بيسون

StackOverflow https://stackoverflow.com/questions/1440147

سؤال

ويكيبيديا الاستيفاء تعريف أنا مجرد التعلم المرن / البيسون وأنا أكتب بلدي شل الخاصة به. أحاول أن يجدوا طريقة جيدة للقيام الاستيفاء متغير. كان توجهي الأولي لهذا أن يكون المسح المرنة لشيء من هذا القبيل ~ لبلدي الدليل الرئيسي، أو $ myVar، ثم قم بتعيين ما yyval.stringto ما عاد باستخدام وظيفة البحث عنها. مشكلتي هي أن هذا لا يساعدني عندما يظهر النص رمز واحد:

kbsh:/home/kbrandt% echo ~
/home/kbrandt
kbsh:/home/kbrandt% echo ~/foo
/home/kbrandt /foo
kbsh:/home/kbrandt%

وتعريف يكس لدي للمتغيرات:

\$[a-zA-Z/0-9_]+    {
    yylval.string=return_value(&variables, (yytext + sizeof(char)));;
    return(WORD);
}

وبعد ذلك في بلدي قواعد اللغة، ولدي أشياء مثل:

chdir_command:
    CD WORD { change_dir($2); }
    ;

أحد يعرف من وسيلة جيدة للتعامل مع هذا النوع من الاشياء؟ أنا ذاهب عن هذا كله غير صحيح؟

هل كانت مفيدة؟

المحلول

والطريقة قذائف "التقليدية" تتعامل مع أشياء مثل استبدال متغير من الصعب التعامل مع يكس / ياك. ما يفعلونه هو أشبه التوسع الكلي، حيث بعد توسيع متغير، وثم إعادة tokenize المدخلات، دون توسيع المزيد من المتغيرات. هكذا على سبيل المثال، مدخلا مثل "س س $ {$ فو}" حيث يتم تعريف "فو" على أنه "بار" و "بار" هو الذي يعرف بأنه '$ ذ' سوف تتوسع ل"×× $ ذ 'التي سيتم التعامل معها على أنها (لن يتم توسيعها و$ ص) كلمة واحدة.

ويمكنك التعامل مع هذا في العطف، ولكن تحتاج إلى الكثير من الدعم التعليمات البرمجية. تحتاج إلى استخدام الاشياء yy_buffer_state المرن لإعادة توجيه بعض الأحيان الإخراج إلى منطقة عازلة أن عليك ثم إعادة تفحص من، واستخدام تبدأ الدول بعناية للسيطرة عندما المتغيرات يمكن ولا يمكن توسيعها.

ه على الأرجح أسهل لاستخدام lexer بسيط جدا وترجع الرموز مثل ALPHA (واحد أو أكثر من حروف الأبجدية)، NUMERIC (واحد أو أكثر من أرقام)، أو بيضاء (مسافة واحدة أو أكثر أو علامة التبويب)، ويكون محلل تجميع لهم على نحو ملائم، وينتهي بك الأمر مع قواعد مثل:

simple_command: wordlist NEWLINE ;

wordlist: word | wordlist WHITESPACE word ;

word: word_frag
    | word word_frag { $$ = concat_string($1, $2); }
;

word_frag: single_quote_string
         | double_quote_string
         | variable
         | ALPHA
         | NUMERIC
        ...more options...
;

variable: '$' name { $$ = lookup($2); }
        | '$' '{' word '}' { $$ = lookup($3); }
        | '$' '{' word ':' ....

وكما ترون، هذا يحصل معقدة سريعة جدا.

نصائح أخرى

يبدو OK عموما


ولست متأكدا ما return_value يقوم به، واتمنى ان strdup(3) اسم المتغير، لأن yytext هو مجرد العازلة.

إذا كنت تسأل عن تقسيم العمل بين الدعوى وتحليل، وأنا متأكد انها تماما معقول لدفع تجهيز الكلي واستبدال المعلمة إلى الماسح الضوئي ويكون مجرد صفقة قواعد اللغة الخاصة بك مع WORDs، والقوائم، أوامر، وخطوط الأنابيب، إعادة توجيه، وما بعد كل شيء، فإنه سيكون معقولا بما فيه الكفاية، وإن كان ذلك نوع من الخروج من نمط وربما هزيمة نقطة من التمرين، على أن تفعل كل شيء مع التعليمات البرمجية.

وأعتقد أن جعل cd أو chdir رمزا محطة واستخدام ذلك في إنتاج قواعد اللغة هو ... ليس أفضل قرار تصميم. مجرد أمر هو في المدمج لا يعني أنه يجب أن تظهر كقاعدة عامة. والمضي قدما في تحليل cd وchdir مثل أي أمر آخر. التحقق من وجود دلالات المدمج في كإجراء من إجراءات، وليس الإنتاج.

وبعد كل شيء، ما اذا كان تعريف كإجراء قذيفة؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top