summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Davenport <qball@gmpclient.org>2016-12-12 16:55:31 +0100
committerDave Davenport <qball@gmpclient.org>2016-12-12 16:55:31 +0100
commitc6030063c6eeee267eca07d06dbe69a2657181c6 (patch)
tree6bccea52c788badc1508ecc8db737f7bcc7f2088
parentd6ec7b1de8094d20887f72be32af09ecfe3da4fe (diff)
Keep track of location in parser
-rw-r--r--lexer/theme-lexer.l88
-rw-r--r--lexer/theme-parser.y6
-rw-r--r--source/theme.c8
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 <stdio.h>
#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 ++;
+};
<*><<EOF>> {
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 <stdio.h>
#include <stdlib.h>
-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 <errno.h>
#include <string.h>
#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);
}
/**