2009-12-01 25 views
16

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

मैंने व्याकरण अपलोड किया है जिसे मैं पढ़ने के लिए here से अनुवाद कर रहा हूं।

संपादित करें: पॉल से सलाह के साथ अपडेट किया गया।

यह व्याकरण मैं वर्तमान में मिल गया है है (सिंटेक्स परिभाषा के दो शीर्ष लाइनों मुझे बहुत बुरा मैं जानता हूँ कि कर रहे हैं):

# Lexical structure definition 
ifS = Keyword('if') 
elseS = Keyword('else') 
whileS = Keyword('while') 
returnS = Keyword('return') 
intVar = Keyword('int') 
voidKeyword = Keyword('void') 
sumdiff = Literal('+') | Literal('-') 
prodquot = Literal('*') | Literal('/') 
relation = Literal('<=') | Literal('<') | Literal('==') | \ 
      Literal('!=') | Literal('>') | Literal('=>') 
lbrace = Literal('{') 
rbrace = Literal('}') 
lparn = Literal('(') 
rparn = Literal(')') 
semi = Literal(';') 
comma = Literal(',') 
number = Word(nums) 
identifier = Word(alphas, alphanums) 

# Syntax definition 
term = '' 
statement = '' 
variable = intVar + identifier + semi 
locals  = ZeroOrMore(variable) 
expr  = term | OneOrMore(Group(sumdiff + term)) 
args  = ZeroOrMore(OneOrMore(Group(expr + comma)) | expr) 
funccall = Group(identifier + lparn + args + rparn) 
factor  = Group(lparn + expr + rparn) | identifier | funccall | number 
term  = factor | OneOrMore(prodquot + factor) 
cond  = Group(lparn + expr + relation + expr + rparn) 
returnState = Group(returnS + semi) | Combine(returnS + expr + semi) 
assignment = Group(identifier + '=' + expr + semi) 
proccall = Group(identifier + lparn + args + rparn + semi) 
block  = Group(lbrace + locals + statement + rbrace) 
iteration = Group(whileS + cond + block) 
selection = Group(ifS + cond + block) | Group(ifS + cond + block + elseS + block) 
statement = OneOrMore(proccall | assignment | selection | iteration | returnState) 
param  = Group(intVar + identifier) 
paramlist = OneOrMore(Combine(param + comma)) | param 
params  = paramlist | voidKeyword 
procedure = Group(voidKeyword + identifier + lparn + params + rparn + block) 
function = Group(intVar + identifier + lparn + params + rparn + block) 
declaration = variable | function | procedure 
program  = OneOrMore(declaration) 

मैं चाहते हैं, तो वहाँ कोई गलती मैं कर रहे हैं पता करने के लिए मैंने व्याकरण का अनुवाद करने में क्या किया है और मुझे जो व्याकरण दिया गया है, उसका पालन करते हुए इसे सरल बनाने के लिए मैं क्या कर सकता हूं।

संपादित करें 2: नई त्रुटि को शामिल करने के लिए अपडेट किया गया।

यहाँ इनपुट स्ट्रिंग मैं पार्स करने हूं:

int larger (int first , int second) { 
if (first > second) { 
return first ; 
} else { 
return second ; 
} 
} 

void main (void) { 
int count ; 
int sum ; 
int max ; 
int x ; 

x = input () ; 
max = x ; 
sum = 0 ; 
count = 0 ; 

while (x != 0) { 
count = count + 1 ; 
sum = sum + x ; 
max = larger (max , x) ; 
x = input () ; 
} 

output (count) ; 
output (sum) ; 
output (max) ; 
} 

और यह मैं जब टर्मिनल से मेरा कार्यक्रम चलाने के त्रुटि संदेश है:

/Users/Joe/Documents/Eclipse Projects/Parser/src/pyparsing.py:1156: SyntaxWarning: null string passed to Literal; use Empty() instead 
other = Literal(other) 
/Users/Joe/Documents/Eclipse Projects/Parser/src/pyparsing.py:1258: SyntaxWarning: null string passed to Literal; use Empty() instead 
other = Literal(other) 
Expected ")" (at char 30), (line:6, col:26) 
None 
+0

क्या आपके पास हमारे लिए कोई संकेत है, जैसे कि आपको क्या त्रुटि संदेश मिल रहा है (यदि कोई है)? आप कहते हैं "यह सही ढंग से पार्स नहीं कर रहा है" लेकिन आप इसे कैसे जानते हैं? क्या कोई त्रुटि है? क्या यह गलत एएसटी उत्पन्न कर रहा है? अधिक जानकारी की आवश्यकता है। –

+0

इसके बारे में क्षमा करें। मैंने इनपुट स्ट्रिंग के साथ अपना प्रश्न अपडेट कर लिया है जिसे मैं पार्सल करने में प्रयास कर रहा हूं और टर्मिनल में त्रुटि संदेश प्राप्त कर रहा हूं। – greenie

