首页 > 解决方案 > 在 lex yacc 编译器中解析 func f(arg1, arg2: type)

问题描述

我成功解析:

func f(a: int) return int{}

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

但我无法解析

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

我的编译器无法捕获逗号后面的任何内容,我无法弄清楚如何修复它。我在第三种情况下得到的是 c 作为 int,b 作为字符串,null 作为 a(而不是 a 作为 int)。

我使用的规则-

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;}
    ;

标签: cparsingcompiler-constructionyacc

解决方案


规则

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

定义它parameters是一个叫做 的东西的序列,parameter用分号或逗号分隔。马上它看起来不像你所追求的,因为它会接受a: int, b: string

同时,根据下一条规则,可以有一个由 go just an 组成的参数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
    ;

推荐阅读