From c6030063c6eeee267eca07d06dbe69a2657181c6 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Mon, 12 Dec 2016 16:55:31 +0100 Subject: [PATCH] Keep track of location in parser --- lexer/theme-lexer.l | 88 +++++++++++++++++++++++++++++--------------- lexer/theme-parser.y | 6 ++- source/theme.c | 8 ++-- 3 files changed, 67 insertions(+), 35 deletions(-) diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index 7cc58046..7f82e759 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -1,22 +1,40 @@ -%option noyywrap nounput batch +%option noyywrap nounput +%option bison-locations %{ #include #include "lexer/theme-parser.h" -int yylex(void); -#define YY_DECL int yylex() +%} +%{ + +#define YY_USER_ACTION {\ + yylloc->last_column+= yyleng;\ +} +#define YY_LLOC_START {\ + yylloc->first_line = yylloc->last_line; yylloc->first_column = yylloc->last_column;\ +} %} %% + +%{ +YY_LLOC_START +%} + "//" { int c; - while ((c = input()) != EOF) + while ((c = input()) != EOF){ if (c == '\n') { + yylloc->last_column = 1; + yylloc->last_line ++; break; } + yylloc->last_column++; + } + YY_LLOC_START } "/*" { int c = 0, p; @@ -25,13 +43,20 @@ int yylex(void); p = c; c = input(); switch (c) { - case '*': if (p == '/') { c = 0; nesting_depth++; } break; - case '/': if (p == '*') { c = 0; nesting_depth--; } break; - case '\n': break; + case '*': yylloc->last_column++; if (p == '/') { c = 0; nesting_depth++; } break; + case '/': yylloc->last_column++; if (p == '*') { c = 0; nesting_depth--; } break; + case '\n': { + yylloc->last_column = 1; + yylloc->last_line ++; + break; + } case EOF: nesting_depth = 0; break; - default: ; + default: + yylloc->last_column++; + ; } } + YY_LLOC_START } "\{" { return BOPEN;} "\}" { return BCLOSE;} @@ -39,47 +64,50 @@ int yylex(void); ";" { return PCLOSE;} "." { return NSEP; } [ \t] ; // ignore all whitespace -[0-9]+\.[0-9]+ { yylval.fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;} -[0-9]+ { yylval.ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} -(true|false) { yylval.bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;} -[_\-a-zA-Z0-9]+ { yylval.sval = g_strdup(yytext); return N_STRING;} -\"[_\-a-zA-Z0-9 \t]+\" { yytext[yyleng-1] = '\0'; yylval.sval = g_strdup(&yytext[1]); return T_STRING;} +[0-9]+\.[0-9]+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;} +[0-9]+ { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} +(true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;} +[_\-a-zA-Z0-9]+ { yylval->sval = g_strdup(yytext); return N_STRING;} +\"[_\-a-zA-Z0-9 \t]+\" { yytext[yyleng-1] = '\0'; yylval->sval = g_strdup(&yytext[1]); return T_STRING;} #[0-9A-Fa-f]{8} { union { unsigned int val; struct { unsigned char b,g,r,a;};} val; val.val = (unsigned int)strtoull ( &yytext[1], NULL, 16); - yylval.colorval.alpha = val.a/255.0; - yylval.colorval.red = val.r/255.0; - yylval.colorval.green = val.g/255.0; - yylval.colorval.blue = val.b/255.0; + yylval->colorval.alpha = val.a/255.0; + yylval->colorval.red = val.r/255.0; + yylval->colorval.green = val.g/255.0; + yylval->colorval.blue = val.b/255.0; return T_COLOR; } #[0-9A-Fa-f]{6} { union { unsigned int val; struct { unsigned char b,g,r,a;};} val; val.val = (unsigned int)g_ascii_strtoull ( &yytext[1], NULL, 16); - yylval.colorval.alpha = 1.0; - yylval.colorval.red = val.r/255.0; - yylval.colorval.green = val.g/255.0; - yylval.colorval.blue = val.b/255.0; + yylval->colorval.alpha = 1.0; + yylval->colorval.red = val.r/255.0; + yylval->colorval.green = val.g/255.0; + yylval->colorval.blue = val.b/255.0; return T_COLOR; } rgba\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[01](\.[0-9]+)?\) { char *endptr = &yytext[5]; - yylval.colorval.red = g_ascii_strtoull ( endptr, &endptr, 10); - yylval.colorval.green= g_ascii_strtoull ( endptr+1, &endptr, 10); - yylval.colorval.blue= g_ascii_strtoull ( endptr+1, &endptr, 10); - yylval.colorval.alpha= g_ascii_strtod ( endptr+1, NULL); + yylval->colorval.red = g_ascii_strtoull ( endptr, &endptr, 10); + yylval->colorval.green= g_ascii_strtoull ( endptr+1, &endptr, 10); + yylval->colorval.blue= g_ascii_strtoull ( endptr+1, &endptr, 10); + yylval->colorval.alpha= g_ascii_strtod ( endptr+1, NULL); return T_COLOR; } rgb\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3}\) { char *endptr = &yytext[4]; - yylval.colorval.red = g_ascii_strtoull ( endptr, &endptr, 10); - yylval.colorval.green = g_ascii_strtoull ( endptr+1, &endptr, 10); - yylval.colorval.blue = g_ascii_strtoull ( endptr+1, &endptr, 10); - yylval.colorval.alpha = 1.0; + yylval->colorval.red = g_ascii_strtoull ( endptr, &endptr, 10); + yylval->colorval.green = g_ascii_strtoull ( endptr+1, &endptr, 10); + yylval->colorval.blue = g_ascii_strtoull ( endptr+1, &endptr, 10); + yylval->colorval.alpha = 1.0; return T_COLOR; } - [\r\n]+ ; +(\r\n|\n) { + yylloc->last_column = 1; + yylloc->last_line ++; +}; <*><> { yyterminate(); diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index 53cf08af..2ad71627 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -1,3 +1,4 @@ +%define api.pure %glr-parser %skeleton "glr.c" %locations @@ -11,11 +12,12 @@ #include #include -void yyerror(const char* s); -int yylex (void ); #include "theme.h" +#include "lexer/theme-parser.h" Widget *rofi_theme = NULL; +void yyerror(YYLTYPE *yylloc, const char* s); +int yylex (YYSTYPE *, YYLTYPE *); %} %union { diff --git a/source/theme.c b/source/theme.c index ba57a3d0..b098120e 100644 --- a/source/theme.c +++ b/source/theme.c @@ -3,14 +3,15 @@ #include #include #include "theme.h" +#include "lexer/theme-parser.h" +void yyerror ( YYLTYPE *ylloc, const char *); -void yyerror ( const char *); Widget *rofi_theme_find_or_create_class ( Widget *base, const char *class ) { for ( unsigned int i = 0; i < base->num_widgets;i++){ if ( g_strcmp0(base->widgets[i]->name, class) == 0 ){ return base->widgets[i]; - } + } } base->widgets = g_realloc ( base->widgets, sizeof(Widget*)*(base->num_widgets+1)); @@ -116,8 +117,9 @@ extern int yyparse(); extern FILE* yyin; extern Widget *rofi_theme; -void yyerror(const char* s) { +void yyerror(YYLTYPE *yylloc, const char* s) { fprintf(stderr, "Parse error: %s\n", s); + fprintf(stderr, "From line %d column %d to line %d column %d\n", yylloc->first_line, yylloc->first_column, yylloc->last_line, yylloc->last_column); exit(EXIT_FAILURE); } /**