2016-06-01 7 views
0

ist der Code, den ich habe:Warum werden meine Syntaxfehler in Jison nicht "propagiert"? Dieser

%lex 
%options flex 

%{ 
// Used to store the parsed data 
if (!('regions' in yy)) { 
    yy.regions = { 
     settings: {}, 
     tables: [], 
     relationships: [] 
    }; 
} 
%} 

text    [a-zA-Z][a-zA-Z0-9]* 

%% 

\n\s*    return 'NEWLINE'; 
[^\S\n]+   ; // ignore whitespace other than newlines 
"."     return '.'; 
","     return ','; 
"-"     return '-'; 
"="     return '='; 
"=>"    return '=>'; 
"<="    return '<='; 
"["     return '['; 
"settings]"   return 'SETTINGS'; 
"tables]"   return 'TABLES'; 
"relationships]" return 'RELATIONSHIPS'; 
"]"     return ']'; 
{text}    return 'TEXT'; 
<<EOF>>    return 'EOF'; 

/lex 

%left ',' 

%start source 

%% 

source 
    : content EOF 
     { 
      console.log(yy.regions); 
      console.log("\n" + JSON.stringify(yy.regions)); 
      return yy.regions; 
     } 
    | NEWLINE content EOF 
     { 
      console.log(yy.regions); 
      console.log("\n" + JSON.stringify(yy.regions)); 
      return yy.regions; 
     } 
    | NEWLINE EOF 
    | EOF 
    ; 

content 
    : '[' section content 
    | '[' section 
    ; 

section 
    : SETTINGS NEWLINE settings_content 
    | TABLES NEWLINE tables_content 
    | RELATIONSHIPS NEWLINE relationships_content 
    ; 

settings_content 
    : settings_line NEWLINE settings_content 
    | settings_line NEWLINE 
    | settings_line 
    ; 

settings_line 
    : text '=' text 
     { yy.regions.settings[$1] = $3; } 
    ; 

tables_content 
    : tables_line NEWLINE tables_content 
    | tables_line NEWLINE 
    | tables_line 
    ; 

tables_line 
    : table_name 
     { yy.regions.tables.push({ name: $table_name, fields: [] }); } 
    | field_list 
     { 
      var tableCount = yy.regions.tables.length; 
      var tableIndex = tableCount - 1; 
      yy.regions.tables[tableIndex].fields.push($field_list); 
     } 
    ; 

table_name 
    : '-' text 
     { $$ = $text; } 
    ; 

field_list 
    : text 
     { $$=[]; $$.push($text); } 
    | field_list ',' text 
     { $field_list.push($text); $$ = $field_list; } 
    ; 

relationships_content 
    : relationships_line NEWLINE relationships_content 
    | relationships_line NEWLINE 
    | relationships_line 
    ; 

relationships_line 
    : relationship_key '=>' relationship_key 
     { 
      yy.regions.relationships.push({ 
       pkTable: $1, 
       fkTable: $3 
      }); 
     } 
    | relationship_key '<=' relationship_key 
     { 
      yy.regions.relationships.push({ 
       pkTable: $3, 
       fkTable: $1 
      }); 
     } 
    ; 

relationship_key 
    : text '.' text 
     { $$ = { name: $1, field: $3 }; } 
    | text 
     { $$ = { name: $1 }; } 
    ; 

text 
    : TEXT 
     { $$ = $TEXT; } 
    ; 

Es verwendet wird, diese Art von Code zu analysieren:

[settings] 
DefaultFieldType = string 

[tables] 
-table1 
id, int, PK 
username, string, NULL 
password, string 

-table2 
id, int, PK 
itemName, string 
itemCount, int 

[relationships] 
table1 => table2 
foo.test => bar.test2 

in diese Art von JSON:

{ settings: { DefaultFieldType: 'string' }, 
    tables: 
    [ { name: 'table1', fields: [Object] }, 
    { name: 'table2', fields: [Object] } ], 
    relationships: 
    [ { pkTable: [Object], fkTable: [Object] }, 
    { pkTable: [Object], fkTable: [Object] } ] } 

ich aber don‘ t bekomme Syntaxfehler. Als ich nach Jison demo gehen und versuchen 5*PI 3^2 zu analysieren, erhalte ich folgende Fehlermeldung:

Parse error on line 1: 
5*PI 3^2 
-----^ 
Expecting 'EOF', '+', '-', '*', '/', '^', ')', got 'NUMBER' 

, die erwartet wird. Aber wenn ich ändern die letzte Zeile des Codes, die ich möchte von analysieren:

foo.test => bar.test2 

um so etwas wie

foo.test => a bar.test2 

ich die folgende Fehlermeldung erhalten:

throw new _parseError(str, hash); 
    ^
TypeError: Function.prototype.toString is not generic 

ich das verfolgt zu dem erzeugten Parser-Code, der wie folgt aussieht:

if (hash.recoverable) { 
    this.trace(str); 
} else { 
    function _parseError (msg, hash) { 
     this.message = msg; 
     this.hash = hash; 
    } 
    _parseError.prototype = Error; 

    throw new _parseError(str, hash); 
} 

Das führt mich zu der Annahme, dass etwas nicht stimmt, wie ich meinen Code strukturiert habe und wie ich mit Parsing umgegangen bin, aber ich habe keine Ahnung, was das sein könnte.

Es scheint, als ob es etwas mit error recovery zu tun haben könnte. Wenn das richtig ist, wie soll das verwendet werden? Soll ich die 'error'-Regel nach oben zu jedem Element bis zum Quellstamm hinzufügen?

Antwort

1

Ihre Grammatik scheint auf der Jison-Demoseite wie erwartet zu funktionieren, zumindest mit dem von mir verwendeten Browser (Firefox 46.0.1). Aus der Menge der Aktivität in der git-Repository um den Code, den Sie zitieren, vermute ich, dass die Version von Jison Sie verwenden einen der Fehler hat:

I denke, die Jison-Version auf der Demo-Seite ist älter, nicht neuer, also, wenn das Ergreifen des aktuellen Codes von Github nicht funktioniert, könnten Sie versuchen, eine ältere Version zu verwenden.

Verwandte Themen