parse: update parser to support new lexer behaviour
This commit is contained in:
@@ -24,7 +24,7 @@ void parse_ctx_cleanup(struct parse_ctx *ctx)
|
|||||||
struct ast_node *parse_ctx_read_node(struct parse_ctx *ctx)
|
struct ast_node *parse_ctx_read_node(struct parse_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct ast_node *result = NULL;
|
struct ast_node *result = NULL;
|
||||||
bool ok = parse_expr(ctx, &result);
|
bool ok = parse_statement(ctx, &result);
|
||||||
|
|
||||||
return ok ? result : NULL;
|
return ok ? result : NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,22 +16,20 @@ extern struct lex_token *peek_token(struct parse_ctx *ctx);
|
|||||||
extern enum token_type peek_token_type(struct parse_ctx *ctx);
|
extern enum token_type peek_token_type(struct parse_ctx *ctx);
|
||||||
extern enum token_keyword peek_unknown_keyword(struct parse_ctx *ctx);
|
extern enum token_keyword peek_unknown_keyword(struct parse_ctx *ctx);
|
||||||
extern enum token_symbol peek_unknown_symbol(struct parse_ctx *ctx);
|
extern enum token_symbol peek_unknown_symbol(struct parse_ctx *ctx);
|
||||||
extern bool peek_int(struct parse_ctx *ctx);
|
|
||||||
|
|
||||||
extern struct lex_token *claim_token(struct parse_ctx *ctx);
|
extern struct lex_token *claim_token(struct parse_ctx *ctx);
|
||||||
extern struct lex_token *claim_glob_word(struct parse_ctx *ctx);
|
|
||||||
extern void discard_token(struct parse_ctx *ctx);
|
extern void discard_token(struct parse_ctx *ctx);
|
||||||
|
|
||||||
extern bool peek_linefeed(struct parse_ctx *ctx);
|
extern bool peek_linefeed(struct parse_ctx *ctx);
|
||||||
extern bool peek_symbol(struct parse_ctx *ctx, enum token_symbol sym);
|
extern bool peek_symbol(struct parse_ctx *ctx, enum token_symbol sym);
|
||||||
extern struct lex_token *peek_glob_word(struct parse_ctx *ctx);
|
extern bool peek_word(struct parse_ctx *ctx, struct lex_token **out);
|
||||||
|
extern bool peek_int(struct parse_ctx *ctx);
|
||||||
|
|
||||||
extern bool parse_linefeed(struct parse_ctx *ctx);
|
extern bool parse_linefeed(struct parse_ctx *ctx);
|
||||||
extern bool parse_symbol(struct parse_ctx *ctx, enum token_symbol sym);
|
extern bool parse_symbol(struct parse_ctx *ctx, enum token_symbol sym);
|
||||||
extern bool parse_keyword(struct parse_ctx *ctx, enum token_keyword kw);
|
extern bool parse_keyword(struct parse_ctx *ctx, enum token_keyword kw);
|
||||||
extern bool parse_int(struct parse_ctx *ctx, long long *out);
|
extern bool parse_int(struct parse_ctx *ctx, long long *out);
|
||||||
extern bool parse_flag(struct parse_ctx *ctx, struct lex_token **out);
|
extern bool parse_flag(struct parse_ctx *ctx, struct lex_token **out);
|
||||||
extern struct lex_token *parse_glob_word(struct parse_ctx *ctx);
|
|
||||||
|
|
||||||
extern bool peek_arith_expr(struct parse_ctx *ctx);
|
extern bool peek_arith_expr(struct parse_ctx *ctx);
|
||||||
extern bool parse_arith_expr(struct parse_ctx *ctx, struct ast_node **out);
|
extern bool parse_arith_expr(struct parse_ctx *ctx, struct ast_node **out);
|
||||||
@@ -40,7 +38,7 @@ extern bool parse_operand(
|
|||||||
enum parse_operand_flags flags,
|
enum parse_operand_flags flags,
|
||||||
struct ast_node **out);
|
struct ast_node **out);
|
||||||
|
|
||||||
extern bool parse_expr(struct parse_ctx *ctx, struct ast_node **out);
|
extern bool parse_statement(struct parse_ctx *ctx, struct ast_node **out);
|
||||||
|
|
||||||
extern bool peek_command(struct parse_ctx *ctx);
|
extern bool peek_command(struct parse_ctx *ctx);
|
||||||
extern bool parse_command(struct parse_ctx *ctx, struct ast_node **out);
|
extern bool parse_command(struct parse_ctx *ctx, struct ast_node **out);
|
||||||
|
|||||||
@@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
static bool parse_cmdcall_arg(struct parse_ctx *ctx, struct ast_node **out)
|
static bool parse_cmdcall_arg(struct parse_ctx *ctx, struct ast_node **out)
|
||||||
{
|
{
|
||||||
|
if (ctx->p_status != BSHELL_SUCCESS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
struct lex_token *tok = peek_token(ctx);
|
struct lex_token *tok = peek_token(ctx);
|
||||||
if (!tok) {
|
if (!tok) {
|
||||||
return false;
|
return false;
|
||||||
@@ -80,19 +84,7 @@ static bool parse_cmdcall_arg(struct parse_ctx *ctx, struct ast_node **out)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default:
|
||||||
struct word_ast_node *n
|
|
||||||
= (struct word_ast_node *)ast_node_create(AST_WORD);
|
|
||||||
if (!n) {
|
|
||||||
ctx->p_status = BSHELL_ERR_NO_MEMORY;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
n->n_value = claim_glob_word(ctx);
|
|
||||||
*out = (struct ast_node *)n;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,6 +97,10 @@ static bool parse_redirect_to_fd(
|
|||||||
bool append,
|
bool append,
|
||||||
struct ast_node **out)
|
struct ast_node **out)
|
||||||
{
|
{
|
||||||
|
if (ctx->p_status != BSHELL_SUCCESS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
struct redirection_ast_node *redirect
|
struct redirection_ast_node *redirect
|
||||||
= (struct redirection_ast_node *)ast_node_create(
|
= (struct redirection_ast_node *)ast_node_create(
|
||||||
AST_REDIRECTION);
|
AST_REDIRECTION);
|
||||||
@@ -117,18 +113,34 @@ static bool parse_redirect_to_fd(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
long long out_fd = 0;
|
struct lex_token *out_tok = NULL;
|
||||||
if (!parse_int(ctx, &out_fd)) {
|
struct ast_node *out_expr = NULL;
|
||||||
ctx->p_status = BSHELL_ERR_BAD_SYNTAX;
|
long long out_fd = -1;
|
||||||
ast_node_destroy((struct ast_node *)redirect);
|
|
||||||
|
if (peek_word(ctx, &out_tok)) {
|
||||||
|
const char *s = out_tok->tok_str;
|
||||||
|
char *ep;
|
||||||
|
out_fd = strtoll(s, &ep, 10);
|
||||||
|
if (*ep == '\0') {
|
||||||
|
discard_token(ctx);
|
||||||
|
out_tok = NULL;
|
||||||
|
} else {
|
||||||
|
out_fd = -1;
|
||||||
|
}
|
||||||
|
} else if (!parse_cmdcall_arg(ctx, &out_expr)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
redirect->n_out_is_fd = true;
|
redirect->n_out_is_fd = (out_fd >= 0) || out_expr;
|
||||||
redirect->n_out_is_expr = false;
|
redirect->n_out_is_expr = out_expr != NULL;
|
||||||
redirect->n_out = (unsigned int)out_fd;
|
redirect->n_out = (unsigned int)out_fd;
|
||||||
*out = (struct ast_node *)redirect;
|
redirect->n_out_path_expr = out_expr;
|
||||||
|
if (out_tok) {
|
||||||
|
redirect->n_out_tok = claim_token(ctx);
|
||||||
|
redirect->n_out_path = out_tok->tok_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out = (struct ast_node *)redirect;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,6 +151,10 @@ static bool parse_redirect_to_file_squashed(
|
|||||||
const char *str,
|
const char *str,
|
||||||
struct ast_node **out)
|
struct ast_node **out)
|
||||||
{
|
{
|
||||||
|
if (ctx->p_status != BSHELL_SUCCESS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
struct lex_token *tok = peek_token(ctx);
|
struct lex_token *tok = peek_token(ctx);
|
||||||
if (*str == '\0') {
|
if (*str == '\0') {
|
||||||
return false;
|
return false;
|
||||||
@@ -166,6 +182,10 @@ static bool parse_redirect_to_file_separate(
|
|||||||
bool append,
|
bool append,
|
||||||
struct ast_node **out)
|
struct ast_node **out)
|
||||||
{
|
{
|
||||||
|
if (ctx->p_status != BSHELL_SUCCESS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
struct ast_node *out_path = NULL;
|
struct ast_node *out_path = NULL;
|
||||||
if (!parse_cmdcall_arg(ctx, &out_path)) {
|
if (!parse_cmdcall_arg(ctx, &out_path)) {
|
||||||
ctx->p_status = BSHELL_ERR_BAD_SYNTAX;
|
ctx->p_status = BSHELL_ERR_BAD_SYNTAX;
|
||||||
|
|||||||
@@ -8,11 +8,6 @@ struct lex_token *claim_token(struct parse_ctx *ctx)
|
|||||||
return lex_ctx_claim(ctx->p_src);
|
return lex_ctx_claim(ctx->p_src);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct lex_token *claim_glob_word(struct parse_ctx *ctx)
|
|
||||||
{
|
|
||||||
return lex_ctx_claim_word(ctx->p_src);
|
|
||||||
}
|
|
||||||
|
|
||||||
void discard_token(struct parse_ctx *ctx)
|
void discard_token(struct parse_ctx *ctx)
|
||||||
{
|
{
|
||||||
return lex_ctx_discard(ctx->p_src);
|
return lex_ctx_discard(ctx->p_src);
|
||||||
@@ -43,6 +38,17 @@ enum token_keyword peek_unknown_keyword(struct parse_ctx *ctx)
|
|||||||
: KW_NONE;
|
: KW_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool peek_word(struct parse_ctx *ctx, struct lex_token **out)
|
||||||
|
{
|
||||||
|
struct lex_token *tok = peek_token(ctx);
|
||||||
|
if (tok && tok->tok_type == TOK_WORD) {
|
||||||
|
*out = tok;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool peek_linefeed(struct parse_ctx *ctx)
|
bool peek_linefeed(struct parse_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct lex_token *tok = peek_token(ctx);
|
struct lex_token *tok = peek_token(ctx);
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
#include "../syntax.h"
|
#include "../syntax.h"
|
||||||
|
|
||||||
bool parse_expr(struct parse_ctx *ctx, struct ast_node **out)
|
bool parse_statement(struct parse_ctx *ctx, struct ast_node **out)
|
||||||
{
|
{
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
if (peek_arith_expr(ctx)) {
|
if (peek_arith_expr(ctx)) {
|
||||||
ok = parse_arith_expr(ctx, out);
|
ok = parse_arith_expr(ctx, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ok && peek_command(ctx)) {
|
if (!ok && peek_command(ctx)) {
|
||||||
ok = parse_command(ctx, out);
|
ok = parse_command(ctx, out);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user