node.js - PEGjs: Fallback (backtrack?) to string if floating point rule fail -


i have atom rule tries parse either number or quoted string first, if fails, treat thing string.

everything parses fine except 1 particular case specific string:

dud 123abc

which fails parse expected " ", "." or [0-9] "a" found. error.

what expect: should parse , return string "123abc" string atom. can see several of unsuccessful attempts commented out in grammar content below.

any help/tips/pointers/suggestions appreciated!


you can try grammar on online peg.js version. i'm using node v0.8.23 , pegjs 0.7.0

numbers parses correctly:

  • `123
  • `0
  • `0.
  • `1.
  • `.23
  • `0.23
  • `1.23
  • `0.000
  • . <--- string, not number , not error

i want 123abc parsed string, possible?


this entire grammar file:

start = lines:line+ { return lines; }  // --------------------- line structure line = command:command eol { return command; }  command = action:atom args:(sep atom)* {   var = 0, len = 0;    (var = 0, len = args.length; < 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); }  */ 

solved adding !([0-9\.]+[^0-9\.]) sort of look-ahead infront of number rule.

i know atom rule match making number rule fails bit sooner. can helps ambiguous cases in future.

so number rule becomes:

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


Comments

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -