Blame gfs2/libgfs2/parser.y

Packit Service 360c39
%code requires {
Packit Service 360c39
/* Required to break a circular dependency introduced with bison 2.6 */
Packit Service 360c39
typedef void* yyscan_t;
Packit Service 360c39
}
Packit Service 360c39
%code top {
Packit Service 360c39
#include <errno.h>
Packit Service 360c39
#include "lang.h"
Packit Service 360c39
#include "lexer.h"
Packit Service 360c39
Packit Service 360c39
static int yyerror(struct lgfs2_lang_state *state, yyscan_t lexer, const char *errorstr)
Packit Service 360c39
{
Packit Service 360c39
	fprintf(stderr, "%d:%d: %s\n", state->ls_linenum, state->ls_colnum, errorstr);
Packit Service 360c39
	return 1;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
}
Packit Service 360c39
%defines
Packit Service 360c39
%debug
Packit Service 360c39
%define api.pure
Packit Service 360c39
%parse-param { struct lgfs2_lang_state *state }
Packit Service 360c39
%parse-param { yyscan_t lexer }
Packit Service 360c39
%lex-param { yyscan_t lexer }
Packit Service 360c39
%start script
Packit Service 360c39
%token TOK_COLON
Packit Service 360c39
%token TOK_COMMA
Packit Service 360c39
%token TOK_ID
Packit Service 360c39
%token TOK_LBRACE
Packit Service 360c39
%token TOK_LBRACKET
Packit Service 360c39
%token TOK_NUMBER
Packit Service 360c39
%token TOK_OFFSET
Packit Service 360c39
%token TOK_RBRACE
Packit Service 360c39
%token TOK_RBRACKET
Packit Service 360c39
%token TOK_SEMI
Packit Service 360c39
%token TOK_SET
Packit Service 360c39
%token TOK_GET
Packit Service 360c39
%token TOK_STATE
Packit Service 360c39
%token TOK_STRING
Packit Service 360c39
%token TOK_PATH
Packit Service 360c39
%%
Packit Service 360c39
script:	statements {
Packit Service 360c39
		state->ls_ast_root = $1;
Packit Service 360c39
		state->ls_interp_curr = $1;
Packit Service 360c39
	}
Packit Service 360c39
	| statements TOK_SEMI {
Packit Service 360c39
		state->ls_ast_root = $1;
Packit Service 360c39
		state->ls_interp_curr = $1;
Packit Service 360c39
	}
Packit Service 360c39
;
Packit Service 360c39
statements: statements TOK_SEMI statement {
Packit Service 360c39
		state->ls_ast_tail->ast_left = $3;
Packit Service 360c39
		state->ls_ast_tail = $3;
Packit Service 360c39
		$$ = $1;
Packit Service 360c39
	}
Packit Service 360c39
	| statement {
Packit Service 360c39
		if (state->ls_ast_tail == NULL)
Packit Service 360c39
			state->ls_ast_tail = $1;
Packit Service 360c39
		$$ = $1;
Packit Service 360c39
	}
Packit Service 360c39
;
Packit Service 360c39
statement: set_stmt { $$ = $1;}
Packit Service 360c39
	| get_stmt { $$ = $1; }
Packit Service 360c39
;
Packit Service 360c39
set_stmt: TOK_SET blockspec structspec {
Packit Service 360c39
		$1->ast_right = $2;
Packit Service 360c39
		$2->ast_right = $3;
Packit Service 360c39
		$$ = $1;
Packit Service 360c39
	}
Packit Service 360c39
	| TOK_SET blockspec typespec structspec {
Packit Service 360c39
		$1->ast_right = $2;
Packit Service 360c39
		$2->ast_right = $3;
Packit Service 360c39
		$3->ast_right = $4;
Packit Service 360c39
		$$ = $1;
Packit Service 360c39
	}
Packit Service 360c39
;
Packit Service 360c39
get_stmt: TOK_GET blockspec {
Packit Service 360c39
		$1->ast_right = $2; $$ = $1;
Packit Service 360c39
	}
Packit Service 360c39
	| TOK_GET blockspec TOK_STATE {
Packit Service 360c39
		$1->ast_right = $2;
Packit Service 360c39
		$2->ast_right = $3;
Packit Service 360c39
		$$ = $1;
Packit Service 360c39
	}
Packit Service 360c39
;
Packit Service 360c39
blockspec: offset { $$ = $1; }
Packit Service 360c39
	| address { $$ = $1; }
Packit Service 360c39
	| path { $$ = $1; }
Packit Service 360c39
	| block_literal { $$ = $1; }
Packit Service 360c39
	| subscript { $$ = $1; }
Packit Service 360c39
;
Packit Service 360c39
offset:	blockspec TOK_OFFSET {
Packit Service 360c39
		$2->ast_left = $1;
Packit Service 360c39
		$$ = $2;
Packit Service 360c39
	}
Packit Service 360c39
;
Packit Service 360c39
typespec: identifier {
Packit Service 360c39
		$1->ast_type = AST_EX_TYPESPEC;
Packit Service 360c39
		$$ = $1;
Packit Service 360c39
	}
Packit Service 360c39
;
Packit Service 360c39
block_literal: identifier { $$ = $1; }
Packit Service 360c39
;
Packit Service 360c39
subscript: block_literal TOK_LBRACKET index TOK_RBRACKET {
Packit Service 360c39
		$4->ast_left = $1;
Packit Service 360c39
		$1->ast_left = $3;
Packit Service 360c39
		$$ = $4;
Packit Service 360c39
	}
Packit Service 360c39
;
Packit Service 360c39
index: number { $$ = $1; }
Packit Service 360c39
	| identifier { $$ = $1; }
Packit Service 360c39
;
Packit Service 360c39
address: number {
Packit Service 360c39
		$1->ast_type = AST_EX_ADDRESS;
Packit Service 360c39
		$$ = $1;
Packit Service 360c39
	 }
Packit Service 360c39
;
Packit Service 360c39
structspec: TOK_LBRACE fieldspecs TOK_RBRACE { $$ = $2; }
Packit Service 360c39
	| TOK_LBRACE TOK_RBRACE { $$ = NULL; }
Packit Service 360c39
;
Packit Service 360c39
fieldspecs: fieldspecs TOK_COMMA fieldspec {
Packit Service 360c39
		$1->ast_left = $3;
Packit Service 360c39
		$$ = $1;
Packit Service 360c39
	}
Packit Service 360c39
	| fieldspec { $$ = $1; }
Packit Service 360c39
;
Packit Service 360c39
fieldspec: identifier TOK_COLON fieldvalue {
Packit Service 360c39
		$2->ast_right = $1;
Packit Service 360c39
		$1->ast_right = $3;
Packit Service 360c39
		$$ = $2;
Packit Service 360c39
	}
Packit Service 360c39
;
Packit Service 360c39
fieldvalue: number { $$ = $1; }
Packit Service 360c39
	| string { $$ = $1; }
Packit Service 360c39
;
Packit Service 360c39
number: TOK_NUMBER { $$ = $1; }
Packit Service 360c39
string: TOK_STRING { $$ = $1; }
Packit Service 360c39
identifier: TOK_ID { $$ = $1; }
Packit Service 360c39
path: TOK_PATH { $$ = $1; }
Packit Service 360c39
%%
Packit Service 360c39
Packit Service 360c39
/**
Packit Service 360c39
 * Allocate and initialize a new parse state structure. The caller must free the
Packit Service 360c39
 * memory returned by this function.
Packit Service 360c39
 */
Packit Service 360c39
struct lgfs2_lang_state *lgfs2_lang_init(void)
Packit Service 360c39
{
Packit Service 360c39
	struct lgfs2_lang_state *state;
Packit Service 360c39
	state = calloc(1, sizeof(struct lgfs2_lang_state));
Packit Service 360c39
	if (state == NULL) {
Packit Service 360c39
		return NULL;
Packit Service 360c39
	}
Packit Service 360c39
	state->ls_linenum = 1;
Packit Service 360c39
	return state;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
void lgfs2_lang_free(struct lgfs2_lang_state **state)
Packit Service 360c39
{
Packit Service 360c39
	ast_destroy(&(*state)->ls_ast_root);
Packit Service 360c39
	free(*state);
Packit Service 360c39
	*state = NULL;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
int lgfs2_lang_parsef(struct lgfs2_lang_state *state, FILE *src)
Packit Service 360c39
{
Packit Service 360c39
	int ret = 0;
Packit Service 360c39
	yyscan_t lexer;
Packit Service 360c39
Packit Service 360c39
	ret = yylex_init_extra(state, &lexer);
Packit Service 360c39
	if (ret != 0) {
Packit Service 360c39
		fprintf(stderr, "Failed to initialize lexer.\n");
Packit Service 360c39
		return ret;
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	yyset_in(src, lexer);
Packit Service 360c39
	ret = yyparse(state, lexer);
Packit Service 360c39
	yylex_destroy(lexer);
Packit Service 360c39
	return ret;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
int lgfs2_lang_parses(struct lgfs2_lang_state *state, const char *cstr)
Packit Service 360c39
{
Packit Service 360c39
	int ret;
Packit Service 360c39
	FILE *src;
Packit Service 360c39
	char *str = strdup(cstr);
Packit Service 360c39
Packit Service 360c39
	if (str == NULL) {
Packit Service 360c39
		perror("Failed to duplicate source string");
Packit Service 360c39
		return 1;
Packit Service 360c39
	}
Packit Service 360c39
	src = fmemopen(str, strlen(str), "r");
Packit Service 360c39
	if (src == NULL) {
Packit Service 360c39
		perror("Failed to open string as source file");
Packit Service 360c39
		free(str);
Packit Service 360c39
		return 1;
Packit Service 360c39
	}
Packit Service 360c39
	ret = lgfs2_lang_parsef(state, src);
Packit Service 360c39
	fclose(src);
Packit Service 360c39
	free(str);
Packit Service 360c39
	if (ret != 0 || state->ls_errnum != 0) {
Packit Service 360c39
		return 1;
Packit Service 360c39
	}
Packit Service 360c39
	return 0;
Packit Service 360c39
}