parsing Yacc/ocamlyacc में संघर्ष को कम/कम करने का समाधान




grammar (2)

मैं ओकैलेमैस में एक व्याकरण को पार्स करने की कोशिश कर रहा हूं (बहुत ज्यादा नियमित यैक्ट के समान) जो बिना ऑपरेटरों (ओकैमल या हास्केल) के साथ फ़ंक्शन अनुप्रयोग का समर्थन करता है, और द्विआधारी और यूनरी ऑपरेटर्स की सामान्य वर्गीकरण मैं '-' ऑपरेटर के साथ संघर्ष कम / कम कर रहा हूं, जिसका उपयोग घटाव और निषेध दोनों के लिए किया जा सकता है यहां मैं व्याकरण का एक नमूना उपयोग कर रहा हूं:

%token <int> INT
%token <string> ID
%token MINUS

%start expr
%type <expr> expr

%nonassoc INT ID
%left MINUS
%left APPLY

%%

expr: INT
    { ExprInt $1 }
| ID
    { ExprId $1 }
| expr MINUS expr
    { ExprSub($1, $3) }
| MINUS expr
    { ExprNeg $2 }
| expr expr %prec APPLY
    { ExprApply($1, $2) };

समस्या यह है कि जब आप "ए - बी" जैसे अभिव्यक्ति प्राप्त करते हैं तो पार्सर यह नहीं जानता कि क्या इसे "ए (बी)" (बी का नकारा, आवेदन के बाद) या "ए - बी" के रूप में कम किया जाना चाहिए ( घटाव)। घटाव में कमी सही है मैं उस नियम के पक्ष में संघर्ष को कैसे हल करता हूं?


ठीक है, यह सबसे आसान जवाब है कि इसे अनदेखा करना और डिफ़ॉल्ट को कम करने / संकल्प को कम करने के लिए इसका संचालन करना - व्याकरण में पहले प्रकट होने वाले नियम को कम करना। इस मामले में, इसका अर्थ है कि expr MINUS expr को वरीयता में expr MINUS expr को कम करना, जो कि वास्तव में आप क्या चाहते हैं। ab देखने के बाद, आप उसे एक बायनरी घटाव के रूप में पार्स करना चाहते हैं, बजाय एक यूनिअन माइनस और फिर एक आवेदन


दुर्भाग्य से, एकमात्र उत्तर मैं व्याकरण की जटिलता में वृद्धि के साथ आ सकता हूं।

  1. split expr simple_expr और expr_with_prefix
  2. केवल simple_expr केवल simple_expr या (expr_with_prefix) अनुमति दें

पहला कदम संघर्ष को कम करने / संघर्ष को कम करने / संघर्ष को कम करने के लिए मुड़ता है, लेकिन कंस को हल करता है।

आप 'एबी सी' के साथ एक ही समस्या होने जा रहे हैं: क्या यह a(b(c)) या (a(b))(c) ? व्याकरण में आपको applied_expression और आवश्यक (applied_expression) को भी बंद करना applied_expression

मुझे लगता है कि यह ऐसा करेगा, लेकिन मुझे यकीन नहीं है:

expr := INT
      | parenthesized_expr
      | expr MINUS expr

parenthesized_expr := ( expr )
                    | ( applied_expr )
                    | ( expr_with_prefix )

applied_expr := expr expr

expr_with_prefix := MINUS expr