javascript
  • parsing
  • grammar
  • jison
  • 2015-02-09 25 views 0 likes 
    0

    我正在嘗試創建一個簡單的腳本語言。對於一開始我只是想的東西一樣用簡單的jison語法解析錯誤

    i = 5; 
    i += 3; 
    out(i); 
    

    所以我創建了下面的文法jison:

    %lex 
    %% 
    
    \s+     { /* ignore */ } 
    
    "="     { return '='; } 
    "+="     { return '+='; } 
    "-="     { return '-='; } 
    "*="     { return '*='; } 
    "/="     { return '/='; } 
    
    "."     { return '.'; } 
    "("     { return '('; } 
    ")"     { return ')'; } 
    "{"     { return '{'; } 
    "}"     { return '}'; } 
    
    [0-9]+    { return 'NUMBER'; } 
    [A-Z]*    { return 'CHAR_SEQUENCE'; } 
    
    <<EOF>>    { return 'EOF'; } 
    
    /lex 
    
    %% 
    
    Program 
        : StatementList EOF 
         { 
          return function() 
          { 
           for(var i = 0; i < $1.length; i++) 
           { 
            $1[i](); 
           } 
          }; 
         } 
        ; 
    
    StatementList 
        : StatementList Statement 
         { $$ = $1.concat($2); } 
        | 
         { $$ = []; } 
        ; 
    
    Statement 
        : AssignStatement 
        | VariableOutput 
        ; 
    
    Operator 
        : "=" 
         { $$ = function(left, right) { left.set(right); }; } 
        | "+=" 
         { $$ = function(left, right) { left.add(right); }; } 
        | "-=" 
         { $$ = function(left, right) { left.remove(right); }; } 
        | "*=" 
         { $$ = function(left, right) { left.multiplicate(right); }; } 
        | "/=" 
         { $$ = function(left, right) { left.divide(right); }; } 
        ; 
    
    
    VariableOutput 
        : 'out(' CHAR_SEQUENCE ')' ';' 
         { 
          $$ = function() 
          { 
           var t = new Tellraw("Output: "); 
           t.extra.push(vars[$1].toTellrawExtra()); 
           t.tell(new Entities.Player("@a")); 
          }; 
         } 
        ; 
    
    AssignStatement 
        : CHAR_SEQUENCE Operator CHAR_SEQUENCE ';' 
         { 
          $$ = function() 
          { 
           Util.assert(typeof vars[$3] != 'undefined', "Unknown identifier '"+$3+"'"); 
    
           if(typeof vars[$1] == 'undefined') 
            vars[$1] = vars[$3].constructor.call(); 
    
           $2(vars[$1], vars[$3]); 
          }; 
         } 
        | CHAR_SEQUENCE Operator '"' CHAR_SEQUENCE '"' ';' 
         { 
          $$ = function() 
          { 
           if(typeof vars[$1] == 'undefined') 
            vars[$1] = new Runtime.String($3); 
    
           $2(vars[$1], $3); 
          }; 
         } 
        | CHAR_SEQUENCE Operator NUMBER ';' 
         { 
          $$ = function() 
          { 
           if(typeof vars[$1] == 'undefined') 
            vars[$1] = new Runtime.Integer($3); 
    
           $2(vars[$1], $3); 
          }; 
         } 
        ; 
    

    它生成解析器不抱怨的語法。我的問題是,當我做

    parser.parse('i=5;out(i);')(); 
    

    我得到這個錯誤

    Parse error on line 1: 
    i = 5;out(i); 
    ^ 
    Expecting '=', '+=', '-=', '*=', '/=', got 'CHAR_SEQUENCE' 
    

    這完全混淆了我:/沒有規則,起初預計的運營商。期望操作符的唯一規則是AssignStatements,但它們都期望CHAR_SQUENCE作爲第一個對象。

    我做錯了什麼?或者爲什麼它不起作用? 如果您需要任何進一步的信息,隨意問:)

    回答

    1

    您期待iCHAR_SEQUENCE,但CHAR_SEQUENCE[A-Z]*,也就是說,只有大寫字母。您可能需要諸如[A-Za-z_][A-Za-z_0-9]*之類的東西。所以詞法分析器根本不認可i

    但是,它識別出一個空的CHAR_SEQUENCE。在jison中,與flex不同,可以匹配空字符串的模式將這樣做,並且幾乎總是應該避免。

    +0

    謝謝你現在的作品:) – M4GNV5 2015-02-09 16:52:41

    0

    是否有可能,當你使用

    [A-Z]*    { return 'CHAR_SEQUENCE'; } 
    

    *代替+你正在考慮的空字符串作爲CHAR_SEQUENCE然後解析器找到兩個CHAR_SEQUENCE而不是一個?

    相關問題