static char *sccsid
= "@(#)parser1.c 3.5 83/12/09";
#define p_erred() (cx.x_erred)
#define p_clearerr() (cx.x_erred = cx.x_synerred = 0)
#define p_abort() (cx.x_abort)
#define p_varfree(v) if ((v).v_type == V_STR) str_free((v).v_str)
if (token
== T_EOF
|| p_abort())
while (token
!= T_EOL
&& token
!= T_EOF
) {
for (; p_statement(flag
) >= 0; p_clearerr())
error("statement: %d.", flag
);
error("statement: EOL.", flag
);
error("statement: IF.", flag
);
error("statement: command.", flag
);
if (p_expr(&t
, flag
) < 0) {
true = !true && t
.v_num
!= 0;
p_error("Numeric value required for if.");
p_statementlist(flag
&& true);
p_statementlist(flag
&& !true);
error("command: %d.", flag
);
if (p_expr(&t
, flag
) < 0)
error("command: expression.");
if ((cmd
= str_itoa(t
.v_num
)) == 0) {
error("command: assignment %s.", cmd
== 0 ? "ERR" : cmd
);
if (p_assign(cmd
, &t
, flag
) < 0) {
error("command: function %s.", cmd
== 0 ? "ERR" : cmd
);
if (p_function(cmd
, &t
, flag
) < 0) {
else if (token
!= T_EOF
) {
* name == 0 means we don't have a function name but
* want to parse the arguments anyway. flag == 0 in this case.
p_function(name
, v
, flag
)
register struct value
*v
;
register struct lcmd_tab
*c
;
register struct lcmd_arg
*ap
;
if ((c
= lcmd_lookup(name
)) == 0) {
p_error("%s: No such command.", name
);
for (ap
= c
->lc_arg
; ap
->arg_name
!= 0; ap
++)
ap
->arg_val
.v_type
= V_ERR
;
if (p_expr0(&t
, flag
) < 0)
p_error("%s: Too many arguments.",
if ((tmp
= str_itoa(t
.v_num
)) == 0) {
if (p_expr(&t
, flag
) < 0) {
for (ap
= c
->lc_arg
; ap
->arg_name
!= 0; ap
++)
if (str_match(tmp
, ap
->arg_name
,
p_error("%s: Unknown argument \"%s\".",
if (ap
->arg_val
.v_type
!= V_ERR
) {
p_error("%s: Argument %d (%s) duplicated.",
c
->lc_name
, ap
- c
->lc_arg
+ 1,
} else if (t
.v_type
== V_ERR
) {
} else if (ap
->arg_type
== ARG_NUM
&& t
.v_type
!= V_NUM
|| ap
->arg_type
== ARG_STR
&& t
.v_type
!= V_STR
) {
p_error("%s: Argument %d (%s) type mismatch.",
c
->lc_name
, ap
- c
->lc_arg
+ 1,
if (token
!= T_RP
&& token
!= T_EOL
&& token
!= T_EOF
)
flag
= 0; /* look ahead a bit */
for (ap
= c
->lc_arg
; ap
->arg_name
!= 0; ap
++)
for (ap
= c
->lc_arg
; ap
->arg_name
!= 0; ap
++)
if (p_expr(v
, flag
) < 0) {
if (flag
&& var_set(name
, v
) == 0) {
register struct value
*v
;
error("expr: %d.", flag
);
if (p_expr0(&t
, flag
) < 0)
if ((t
.v_str
= str_itoa(t
.v_num
)) == 0) {
ret
= p_assign(t
.v_str
, v
, flag
);
register struct value
*v
;
if (p_expr1(v
, flag
) < 0)
p_error("Numeric value required for ?.");
if ((flag
&& true ? p_expr1(v
, 1) : p_expr1(&t
, 0)) < 0)
return flag
&& !true ? p_expr1(v
, 1) : p_expr1(&t
, 0);
register struct value
*v
;
if (p_expr2(v
, flag
) < 0)
v
->v_num
= true = true || v
->v_num
!= 0;
p_error("Numeric value required for ||.");
if (p_expr2(v
, flag
&& !true) < 0)
register struct value
*v
;
if (p_expr3_10(3, v
, flag
) < 0)
v
->v_num
= true = true && v
->v_num
!= 0;
p_error("Numeric value required for &&.");
if (p_expr3_10(3, v
, flag
&& true) < 0)
p_expr3_10(level
, v
, flag
)
register struct value
*v
;
if (p_expr11(v
, flag
) < 0)
if (p_expr3_10(level
+ 1, v
, flag
) < 0)
else if (token
== T_MINUS
)
if (p_expr11(&t
, flag
) < 0)
if (p_expr3_10(level
+ 1, &t
, flag
) < 0)
else if (t
.v_type
!= v
->v_type
) {
p_error("Type mismatch.");
if (v
->v_type
== V_STR
) {
tmp
= strcmp(v
->v_str
, t
.v_str
);
if (v
->v_type
== V_STR
) {
p_error("Numeric value required for %s.",
v
->v_num
= v
->v_num
== t
.v_num
;
v
->v_num
= v
->v_num
!= t
.v_num
;
v
->v_num
= v
->v_num
< t
.v_num
;
v
->v_num
= v
->v_num
<= t
.v_num
;
v
->v_num
= v
->v_num
> t
.v_num
;
v
->v_num
= v
->v_num
>= t
.v_num
;
register struct value
*v
;
return p_expr12(v
, flag
);
if (p_expr11(v
, flag
) < 0)
if (op
== T_DOLLAR
&& (v
->v_str
= str_itoa(v
->v_num
)) == 0) {
p_error("Numeric value required for %s.", opname
);
if ((r
= var_lookup(v
->v_str
)) == 0) {
p_error("%s: Undefined variable.", v
->v_str
);
&& (v
->v_str
= str_cpy(v
->v_str
)) == 0) {
* string, number, ( expr )
* Also we map * and % into strings.
* Always return v_type == V_ERR when flag == 0.
register struct value
*v
;
error("expr12: %d.", flag
);
error("expr12: NUM %d.", token_num
);
error("expr12: STR %s.", token_str
);
if (p_expr(v
, flag
) < 0) {
error("expr12: token %d.", token
);
if ((cmd
= str_itoa(v
->v_num
)) == 0) {
error("expr12: function %s.", cmd
);
if (p_function(cmd
, v
, flag
) < 0) {
cx
.x_synerred
= cx
.x_erred
= 1;
cx
.x_erred
= cx
.x_abort
= 1;