2012-05-04 10 views
7

मैं कुछ सरल आरटीएफ टेक्स्ट पार्सिंग करना चाहता हूं, मुझे एक जारी करने की आवश्यकता है।नियमों के साथ पेड़ प्रतिनिधित्व में स्ट्रिंग को कनवर्ट करें

{aaaaaaa\}aaaa\{aaaaa{bbbbbbbb{ccccc\{cccc}bbb{eeeee}{{gggg}ffff}bbbbbb}aaaaa} 

कहाँ:

\ means ignore next character 
{ means expand 
} means collapse up to parent 

स्ट्रिंग में किसी भी बिंदु पर राज्य बंद टैग में पात्रों के अलावा किसी भी पिछले चरित्र से प्रभावित हो सकता निम्न स्ट्रिंग को देखते हुए। उदाहरण के लिए {gggg} एफएफएफ को प्रभावित नहीं करेगा लेकिन aaaaaaaa} aaa .. bbbb, ccc, eee, ggg, fff और इससे भी प्रभावित होगा।

इस से

हम विभाजित कर सकते हैं इसके बाद के संस्करण सिर्फ सार्थक ब्लॉक

A1 = aaaaaaa\}aaaa\{aaaaa 
B1 = bbbbbbbb 
C = ccccc\{cccc 
B2 = bbb 
E = eeeee 
G = gggg 
F = ffff 
B3 = bbbbbb 
A2 = aaaaa 

पैदावार करने के लिए:

{A1{B1{C}B2{E}{{G}F}B3}A2} 

निर्भरता मैं इस्तेमाल किया वर्णन करने के लिए एक्स> Y का मतलब वाई (एक्स पर निर्भर करता है एक्स में के रूप में वाई का अर्थ बदल सकता है

A1 
A1 > B1 
A1 > B1 > C 
A1 > B1 > B2 
A1 > B1 > B2 > E 
A1 > B1 > B2 > G 
A1 > B1 > B2 > F 
A1 > B1 > B2 > B3 
A1 > B1 > B2 > A2 
A1 > A2 

तो यदि हमारे पास एक नोड है जिसमें कोई मूल्य हो सकता है और आदेश दिया जा सकता है उप मूल्यों की सूची। इस तरह की है कि मूल्य वृक्ष इस प्रकार दिखाई देगा:

A1 
- B1 
- - C 
- - B2 
- - - E 
- - - G 
- - - F 
- - - B3 
- A2 

तो अक्षर हैं जो किसी भी नोड को प्रभावित, मैंने अभी हर माता-पिता के माध्यम से रिकर्सिवली कदम कर सकते हैं पाने के लिए।

मैं पर मेरे नोड वर्ग में स्ट्रिंग पार्स करने का प्रयास कर रहा है क्या अटक रखना:

public class myNode 
{ 
    public myNode Parent; 
    public string Value; 
    public List<myNode> subNodes; 
} 

मैं, चरित्र से स्ट्रिंग चरित्र पढ़ा जब मैं एक \ मैं दो से बढ़ा देते मुठभेड़। जब मुझे { मिलता है तो मैं पिछले टेक्स्ट अनुभाग को नोड मान और बच्चे में कदम के रूप में सहेजता हूं, और जब मुझे } मिलता है तो मैं नीचे जाता हूं।

लेकिन मैं तर्क को गड़बड़ कर रहा हूं, खासकर G और A2 के लिए। पेपर पर करना आसान है, लेकिन जब मैं कदम के लिए वास्तविक तर्क करने का प्रयास करता हूं तो मैं इसे गड़बड़ कर रखता हूं।

क्या इस संरचना को बनाने के लिए कोई और आसान तरीका है? (या क्या एक बेहतर संरचना है जिसका उपयोग करना चाहिए)। मुझे लगता है कि कुछ लाइब्रेरी होनी चाहिए जो तारों के पेड़ों के रूपांतरण की अनुमति देती है लेकिन मुझे कोई भी प्रतीत नहीं होता है।

string rtf = @"{aaaaaaa\}aaaa\{aaaaa{bbbbbbbb{ccccc\{cccc}bbb{eeeee}{{gggg}ffff}bbbbbb}aaaaa}"; 

Node root = new Node { Parent = null, Value = "root", SubNodes = new List<Node>() }; 
Node node = root; 
bool escape = false; 
foreach (char c in rtf) { 
    if (escape) { 
    node.Value += c; 
    escape = false; 
    } else { 
    switch (c) { 
     case '{': 
     node = new Node { Parent = node, Value = String.Empty, SubNodes = new List<Node>() }; 
     node.Parent.SubNodes.Add(node); 
     break; 
     case '}': 
     node = new Node { Parent = node.Parent.Parent, Value = String.Empty, SubNodes = new List<Node>() }; 
     if (node.Parent != null) node.Parent.SubNodes.Add(node); 
     break; 
     case '\\': 
     escape = true; 
     break; 
     default: 
     node.Value += c; 
     break; 
    } 
    } 
} 

PrintNode(root, String.Empty); 

नोड वर्ग (सिर्फ एक छोटे से नाम बदला):

public class Node { 
    public Node Parent; 
    public string Value; 
    public List<Node> SubNodes; 
} 

लिए

+0

http://www.antlr.org/ .. यह आपकी संरचना को पार्स करने में सक्षम होना चाहिए ... इस परियोजना के लिए एक ओवरकिल हो सकता है हालांकि –

+0

यदि मैं सही हूं तो आपकी समस्या को एएसटी http द्वारा मॉडलिंग किया जा सकता है://en.wikipedia.org/wiki/Abstract_syntax_tree .. यदि ऐसा है तो आप किसी भी अस्थिर पार्सर्स/पार्सर जनरेटर का उपयोग कर सकते हैं .. मुझे विश्वास है कि वे टेबल उत्पन्न करते हैं जो तेजी से पार्सिंग के साथ मदद करते हैं ... पूरी तरह भूल गए हैं कि टेबल को क्या कहा गया था –

+0

अच्छा समस्या का विवरण। मैंने शीर्षक को संपादित करने की स्वतंत्रता ली है क्योंकि यह वास्तव में आपको आवश्यक बाइनरी पेड़ नहीं है। –

उत्तर

5

एक "राज्य मशीन" दृष्टिकोण, जहां राज्य वर्तमान नोड है, तथा भागने ध्वज का उपयोग करें प्रदर्शन:

private static void PrintNode(Node node, string level) { 
    if (node.Value.Length > 0) Console.WriteLine(level + node.Value); 
    foreach (Node n in node.SubNodes) { 
    PrintNode(n, level + " "); 
    } 
} 

आउटपुट:

root 
    aaaaaaa}aaaa{aaaaa 
    bbbbbbbb 
     ccccc{cccc 
    bbb 
     eeeee 
     gggg 
     ffff 
    bbbbbb 
    aaaaa 

ध्यान दें कि जी नोड ई नोड का बच्चा नहीं है, लेकिन एक खाली मूल्य वाला नोड का बच्चा है।

तो निश्चित रूप से आपको कुछ त्रुटि प्रबंधन भी जोड़ना होगा।

+0

धन्यवाद, यह काफी करीब है; मैं माता-पिता के आश्रित नोड्स प्राप्त करने से पहले निर्भर नोड्स प्राप्त करने के लिए 'पैरेंट। सबनोड्स' के माध्यम से पीछे की ओर लूप करता हूं। चूंकि 'बीबीबी'' bbbbbbbb' – Seph

+0

में मान पर निर्भर करता है, इसलिए मुझे बदलने की आवश्यकता एक और चीज थी 'केस' \\ ':' अभी भी आउटपुट में '\ 'अक्षर को जोड़ने की आवश्यकता है क्योंकि इन स्लैश बाद में पार्स किए गए अन्य पात्रों से बच निकले पर, अन्यथा बहुत अच्छा जवाब: डी – Seph

+0

@ सेफ: मैं देखता हूं। ऐसा नहीं है कि आम तौर पर कैसे बच निकलता है। :) – Guffa

संबंधित मुद्दे