Разбираем func f (arg1, arg2: type) в компиляторе lex yacc - PullRequest
1 голос
/ 25 мая 2019

Я успешно разбираю:

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

Ответы [ 2 ]

3 голосов
/ 25 мая 2019

Правило

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
    ;
2 голосов
/ 25 мая 2019

Если мы посмотрим, что yacc увидит при разборе a, c: int, у вас будет

iden_name COMMA iden_name COLON ident_type

Следовательно, поскольку в предложении запятой указан список имен параметров, он должен быть частью правила parameter, а не частью parameters. parameter необходимо обновить, чтобы он поддерживал список iden_name s.

...