解析两种语句,优先级

时间:2014-01-24 17:35:50

标签: parsing ocaml ocamlyacc

我想将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 个答案:

答案 0 :(得分: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 }
相关问题