2016-11-19 43 views
0

我有我的分配me.We教授給出了以下移進/歸約conlfict以及如何解決

Goal 
    ::= (Function|Statement)* <EOF> 
Function 
    ::= "def" Identifier "(" Argument? ")" ":" Statement 
Argument 
    ::= Identifier ("=" Value)? ("," Identifier ("=" Value)?)* 
Statement 
    ::= tab* "if" Comparison ":" Statement 
    |tab* "while" Comparison ":" Statement 
    |tab* "for" Identifier "in" Identifier ":" Statement 
    |tab* "return" Expression 
    |tab* "print" Expression ("," Expression)* 
    |tab* Identifier ("=" | "-=" | "/=") Expression 
    |tab* Identifier "[" Expression "]" "=" Expression 
    |tab* Function Call 
Expression 
    ::= Expression ("+" | "-" | "*" | "/") Expression 
    | ("++" | "--") Expression 
    | Expression("++" | "--") 
    | Identifier "[" Expression "]" 
    | Function Call 
    | Value 
    | Identifier 
    | "(" Expression ")" 
    | "["Value ("," Value)*"]" 
Comparison 
    ::= Expression (">" | "<" | "!=" | "==") Expression 
    | "true" 
    | "false" 
Function Call 
    ::= Identifier "(" Arglist? ")" 
Arglist 
    ::= Expression ("," Expression)* 
Value 
    ::= Number | "<STRING_LITERAL>"|'<STRING_LITERAL>' 
Number 
    ::= <INTEGER_LITERAL> 
Identifier 
    ::= <IDENTIFIER> 

<STRING_LITERAL> = A word that can contain letter(capitals or non capital) and white spaces 
<INTEGER_LITERAL> = An integer number 
<IDENTIFIER> = Name of a variable 

一個項目的問題,我們必須實現與詞法和語法分析語法文件。我已經實現了大部分的線路,但我有問題,實施其餘的,因爲我得到一個轉變/減少conflict.My代碼是這樣

Helpers 
    digit = ['0' .. '9']; 
    letter = ['a' .. 'z']|['A' .. 'Z']; 
    cr = 13; 
    lf = 10; 
    all = [0..127]; 
    eol = lf | cr | cr lf ; 
    not_eol = [all - [cr + lf]]; 

Tokens 
    tab = 9; 
    plus = '+'; 
    dplus = '++'; 
    minus = '-'; 
    dminus = '--'; 
    mult = '*'; 
    div = '/'; 
    eq = '='; 
    minus_eq = '-='; 
    div_eq = '/='; 
    exclam = '!'; 
    l_br = '['; 
    r_br = ']'; 
    l_par = '('; 
    r_par = ')'; 
    comma=','; 
    def = 'def'; 
    if = 'if'; 
    elif = 'elif'; 
    else = 'else'; 
    for = 'for'; 
    in = 'in'; 
    while = 'while'; 
    print = 'print'; 
    return = 'return'; 
    less = '<'; 
    great = '>'; 
    not_eq = '!='; 
    log_eq = '=='; 
    true = 'true'; 
    semi = ':'; 
    false = 'false';  
    quote = '"'; 
    blank = (' ' | lf | cr); 
    line_comment = '#' not_eol* eol; 
    number = digit+; 
    id = letter (letter | digit)*; 
    string = ('"'not_eol* '"' | ''' not_eol* '''); 

Ignored Tokens 
    blank, line_comment; 
    Productions 
    programme = commands*; 

    commands ={stat} statement| 
       {expr}expression; 

    function = {function} def id l_par argument? r_par semi statement; 

    argument = {argument} id arg1? arg2*; 

    arg1 = {arg1} eq value; 

    arg2 = {arg2} comma id arg1?; 

    statement = {if}tab* if comparison semi statement | 
       {while}tab* while comparison semi statement | 
       {for}tab* for [id1]:id in [id2]:id semi statement | 
       {return}tab* return expression| 
       {print}tab* print expression | 
       {assign}tab* id eq expression | 
       {reduce_by}tab* id minus_eq expression | 
       {divide_by}tab* id div_eq expression | 
       {array_element_assing}tab* id l_br [ex2]:expression r_br eq [ex32]:expression; 



    comparison = {true} true| 
        {false} false| 
        {lessc} [lpar]:expression less [rpar]:expression| 
        {greatc}[lpar]:expression great [rpar]:expression| 
        {equal} [lpar]:expression log_eq [rpar]:expression| 
        {not_equal} [lpar]:expression not_eq [rpar]:expression; 

    expression = {multiplication} multiplication |    
        {addition} expression plus multiplication | 
        {subtraction} expression minus multiplication | 
        {array}id l_br expression r_br; 






    multiplication = {something} something | 
          {multiplication} multiplication mult something | 
          {division} multiplication div something | 
          {postfix} suffix; 

    suffix = {dplus} dplus something | 
       {dminus} dminus something ; 




    value = {number} number | 
      {string} string; 

    something ={identifier}id| 
        {numb}number| 
        {par} l_par expression r_par; 

我不能包括但移線/減少衝突是

在聲明中

|tab* Function Call 

表達

|Expression("++" | "--") 
| Function Call 
| "["Value ("," Value)*"]" 

Function Call 
    ::= Identifier "(" Arglist? ")" 
Arglist 
    ::= Expression ("," Expression)* 

我貼只生產部分,而不是一切,因爲問題的關鍵在於.......我會喜歡一些幫助線關於如何在我的語法中添加這些行而沒有轉換/減少衝突。我正在嘗試解決這個問題,現在看起來我嘗試了一切。感謝您的幫助dvance。

回答

1

您的文法允許expressioncommand(您可以將其混淆地稱爲commands)。你給的語法不是。

由於沒有命令分隔符,因此您的語法允許連續表達式。但是,這是不明確的。是a+b單個表達式,還是兩個表達式a+b?那麼a(b)?函數調用,或表達式a後跟表達式(b)?等等。

您需要重新考慮有關命令的決定。

順便說一下,something是一個非終端可怕的名字,我覺得你很搞笑冒號(:semi;分號實際上是;,這正是我所假設的semi所指的。

+0

非常感謝!我解決了大部分問題,現在我只需要爲後綴和後綴設置優先級! –