lisp meaning यैक्स में लिस्प व्याकरण




lisp meaning (6)

मैं एक लिस्प व्याकरण का निर्माण करने की कोशिश कर रहा हूं आसान, सही? जाहिरा तौर पर नहीं।

मैं इन इनपुटों को प्रस्तुत करता हूं और त्रुटियों को प्राप्त करता हूं ...

( 1 1)
23 23 23 
ui ui

यह व्याकरण है ...

%%
sexpr: atom                 {printf("matched sexpr\n");}
    | list
    ;
list: '(' members ')'       {printf("matched list\n");}
    | '('')'                {printf("matched empty list\n");}
    ;
members: sexpr              {printf("members 1\n");}
    | sexpr members         {printf("members 2\n");}
    ;
atom: ID                    {printf("ID\n");}
    | NUM                   {printf("NUM\n");}
    | STR                   {printf("STR\n");}
    ;
%%

जितना मैं बता सकता हूं, मुझे एक प्रोग्राम के रूप में परिभाषित एक गैर-टर्मिनल की आवश्यकता है, जिस पर पूरे पार्स ट्री लटका सकते हैं। लेकिन मैंने कोशिश की और यह काम करने के लिए प्रतीत नहीं हुआ।

संपादित करें - यह मेरा "शीर्ष टर्मिनल" दृष्टिकोण था:

program: slist;

slist: slist sexpr | sexpr;

लेकिन इससे समस्याओं की अनुमति मिलती है जैसे:

