]> git.ipfire.org Git - pakfire.git/commitdiff
libpakfire: parser: Add compatibility for older pakfire files
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 17 May 2019 17:30:09 +0000 (18:30 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 17 May 2019 17:30:09 +0000 (18:30 +0100)
This patch moves the keyword handling out of the parser and puts
it into the lexer where the "define" keyword is added where it is
needed.

That way, we have a clear definition of a clean syntax without
any shift/reduce or reduce/reduce errors, but remain compatible
to the current pakfire files.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/parser/grammar.y
src/libpakfire/parser/scanner.l

index 00eedc25c20ea702d87249a1198cef8ec8870633..0b00e4140d9f67cdbad86b6d5e3d16691ba7d43e 100644 (file)
@@ -72,7 +72,6 @@ char* current_block = NULL;
 %token <string>                                        T_WORD
 
 %type <string>                                 define;
-%type <string>                                 keyword;
 %type <string>                                 line;
 %type <string>                                 text;
 %type <string>                                 variable;
@@ -108,14 +107,9 @@ value                                              : words
                                                                $$ = NULL;
                                                        };
 
-                                                       // XXX T_DEFINE is sort of missing here, but adding it
-                                                       // generates a highly ambiguous grammar
-keyword                                                : T_IF;
-
                                                        // IF can show up in values and therefore this
                                                        // hack is needed to parse those properly
-word                                           : T_WORD
-                                                       | keyword;
+word                                           : T_WORD;
 
 words                                          : word
                                                        | words word
@@ -196,10 +190,6 @@ assignment                                 : variable T_ASSIGN value T_EOL
 define                                         : T_DEFINE variable T_EOL
                                                        {
                                                                $$ = $2;
-                                                       }
-                                                       | variable T_EOL
-                                                       {
-                                                               $$ = $1;
                                                        };
 
 %%
index c7756a5b0aff4ed988a2ecdf0d461ad80bedfbca..442c751bd3168d8d4fa28c709166ddc2b80e6b53 100644 (file)
@@ -18,7 +18,7 @@
 #                                                                             #
 #############################################################################*/
 
-%option nounput noinput noyywrap yylineno
+%option noinput noyywrap yylineno
 
 %{
 #define YY_DECL int yylex()
@@ -39,20 +39,59 @@ whitespace          ([ \t])+
 quoted_string  \"([^\"])*\"
 word                   ({quoted_string}|({digit}|{letter}|{special})+)
 
+/*
+       Compatibility for the old python parser.
+
+       We automatically prepend "define" in front of some keywords, because
+       generally the language requires it.
+*/
+keywords               (description|{whitespace}(build(_cmds)?|install(_cmds)?|prepare_cmds|requires))
+
+%s DEFINE
+
 %%
 
 #.*$                   { /* ignore comments */ }
 {whitespace}   {}
 \n                             { num_lines++; return T_EOL; }
 
-"=="                   { return T_EQUALS; }
-"="                            { return T_ASSIGN; }
-"+="                   { return T_APPEND; }
+<INITIAL>^{keywords}$ {
+                                       // Determine the length of the string
+                                       size_t length = strlen("define ") + yyleng;
+
+                                       // Make a copy because unput touches yytext
+                                       char* buffer = pakfire_malloc(length + 1);
+                                       snprintf(buffer, length + 1, "define %s", yytext);
+
+                                       // Put the whole string back onto the stack (backwards)
+                                       for (int i = length - 1; i >= 0; i--) {
+                                               unput(buffer[i]);
+                                       }
+
+                                       pakfire_free(buffer);
+                               }
 
-"if"                   { return T_IF; }
-"define"               { return T_DEFINE; }
-"def"                  { return T_DEFINE; }
-"end"                  { return T_END; }
+<INITIAL>"=="  { return T_EQUALS; }
+<INITIAL>"="   { return T_ASSIGN; }
+<INITIAL>"+="  { return T_APPEND; }
+
+<INITIAL>"if"  { return T_IF; }
+<INITIAL>"define" {
+                                       BEGIN(DEFINE);
+                                       return T_DEFINE;
+                               }
+<INITIAL>"def" {
+                                       BEGIN(DEFINE);
+                                       return T_DEFINE;
+                               }
+<INITIAL>"end" {
+                                       return T_END;
+                               }
+
+<DEFINE>"end"  {
+                                       BEGIN(0);
+                                       return T_END;
+                               }
 
 {quoted_string}        {
                                        // Remove quotes