diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2016-03-05 23:40:11 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2016-03-05 23:44:50 +0200 |
commit | 2dbad2727f1d00b223353965b326cfffa96fc776 (patch) | |
tree | 3e76daff8a9bf0a1268e183acce13d6ef828ccf7 /src/dhcpd-lex.l | |
parent | 8241dc04501f62b613f17f5c165f915a216ba30c (diff) | |
download | grecs-2dbad2727f1d00b223353965b326cfffa96fc776.tar.gz grecs-2dbad2727f1d00b223353965b326cfffa96fc776.tar.bz2 |
Improve dhcpd parser
* src/dhcpd-gram.y: Support assignments and conditional
expressions.
* src/dhcpd-lex.l: New exclusive states BOOL and EXPR.
* src/parsertab.c (parser_tab) [ENABLE_DHCPD_PARSER]: Define
dhcpd parser.
* tests/parser-dhcpd.at: New file.
* tests/Makefile.am: Add parser-dhcpd.at
* tests/testsuite.at: Likewise.
Diffstat (limited to 'src/dhcpd-lex.l')
-rw-r--r-- | src/dhcpd-lex.l | 77 |
1 files changed, 73 insertions, 4 deletions
diff --git a/src/dhcpd-lex.l b/src/dhcpd-lex.l index 12e64c6..450a54b 100644 --- a/src/dhcpd-lex.l +++ b/src/dhcpd-lex.l @@ -1,6 +1,5 @@ /* grecs - Gray's Extensible Configuration System -*- c -*- */ %option noinput -%option nounput %top { #ifdef HAVE_CONFIG_H # include <config.h> @@ -43,10 +42,13 @@ grecs_current_locus_point.col += yyleng; \ yylloc.end = grecs_current_locus_point; \ } while (0); + +#define ISWS(c) ((c)==' '||(c)=='\t') %} - -%x COMMENT STR +%x COMMENT STR BOOL EXPR + +OWS [ \t\f]* WS [ \t\f][ \t\f]* ID [a-zA-Z_][a-zA-Z_0-9-]* P [1-9][0-9]* @@ -66,6 +68,61 @@ P [1-9][0-9]* #.* /* end-of-file comment */; "//".*\n { grecs_locus_point_advance_line(grecs_current_locus_point); } "//".* /* end-of-file comment */; +"if" return DHCPD_IF; +"elsif" return DHCPD_ELSIF; +"else" return DHCPD_ELSE; + +<BOOL>[^\{\n]*\n { + char *p; + size_t len; + for (p = yytext, len = yyleng - 1; ISWS(*p) && len > 0; p++, len--) + ; + if (len) { + grecs_line_add(p, len); + grecs_line_add(" ", 1); + } + grecs_locus_point_advance_line(grecs_current_locus_point); +} +<BOOL>[^\{\n]*\{ { + char *p; + size_t len; + + unput('{'); + for (p = yytext, len = yyleng - 1; ISWS(*p) && len > 0; p++, len--) + ; + for (; len > 0 && ISWS(p[len-1]); len--) + ; + grecs_line_add(p, len); + BEGIN(INITIAL); + yylval.string = grecs_line_finish(); + return DHCPD_EXPR; +} + +<EXPR>[^;\n]*\n { + char *p; + size_t len; + for (p = yytext, len = yyleng - 1; ISWS(*p) && len > 0; p++, len--) + ; + if (len) { + grecs_line_add(p, len); + grecs_line_add(" ", 1); + } + grecs_locus_point_advance_line(grecs_current_locus_point); +} +<EXPR>[^;\n]*; { + char *p; + size_t len; + + unput(';'); + for (p = yytext, len = yyleng - 1; ISWS(*p) && len > 0; p++, len--) + ; + for (; len > 0 && ISWS(p[len-1]); len--) + ; + grecs_line_add(p, len); + BEGIN(INITIAL); + yylval.string = grecs_line_finish(); + return DHCPD_EXPR; +} /* Identifiers */ {ID} { grecs_line_begin(); grecs_line_add(yytext, yyleng); @@ -103,7 +160,7 @@ P [1-9][0-9]* {WS} ; /* Other tokens */ \n { grecs_locus_point_advance_line(grecs_current_locus_point); } -[,;{}()!] return yytext[0]; +[,;{}()!=] return yytext[0]; . { if (isascii(yytext[0]) && isprint(yytext[0])) grecs_error(&yylloc, 0, _("stray character %c"), yytext[0]); @@ -112,6 +169,18 @@ P [1-9][0-9]* (unsigned char) yytext[0]); } %% +void +grecs_dhcpd_begin_bool(void) +{ + BEGIN(BOOL); +} + +void +grecs_dhcpd_begin_expr(void) +{ + BEGIN(EXPR); +} + struct dhcpd_input_context { ino_t i_node; dev_t i_dev; |