( 1 1 

संपादन 2: फ्लेक्स कोड है ...

%{
    #include <stdio.h>
    #include "a.yacc.tab.h"
    int linenumber;
    extern int yylval;
%}
%%
\n                         { linenumber++; }
[0-9]+                     { yylval = atoi(yytext); return NUM; }
\"[^\"\n]*\"               { return STR; }
[a-zA-Z][a-zA-Z0-9]*       { return ID; }
.
%%

ओवर-मिलानिंग का एक उदाहरण ...

(1 1 1)
NUM
matched sexpr
NUM
matched sexpr
NUM
matched sexpr
(1 1
NUM
matched sexpr
NUM
matched sexpr

यहां त्रुटि क्या है?

संपादित करें: त्रुटि lexer में थी।



जब से मैंने YACC के साथ काम किया, तब से यह बहुत समय हो गया है, लेकिन आपको शीर्ष स्तर के गैर-टर्मिनल की आवश्यकता है। क्या आप "इसे करने की कोशिश" और "यह काम करने के लिए प्रतीत नहीं" के बारे में अधिक विशिष्ट हो सकता है? या, उस बात के लिए, क्या त्रुटियां हैं?

मुझे यह भी संदेह था कि ऐसी वाक्यविन्यास-प्रकाश भाषा के लिए YACC ओवरकिल हो सकता है कुछ सरल (पुनरावर्ती वंश जैसे) बेहतर काम कर सकता है


आप सही हैं जिसमें आपको गैर-टर्मिनल को परिभाषित करने की आवश्यकता है यह sexpr का एक समूह के रूप में परिभाषित किया जाएगा मुझे इसके लिए YACC वाक्यविन्यास के बारे में निश्चित नहीं है मैं पार्टर जनरेटर के लिए एएनटीएलआर से आंशिक हूँ और वाक्यविन्यास होगा:

program: sexpr*

0 या अधिक sexpr का संकेत

YACC वाक्यविन्यास के साथ अद्यतन:

program :  /* empty */
        | program sexpr
        ;

YACC में नहीं, लेकिन वैसे भी उपयोगी हो सकता है, एएनटीएलआर v3 में एक पूर्ण व्याकरण है जो आपके द्वारा वर्णित मामलों के लिए काम करता है (लेक्जर में स्ट्रिंग्स को शामिल नहीं करता है क्योंकि यह इस उदाहरण के लिए महत्वपूर्ण नहीं है, यह भी सी # कंसोल आउटपुट का उपयोग करता है क्योंकि यही मैंने इसके साथ परीक्षण किया है ):

program: (sexpr)*;

sexpr: list
    |  atom            {Console.WriteLine("matched sexpr");}
    ;

list:     
   '('')'              {Console.WriteLine("matched empty list");}
   | '(' members ')'   {Console.WriteLine("matched list");}

    ;

members: (sexpr)+      {Console.WriteLine("members 1");};

atom: Id               {Console.WriteLine("ID");}
    | Num              {Console.WriteLine("NUM");}
    ;


Num: ( '0' .. '9')+;
Id: ('a' .. 'z' | 'A' .. 'Z')+;
Whitespace : ( ' ' | '\r' '\n' | '\n' | '\t' ) {Skip();};

यह ठीक तरह से काम नहीं करेगा जैसा कि YACC में है क्योंकि YACC जनरेट करता है और एलएलआर पार्सर होता है जबकि एएनटीएलआर एक संशोधित पुनरावर्ती वंश है। एटीएलआर के लिए एक सी / सी + आउटपुट लक्ष्य है यदि आप उस रास्ते जाना चाहते थे।


लिस्प व्याकरण संदर्भ-मुक्त व्याकरण के रूप में प्रतिनिधित्व नहीं किया जा सकता है, और yacc सभी लिस्पी कोड को पार्स नहीं कर सकता। यह पढ़ा-मूल्यांकन और प्रोग्रामयोग्य रीडर जैसी स्पष्ट सुविधाओं की वजह से है इसलिए, एक मनमाने ढंग से लिस्पी कोड पढ़ने के लिए, आपको एक पूर्ण लिज़प चलाना होगा। यह कुछ अस्पष्ट, गैर-उपयोग की जाने वाली सुविधा नहीं है, लेकिन यह वास्तव में प्रयोग किया जाता है। उदाहरण, सीएल-इंटरपोल, सीएल-एसक्यूएल

अगर लक्ष्य को लिप के उपसंच को पार्स करना है, तो प्रोग्राम टेक्स्ट sexprs का क्रम है


मैंने अभी कोशिश की, मेरी "वाईएपी लिपपी व्याकरण" ठीक काम करता है:

%start exprs

exprs:
    | exprs expr
    /// if you prefer right recursion :
    /// | expr exprs
    ;

list:
    '(' exprs ')'
    ;

expr:
    atom
    | list
    ;

atom:
    IDENTIFIER
    | CONSTANT
    | NIL
    | '+'
    | '-'
    | '*'
    | '^'
    | '/'
    ;

क्या आपको अनिश्चित रूप से एक yacc / bison पार्सर की आवश्यकता है? ए "लिप सिंटैक्स का एक सबसेट पढ़ता है" पाठक सी में लागू करने में कठिनाई नहीं है (read_sexpr फ़ंक्शन के साथ शुरू करें, read_list में प्रेषण करें जब आप '(', '' देख '' देखेंगे जो कि एक ' ) 'देखा जाता है; अन्यथा, एक पठन_टॉम को कॉल करें जो एक परमाणु एकत्र करता है और यह तब देता है जब यह परमाणु-घटक वर्ण नहीं पढ़ सकता)।

हालांकि, यदि आप आर्ब्रिटरी कॉमन लिस्प को पढ़ने में सक्षम होना चाहते हैं, तो आपको (सबसे खराब) एक सामान्य लिस्प को लागू करने की आवश्यकता होगी, चूंकि सीएल रीडर रन-टाइम को संशोधित कर सकता है (और यहां तक ​​कि विभिन्न रीड-टेबल रन-टाइम प्रोग्राम नियंत्रण के तहत; जब आप किसी अन्य भाषा में लिखे गए कोड को लोड करना चाहते हों या लिप के बोली) तो बहुत आसान है।