2013-04-18 16 views
0

我有一個​​規則試圖解析所有數字或帶引號的字符串第一,如果失敗,然後將該東西作爲一個字符串。PEGjs:回退(回溯?)爲字符串,如果浮點規則失敗

DUD 123abc

哪些失敗Expected " ", "." or [0-9] but "a" found.錯誤解析:除了這是非常具體的字符串一個特定的情況下

一切分析的罰款。

我期望的是:它應該成功解析並返回字符串「123abc」作爲字符串原子。您可以在下面的語法內容中看到我的一些不成功的嘗試。

任何幫助/提示/指針/建議表示讚賞!


您可以試試online PEG.js version的語法。我使用節點v0.8.23和pegjs 0.7.0

數字,正確分析:

  • `123
  • `0
  • `0。
  • `1。
  • `0.23
  • `0.23
  • `1.23
  • `0.000
  • . < ---爲字符串,而不是數量,而不是錯誤

我想123abc被解析爲一個字符串,這可能嗎?


這是我整個語法文件:

start = lines:line+ { return lines; } 

// --------------------- LINE STRUCTURE 
line = command:command eol { return command; } 

command = action:atom args:(sep atom)* 
{ 
    var i = 0, len = 0; 

    for (var i = 0, len = args.length; i < len; i++) { 
    // discard parsed separator tokens 
    args[i] = args[i][1]; 
    } 

    return [action, args]; 
} 

sep = ' '+ 
eol = "\r"/"\n"/"\r\n" 

atom = num:number { return num; } 
    /str:string_quoted { return str; } 
    /str:string { return str; } 

// --------------------- COMMANDS 

// TODO: 

// --------------------- STRINGS 
string = chars:([^" \r\n]+) { return chars.join(''); } 

string_quoted = '"' chars:quoted_chars* '"' { return chars.join(''); } 
quoted_chars = '\\"' { return '"'; } 
      /char:[^"\r\n] { return char; } 

// --------------------- NUMBERS 
number = integral:('0'/[1-9][0-9]*) fraction:("." [0-9]*)? 
{ 
    if (fraction && fraction.length) { 
    fraction = fraction[0] + fraction[1].join(''); 
    } else { 
    fraction = ''; 
    } 

    integral = integral instanceof Array ? 
    integral[0] + integral[1].join('') : 
    '0'; 

    return parseFloat(integral + fraction); 
} 
     /("."/"0.") fraction:[0-9]+ 
{ 
    return parseFloat("0." + fraction.join('')); 
} 

/* 
float = integral:integer? fraction:fraction { return integral + fraction; } 

fraction = '.' digits:[0-9]* { return parseFloat('0.' + digits.join('')); } 

integer = digits:('0'/[1-9][0-9]*) 
{ 
    if (digits === '0') return 0; 
    return parseInt(digits[0] + digits[1].join(''), 10); 
} 

*/ 

回答

3

加入!([0-9\.]+[^0-9\.])這是排序number規則的前瞻盈的解決了這個。

我知道​​規則將匹配,所以它有效地做的是使number規則更快地失敗。希望這可以幫助未來模糊的案件。

所以數量規則現在變成了:

number = !([0-9\.]+[^0-9\.]) integral:('0'/[1-9][0-9]*) fraction:("." [0-9]*)?

+0

我認爲檢查字符尾部的''數字'是一個數字分隔符(而不是一個字母)也可以工作,而且更便宜。 – Apalala

+1

@阿帕拉啊,那是個好主意。如果您將它添加爲答案,它會贊成。 – chakrit

+1

在[Grako](https://bitbucket.org/apalala/grako)我在每個字母數字標記之後添加了一個(可選)自動檢查alphanums。當流標識爲「IDENTIFICATION」時,它避免了匹配「ID」。到目前爲止,我還沒有把它關掉。 – Apalala

1

我認爲檢查字符尾隨number是數分隔符(不是alphanum)將具有還曾和更便宜。

number = integral:('0'/[1-9][0-9]*) fraction:("." [0-9]*)? !([0-9A-Za-z]) 
相關問題