2014-01-24 99 views
0

我想解析f(arg).methodf(arg)block_statement;第一個比第二個更重要。解析兩種語句,優先級爲

parser.mly下列元素無法解析f(arg),但可以解析f(arg).method如下:

(* f(arg).method *) 
    BS_MAE MAE_LE_UN (
    LE_IE IE_LE_AL (
     LE_SNE SNE_I f, 
     AL_I arg), 
    UN_I method) 

(* parser.mly:*)

block_statement: 
| member_access_expression { BS_MAE $1 } 

simple_name_expression: | IDENTIFIER { SNE_I $1 } 
member_access_expression: | l_expression DOT unrestricted_name { MAE_LE_UN ($1, $3) } 
unrestricted_name: | IDENTIFIER { UN_I $1 } 
index_expression: | l_expression LPAREN argument_list RPAREN { IE_LE_AL ($1, $3) } 
expression: | l_expression { E_LE $1 } 

l_expression: 
| simple_name_expression { LE_SNE $1 } 
| index_expression { LE_IE $1 } 

call_statement: 
| simple_name_expression argument_list { CallS_SNE_AL ($1, $2) } 
| member_access_expression argument_list { CallS_MAE_AL ($1, $2) } 

argument_list: | IDENTIFIER { AL_I $1 } 

但是,如果我們添加另一條線| IDENTIFIER LPAREN expression RPAREN { BS_I_E ($1, $3) }block_statement,這次它可以解析f(arg)如下:

BS_I_E (
    f, 
    E_LE LE_SNE SNE_I arg) 

但是,這一次,f(arg).method不能再被解析。它在閱讀後引發錯誤.

我不知道如何讓解析器進一步閱讀f(arg).method作爲一個整體,如果可能的話;我真的需要解析器來解析這兩個語句......任何人都可以幫忙嗎?

回答

1

我會嘗試文法與沿着線的結構:

block: 
| expr 

expr: 
| expr LPAREN argument_list RPAREN 
| expr DOT unrestricted_name 
| simple_expr 

simple_expr: 
| IDENTIFIER 

注意,如果要分析一個完整的句子,而不是隻輸入一個有效的前綴,你的頂層規則應該要求EOF標記將存在(強制解析器到輸入的末尾):

%start <block> main 

main: 
| b=block EOF { b } 
+0

謝謝: - )...你確定'f(arg).method'可以很好解析? '.method'必須被讀爲'DOT unrestricted_name',因此'f(arg)'必須被讀爲'member_access_expr',但它只是'call_expr'的另一個包含括號的分支... – SoftTimur

+0

事實上,我開始用解析你的例子的東西,做出了改變,結果語法錯了。我將其更新爲混合兩個級別以允許解析。請注意,你必須有一個頂層解析規則,直到EOF(否則你可能會得到一個有效解析的輸入前綴),並且'f(x).y(z)'將被解析爲'( f(x).y)(z)',因爲我認爲它應該是。 – gasche

+0

請您詳細說明一下,您必須有一個頂層解析規則,可以達到EOF(否則您可能會得到一個有效解析輸入的前綴)?另外,我也沒有在你的語法中看到'EOF'......我想這是解決我的問題的關鍵:根據我的語法'f(arg).method'不能被解析,因爲'f(arg )'作爲前綴是一個有效的解析... – SoftTimur