2011-06-08 13 views
14

मेरा प्रश्न: अनावश्यक ब्रांड्स के बिना अभिव्यक्ति को सुंदर प्रिंट करने का सबसे साफ तरीका क्या है?सुंदर प्रिंट अभिव्यक्ति के रूप में संभव के रूप में कुछ कोष्ठक के साथ?


मैं लैम्ब्डा अभिव्यक्ति के निम्नलिखित प्रतिनिधित्व:

Term ::= Fun(String x, Term t) 
     | App(Term t1, Term t2) 
     | Var(String x) 

सम्मेलन App द्वारा छोड़ा साहचर्य है, कि, a b c(a b) c के रूप में व्याख्या की है और समारोह निकायों संभव के रूप में सही करने के लिए जहाँ तक खिंचाव है कि है, λ x. x y को λ x. (x y) के रूप में व्याख्या किया गया है।

मेरे पास एक पार्सर है जो एक अच्छी नौकरी करता है, लेकिन अब मुझे एक सुंदर प्रिंटर चाहिए।

term match { 
    case Fun(v, t) => "(λ %s.%s)".format(v, prettyPrint(t)) 
    case App(s, t) => "(%s %s)".format(prettyPrint(s), prettyPrint(t)) 
    case Var(v) => v 
} 

ऊपर प्रिंटर हमेशा कहते () भाव के आसपास (परमाणु चर के लिए छोड़कर): यहाँ क्या मैं वर्तमान में (छद्म स्केला) पड़ता है। इस प्रकार Fun(x, App(Fun(y, x), y)) के लिए यह

(λ x.((λ y.x) y)) 

यह नहीं पैदा करता है मैं

λ x.(λ y.x) y 
+4

मुझे पता है कि एकमात्र संदर्भ है नॉर्मन रैमसे का "उपसर्ग और पोस्ट ऑपरेटर के साथ अनस्पर्शिंग अभिव्यक्तियां"। यदि आप मानक एमएल के बारे में जानते हैं तो आपको धारा 4 में कोड को अनुकूलित करने में सक्षम होना चाहिए। http://www.cs.tufts.edu/~nr/pubs/unparse-abstract.html –

+0

क्या यह भाषा अज्ञेयवादी है या आप स्कैला उत्तर की तलाश में हैं? किसी भी तरह से, आप व्यापक दर्शक प्राप्त करने के लिए प्रश्न को टैग करना चाहते हैं। – neontapir

उत्तर

2

करना चाहते हैं है तुम सिर्फ अनुप्रयोग के तर्कों के प्रकार की जाँच करने के लिए है कि?

मैं .. यकीन है कि कैसे स्केला में यह लिखने के लिए नहीं कर रहा हूँ

term match { 
    case Fun(v: String, t: Term) => "λ %s.%s".format(v, prettyPrint(t)) 
    case App(s: Fun, t: App) => "(%s) (%s)".format(prettyPrint(s), prettyPrint(t)) 
    case App(s: Term, t: App) => "%s (%s)".format(prettyPrint(s), prettyPrint(t)) 
    case App(s: Fun, t: Term) => "(%s) %s".format(prettyPrint(s), prettyPrint(t)) 
    case App(s: Term, t: Term) => "%s %s".format(prettyPrint(s), prettyPrint(t)) 
    case Var(v: String)   => v 
} 
3

यहाँ मैं संबद्धता और पूर्वता निम्नलिखित व्याकरण जिसका ऑपरेटरों में सूचीबद्ध हैं द्वारा परिभाषित के साथ इन्फ़िक्स भाव के लिए एक सरल व्याकरण का उपयोग करेंगे पूर्वता

E -> E + T | E - T | T  left associative 
T -> T * F | T/F | F  left associative 
F -> G^F | G    right associative 
G -> - G | (E) | NUM 

के आरोही क्रम एक सार वाक्य रचना पेड़ को देखते हुए (एएसटी) हम केवल आवश्यक कोष्ठक नीचे स्यूडोकोड में वर्णित के रूप के साथ एक स्ट्रिंग के लिए एएसटी परिवर्तित। हम रिश्तेदार प्राथमिकता और सहयोगीता की जांच करते हैं क्योंकि हम पेड़ को फिर से उतरते हैं ताकि यह निर्धारित किया जा सके कि ब्रांडेस आवश्यक हैं। ध्यान दें कि अभिव्यक्ति के चारों ओर कोष्ठक लपेटने के सभी निर्णय माता-पिता नोड में होना चाहिए।

toParenString(AST) { 
    if (AST.type == NUM) // simple atomic type (no operator) 
     return toString(AST) 
    else if (AST.TYPE == UNARY_MINUS) // prefix unary operator 
     if (AST.arg.type != NUM AND 
      precedence(AST.op) > precedence(AST.arg.op)) 
       return "-(" + toParenString(AST.arg) + ")" 
     else 
       return "-" + toParenString(AST.arg) 
    else { // binary operation 
     var useLeftParen = 
      AST.leftarg.type != NUM AND 
      (precedence(AST.op) > precedence(AST.leftarg.op) OR 
       (precedence(AST.op) == precedence(AST.leftarg.op) AND 
       isRightAssociative(AST.op))) 

     var useRightParen = 
      AST.rightarg.type != NUM AND 
      (precedence(AST.op) > precedence(AST.rightarg.op) OR 
       (precedence(AST.op) == precedence(AST.rightarg.op) AND 
       isLeftAssociative(AST.op))) 

     var leftString; 
     if (useLeftParen) { 
      leftString = "(" + toParenString(AST.leftarg) + ")" 
     else 
      leftString = toParenString(AST.leftarg) 

     var rightString; 
     if (useRightParen) { 
      rightString = "(" + toParenString(AST.rightarg) + ")" 
     else 
      rightString = toParenString(AST.rightarg) 

     return leftString + AST.op + rightString; 
    } 
    } 
संबंधित मुद्दे