0

我有一个模棱两可的语法问题。我有这个:

%token identifier
%token lolcakes

%start program

%%

program
    : call_or_definitions;

expression
    : identifier
    | lolcakes;

expressions
    : expression
    | expressions ',' expression;

call_or_definition
    : function_call
    | function_definition;

call_or_definitions
    : call_or_definition
    | call_or_definitions call_or_definition;

function_argument_core
    : identifier
    | identifier '=' expression
    | identifier '=' '{' expressions '}';

function_call
    : expression '(' function_arguments ')' ';';

function_definition
    : identifier '(' function_definition_arguments ')' '{' '}';

function_argument
    : lolcakes
    | function_argument_core;

function_arguments
    : function_argument 
    | function_arguments ',' function_argument

function_definition_argument
    : expression function_argument_core
    | function_argument_core;

function_definition_arguments
    : function_definition_argument
    | function_definition_arguments ',' function_definition_argument;

这是我真正的语法的一个子集,可以单独编译。目前,它在遇到流之间function_callfunction_definition遇到流时会产生 S/R 冲突identifier (。我试图通过统一函数调用和函数定义的语法来说服 Bison,直到令牌流的后期才需要做出决定。换句话说,如果它遇到调用和定义共同的东西,它可以减少它而不需要知道哪个是哪个,如果它遇到其他东西,其他东西会清楚地标记哪个是哪个。这甚至可能吗?如果可以,我该怎么做?如果可能的话,我真的宁愿避免改变输入流的结构。

4

2 回答 2

1

问题是 anexpression可以由一个identifier. 此时解析器需要决定它是一个identifieronly 还是应该将它减少到expression,因为这将决定之后的路径。

于 2011-08-11T11:46:48.093 回答
1

identifier ( identifier在您看到,或之前,问题应该不会出现)。此时,解析器必须决定是否将第二个标识符减少为 afunction_definition_argument或 an expression(变为function_argument)。

可以通过蛮力纯粹在语法中解决这个问题,但它会将您带入一个非终结符的迷宫,例如expression_not_naked_identifierand ambiguous_begining_of_function_defn_or_call,从而导致语义动作的猖獗重复。

编写类似的东西可能更易于维护(并导致更容易理解的语法错误消息)

definition_or_call_start: identifier '(' generic_argument_list ')'
generic_argument_list: generic_argument
                     | generic_argument_list ',' generic_argument
generic_argument: expression 
                | function_argument_core
                | ...
function_call: definition_or_call_start ';';
function_definition : definition_or_call_start '{' '}';

然后检查作为最后两个产品的操作中的语义约束,generic_arguments您已解析的实际与它们的用途相匹配。

于 2011-08-11T11:43:55.707 回答