我有一個規則試圖解析所有數字或帶引號的字符串第一,如果失敗,然後將該東西作爲一個字符串。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);
}
*/
我認爲檢查字符尾部的''數字'是一個數字分隔符(而不是一個字母)也可以工作,而且更便宜。 – Apalala
@阿帕拉啊,那是個好主意。如果您將它添加爲答案,它會贊成。 – chakrit
在[Grako](https://bitbucket.org/apalala/grako)我在每個字母數字標記之後添加了一個(可選)自動檢查alphanums。當流標識爲「IDENTIFICATION」時,它避免了匹配「ID」。到目前爲止,我還沒有把它關掉。 – Apalala