在lex yacc编译器中解析func f(arg1,arg2:type)

时间:2019-05-24 21:37:42

标签: c parsing compiler-construction yacc

我成功解析了:

func f(a: int) return int{}

func f(a: int; b: string) return int{}

但我无法解析

func f(a, c: int; b: string) return int{}

我的编译器无法捕获逗号后面的所有内容,因此我无法弄清楚如何解决它。 在第三种情况下,我得到的是c作为整数,b作为字符串,null作为a(而不是a作为整数)。

我使用的规则-

function:
FUNC iden_name O_PAREN parameters C_PAREN RETURN ident_type block { 
    Node * left = makeTripNode("FUNCTION", $7, $2, $4 );
    Node * right = $8;
    $$ = makePairNode("FUNCTION", left, right ); 
}
parameters:
parameters SEMICOLON parameter { $$ = makePairNode("PARAMETERS", $1, $3); }
    | parameters COMMA parameter { $$ = makePairNode("PARAMETERS", $1, $3); }
    | parameter {$$ = $1;}
    ;
parameter:
iden_name COLON ident_type { $$ = makePairNode("PARAM", $3, $1); }
    | iden_name {$$ = $1;}
    ;

2 个答案:

答案 0 :(得分:3)

规则

parameters:
parameters SEMICOLON parameter { $$ = makePairNode("PARAMETERS", $1, $3); }
    | parameters COMMA parameter { $$ = makePairNode("PARAMETERS", $1, $3); }
    | parameter {$$ = $1;}
    ;

定义parameters是一个称为parameter的序列,用分号或逗号分隔。马上看起来就不像您想要的那样,因为它将接受a: int, b: string

同时,根据下一条规则,可以使包含一个ident_name的参数成为可能。正是这样对待a,的方式:一种无类型的a与其他字符之间用逗号隔开。

如果我正确理解了您的意图,请考虑以下内容

parameters
    : parameters SEMICOLON typed_parameter group
    | typed_parameter_group
    ;

typed_parameter_group
    : parameter_list COLON ident_type
    | parameter_list
    ;

parameter_list
    : parameter_list COMMA iden_name
    | iden_name
    ;

答案 1 :(得分:2)

如果我们考虑解析a, c: int时会看到yacc,那么您有

iden_name COMMA iden_name COLON ident_type

因此,由于逗号子句指定了参数名称列表,因此它应该是parameter规则的一部分,而不是parameters的一部分。 parameter将需要更新以支持iden_name列表。