उत्तर

31

1) Literal("if")Keyword("if") के लिए परिवर्तित करें (और तो पर, "ifactor" नामक चर के अग्रणी "अगर" से मेल खाने से रोकने के लिए।

2) nums, alphas, और alphanums भाव वे तार, कि वर्ड वर्ग के साथ इस्तेमाल किया जा सकता पात्रों में से कुछ विशिष्ट सेट को परिभाषित करने के लिए कर रहे हैं नहीं कर रहे हैं, जब की तरह "" शब्द "को परिभाषित करने के लिए एक नंबर एक शब्द से बना है nums ", या" एक पहचानकर्ता एक शब्द है जो अल्फा से शुरू होता है, उसके बाद शून्य या अधिक अल्फानम होते हैं। " तो बजाय:

number = nums 
identifier = alphas + OneOrMore(alphanums) 

आप

number = Word(nums) 
identifier = Word(alphas, alphanums) 

3 चाहते हैं) के बजाय Combine, मुझे लगता है कि आप Group चाहते हैं। Combine का उपयोग करें जब आप मिलान किए गए टोकन को किसी भी हस्तक्षेप वाले व्हाइटस्पेस के साथ संगत नहीं करना चाहते हैं, और टोकन को संयोजित करेंगे और उन्हें एक स्ट्रिंग के रूप में वापस कर देंगे। Combine अक्सर इस तरह के मामलों में किया जाता है:

realnum = Combine(Word(nums) + "." + Word(nums)) 

बिना Combine, "3.14" को पार्स तार ['3', '.', '14'] की सूची वापसी होगी, तो हम Combine जोड़ सकते हैं ताकि realnum के लिए पार्स परिणाम '3.14' है (जिसे फिर आप को दे सकते हैं वास्तविक फ़्लोटिंग मान 3.14 में कनवर्ट करने के लिए पार्स एक्शन)। Combine कोई हस्तक्षेप करने वाली व्हाइटस्पेस के प्रवर्तन को हमें 'The answer is 3. 10 is too much.' पर गलती से पार्सिंग से रोकता है और "3. 10" वास्तविक संख्या का प्रतिनिधित्व करता है।

4) इससे आपकी त्रुटि नहीं होनी चाहिए, लेकिन आपकी इनपुट स्ट्रिंग में अतिरिक्त अतिरिक्त रिक्त स्थान हैं। यदि आपको अपना व्याकरण काम मिल रहा है, तो आपको के साथ-साथ "int x ;" को पार्स करने में सक्षम होना चाहिए।

आशा है कि इनमें से कुछ संकेत आपको जा रहे हैं। क्या आपने कोई ऑनलाइन पिपर्सिंग लेख या ट्यूटोरियल पढ़ा है? और कृपया ऑनलाइन उदाहरण देखें। आपको Word, Literal, Combine इत्यादि के बारे में अच्छी समझ प्राप्त करने की आवश्यकता होगी, आदि। अपने व्यक्तिगत पार्सिंग कार्यों को निष्पादित करें।

5) आपने शब्द और कथन के लिए रिकर्सिव परिभाषाओं को गलत तरीके से कार्यान्वित किया है। उन्हें '' बताए करने के बजाय, लिखें:

term = Forward() 
statement = Forward() 

फिर जब आप वास्तव में उनके पुनरावर्ती परिभाषा के साथ उन्हें परिभाषित करने << ऑपरेटर का उपयोग जाना (और () के में आरएचएस संलग्न करना सुनिश्चित करें)।

term << (... term definition ...) 
statement << (... statement definition ...) 

आप एक पुनरावर्ती पार्सर here, और बुनियादी pyparsing उपयोग here पर एक प्रस्तुति का एक उदाहरण मिल सकते हैं - शीर्षक अनुभाग देखें और कदम-दर-कदम कैसे प्रत्यावर्तन नियंत्रित किया जाता है पर के लिए "पार्स सूचियों"।

+0

धन्यवाद पॉल। मैंने समूह के साथ संयोजन के सभी उदाहरणों को प्रतिस्थापित कर दिया है और अब मुझे कुछ अलग-अलग त्रुटियां मिल रही हैं जो मुझे लगता है कि मेरे द्वारा उपयोग किए गए वाक्यविन्यास के बजाय मेरे नियम कैसे लिखे गए हैं। मैंने आपके मूल पोस्ट को आपके द्वारा सुझाए गए परिवर्तनों और मेरे पास नई त्रुटि को दर्शाने के लिए अपडेट किया है। – greenie

+0

उत्कृष्ट पॉल, बहुत बहुत धन्यवाद। काश मैं आपको और अधिक +1 कर सकता हूँ :) – greenie

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