2012-12-13 15 views
5

में बूलियन और अंकगणितीय अभिव्यक्ति व्याकरण अंकगणित और बुलियन अभिव्यक्तियों के लिए एक व्याकरण लिखने की कोशिश कर रहा हूं। मुझे समझ में नहीं आता कि मैं क्या गलत कर रहा हूं। मेरी व्याकरण के लिए, ANTLR का कहना है:एएनटीएलआर

[घातक] नियम logic_atom alts 1,2 से पहुंचा जा सकता पुनरावर्ती नियम आमंत्रण की वजह से गैर डालूँगा (*) निर्णय है। बाएं फैक्टरिंग या सिंटैक्टिक भविष्यवाणियों का उपयोग करके या बैकट्रैक = सही विकल्प का उपयोग करके हल करें।

लेकिन मैं बाएं फैक्टरिंग नहीं कर सकता। और मैं arith_expr को छूना नहीं चाहता, क्योंकि इसके लिए मेरे पास एक कोड है।

logic_atom : LBR logic_expr RBR | cmp_expr ;

मेरे कोड में त्रुटि:

grammar ArithmeticInterpreter; 

options { 
    output = AST; 
    language = C; 
} 
//options{greedy=true;}: 

axiom : lines EOF! ; 
lines : line (SEP! line)* ; 
line : (def_var | print_expr | scan_expr)? ; 

def_var : VARIABLE ASSIGMENT^ logic_expr ; 
print_expr : PRINT_KEYW^ arith_expr ; 
scan_expr : SCAN_KEYW^ VARIABLE ; 

arith_expr : ((PLS | MNS)^)? term ((PLS | MNS)^ term)*; 
term  : power ((MLP | DIV)^ power)*; 
power  : atom (options{greedy=true;}: PWR^ power)*; 
atom  : INT | FLOAT | VARIABLE | LBR arith_expr RBR -> ^(arith_expr); 

logic_expr : logic_atom ((OR | AND)^ logic_atom)*; 
logic_atom : LBR logic_expr RBR | cmp_expr ; 
cmp_expr: arith_expr (LSS | LSQ | GRT | GRQ | EQL | NEQ) arith_expr; 

WS : (' '| '\t'| '\r') {$channel=HIDDEN;}; 

LBR : '(' ; 
RBR : ')' ; 
PLS : '+' ; 
MNS : '-' ; 
MLP : '*' ; 
DIV : '/' ; 
PWR : '^' ; 

LSS : '<' ; 
LSQ : '<=' ; 
GRT : '>' ; 
GRQ : '>=' ; 
EQL : '==' ; 
NEQ : '!=' ; 
AND : '&&' ; 
OR : '||' ; 
NOT : '!' ; 

ASSIGMENT : '=' ; 
PRINT_KEYW : 'print' ; 
SCAN_KEYW : 'scan' ; 

SEP : '\n' | ';' ; 

INT : ('0'..'9')+; 

FLOAT : INT '.' INT* EXP? | '.' INT EXP? | INT EXP; 
fragment EXP : ('e'|'E') (PLS | MNS)? INT; 

VARIABLE : SS (SS | '0'..'9')* ; 
fragment SS : 'a'..'z' | 'A'..'Z' | '_' ; 

// (LBR arith_expr)=> काम नहीं कर रहा है। क्योंकि यह त्रुटि है कि आप हो रही है और मूल्य जोड़ने वाला नहीं obscures

logic_expr : cmp_expr ((OR | AND)^ cmp_expr)*; 
cmp_expr : (arith_expr (LSS | LSQ | GRT | GRQ | EQL | NEQ))=> arith_expr (LSS | LSQ | GRT | GRQ | EQL | NEQ)^ arith_expr 
      | LBR logic_expr RBR -> logic_expr 
      ; 

मैं नियम logic_atom हटाया:

उत्तर

3

इस के लिए अपने logic_expr और cmp_expr बदलने पर विचार करें।

cmp_expr में वाक्यात्मक विधेय का उपयोग करके आप और ANTLR बताने के लिए एक arith_expr से है कि किसी भी arith_expr एक तर्क संकेत के बाद ही पालन किया जाएगा, जिसका मतलब है कि किसी भी कोष्ठक कि मुठभेड़ों antlr अंकगणितीय अभिव्यक्ति का ही होना चाहिए कर रहे हैं एक तार्किक नहीं है।

यह सुनिश्चित करता है कि logic_expr केवल बूलियन मानों से संबंधित है और arith_expr केवल संख्यात्मक मानों से संबंधित है।


मैं संशोधित व्याकरण के साथ विभिन्न परिदृश्यों का परीक्षण किया और मैं त्रुटियों ANTLRWorks में या अपने कस्टम परीक्षण कोड में नहीं मिल रहा है। क्या आप जो देख रहे हैं उसके बारे में अधिक जानकारी पोस्ट कर सकते हैं?

