0

これは私が持っているコードです:

%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; }
    ;

この種のコードを解析するために使用されます。

[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

この種の JSON に:

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

ただし、構文エラーは発生しません。Jison デモに移動して解析しようとすると5*PI 3^2、次のエラーが発生します。

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

これは期待されています。しかし、解析したいコードの最後の行を変更すると:

foo.test => bar.test2

のようなものに

foo.test => a bar.test2

次のエラーが表示されます。

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

これを、次のような生成されたパーサー コードまでたどりました。

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);
}

したがって、これにより、コードの構造と解析の処理方法に何か問題があると信じるようになりますが、それが何であるかはわかりません。

エラー回復と関係があるようです。それが正しい場合、それはどのように使用されることになっていますか? ソース ルートに至るまで、すべての要素に「エラー」ルールを上向きに追加する必要がありますか?

4

1 に答える 1

1

あなたの文法は、少なくとも私が使用しているブラウザー (Firefox 46.0.1) では、Jison のデモ ページで期待どおりに動作しているようです。引用したコードに関する git リポジトリ内のアクティビティの量から、使用している jison のバージョンにバグの 1 つがあると思われます。

デモ ページの jison バージョンは新しいものではなく、古いものだと思います。そのため、github から現在のコードを取得してもうまくいかない場合は、古いバージョンを使用してみてください。

于 2016-06-01T17:42:26.677 に答える