यहां मेरा पूरा व्याकरण है जिसका उपयोग मैं कर रहा हूं। ध्यान दें कि मैंने language हटा दिया ताकि मैं जावा में इसका परीक्षण कर सकूं। यह ठीक होना चाहिए क्योंकि कोई कार्यवाही/अर्थशास्त्री भविष्यवाणी नहीं है। मैंने कुछ छोटे बदलाव भी किए, लेकिन मुझे उम्मीद नहीं है कि वे गंभीर सुधार करें। वे टिप्पणियों के साथ निहित हैं।

grammar ArithmeticInterpreter; 

options { 
    output = AST; 
} 
//options{greedy=true;}: 

axiom : lines EOF! ; 
lines : line (SEP! line)* ; 
line : (def_var | print_expr | scan_expr)? ; 

def_var : VARIABLE ASSIGMENT^ logic_expr ; 
print_expr : PRINT_KEYW^ arith_expr ; 
scan_expr : SCAN_KEYW^ VARIABLE ; 

arith_expr : ((PLS | MNS)^)? term ((PLS | MNS)^ term)*; 
term  : power ((MLP | DIV)^ power)*; 
power  : atom (PWR^ atom)*; //<-- changed 
atom  : INT | FLOAT | VARIABLE 
      | LBR arith_expr RBR -> arith_expr //<-- changed 
      ; 

logic_expr : cmp_expr ((OR | AND)^ cmp_expr)*; 
cmp_expr : (arith_expr (LSS | LSQ | GRT | GRQ | EQL | NEQ))=> arith_expr (LSS | LSQ | GRT | GRQ | EQL | NEQ)^ arith_expr 
      | LBR logic_expr RBR -> logic_expr 
      ; 

WS : (' '| '\t'| '\r') {$channel=HIDDEN;}; 

LBR : '(' ; 
RBR : ')' ; 
PLS : '+' ; 
MNS : '-' ; 
MLP : '*' ; 
DIV : '/' ; 
PWR : '^' ; 

LSS : '<' ; 
LSQ : '<=' ; 
GRT : '>' ; 
GRQ : '>=' ; 
EQL : '==' ; 
NEQ : '!=' ; 
AND : '&&' ; 
OR : '||' ; 
NOT : '!' ; 

ASSIGMENT : '=' ; 
PRINT_KEYW : 'print' ; 
SCAN_KEYW : 'scan' ; 

SEP : '\n' | ';' ; 

INT : ('0'..'9')+; 

FLOAT : INT '.' INT* EXP? | '.' INT EXP? | INT EXP; 
fragment EXP : ('e'|'E') (PLS | MNS)? INT; 

VARIABLE : SS (SS | '0'..'9')* ; 
fragment SS : 'a'..'z' | 'A'..'Z' | '_' ; 

को देखते हुए इनपुट x=(2<3), निम्नलिखित एएसटी पेड़ का उत्पादन किया है:

(= x (< 2 3)) 

तो जैसे renders कौन सा:

(= x (< 2 3))

संशोधित व्याकरण भी अधिक जटिल संभाल कर सकते हैं अब मामले, जैसे x = 2 + 3 < 4 || (5^5 > 30 && 3 == 10 + 2):

(= x (|| (< (+ 2 3) 4) (&& (> (^ 5 5) 30) (== 3 (+ 10 2))))) 

a more complex graph

तो ऊपर व्याकरण को कॉपी करने और है कि अगर त्रुटि मिल को ठीक करता देखकर प्रयास करें। यदि नहीं, तो मुझे जो त्रुटि दिखाई दे रही है, उसके बारे में मुझे और बताएं।

+0

मुझे भी यह कोशिश की जा रही है। इस antlrworks के लिए एक बग पेड़ खींचा। उदाहरण के लिए: 'x = (1 <2) 'ने' (... -> cmp_expr -> NoViableAltExpression) ' –

+1

@AlexanderLavrukov को चित्रित किया है, मैंने व्याकरण के साथ उत्तर अद्यतन किया है जिसका उपयोग मैंने परीक्षण के लिए किया था और कुछ उदाहरण आउटपुट। जब आपको समय मिलता है, तो यह व्याकरण स्वयं को यह देखने के लिए चलाएं कि यह आपको त्रुटियां देता है या नहीं। – user1201210

+2

@AlexanderLavrukov, सुनिश्चित करें कि परीक्षण के दौरान आप दुभाषिया का उपयोग कर ** ** ** नहीं हैं। इसके बजाय डीबगर का प्रयोग करें। –

1

मेरा त्वरित सुझाव arith और तार्किक अभिव्यक्तियों को जोड़ना है। Java.g या जो कुछ भी नमूना व्याकरण देखें। एएनटीएलआर वी 4 इस समस्या को संभाल लेगा, बीटीडब्ल्यू।

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