regular-grammar
Advanced tools
Comparing version 0.0.5 to 0.1.0
{ | ||
"name": "regular-grammar", | ||
"version": "0.0.5", | ||
"version": "0.1.0", | ||
"description": "A simple regular grammar/parser generator", | ||
@@ -5,0 +5,0 @@ "author": "Victor Grishchenko <victor.grishchenko@gmail.com>", |
14
print.js
"use strict"; | ||
const grammar = require('.'); | ||
let IM ='abcdefgh'; | ||
for(let i=0; i<20; i++) | ||
IM = IM+IM; | ||
for(let key in grammar._parsers) | ||
console.log(key+" parser is", grammar._parsers[key]); | ||
const re = /abcdefgh/g; | ||
//let c = 0, m; | ||
//while ( m=re.exec(IM) ) | ||
// c++; | ||
const m = IM.match(re); | ||
console.log(m.length); |
@@ -8,2 +8,3 @@ /** The class generates regex _parsers for simple regular languages | ||
this._rules = rules; | ||
this._rules.EMPTY = new RegExp(); | ||
// {RULE: regex_str} | ||
@@ -17,2 +18,3 @@ this._parsers = Object.create(null); | ||
} | ||
this._patterns.EMPTY = ''; | ||
this._splitters = Object.create(null); | ||
@@ -28,3 +30,3 @@ } | ||
const m = splitter.exec(text); | ||
return m && m[0].length === text.length; | ||
return m !== null && m[0].length === text.length; | ||
} | ||
@@ -45,8 +47,17 @@ | ||
while (m = Grammar.TRIPLET_RE.exec(rule)) { | ||
if (m[0].length === 0) { | ||
Grammar.TRIPLET_RE.lastIndex = m.index + 1; | ||
continue; | ||
} | ||
const formula = m[0]; | ||
const marker = m[2] ? m[2] : (m[1] || ''); | ||
const rule = m[3] || 'EMPTY'; | ||
const quantifier = m[4] || ''; | ||
const repeating = m[4] !== undefined && (m[4] === '*' || m[4] === '+' || m[4][0] === '{'); | ||
const triplet = { | ||
formula: m[0], | ||
marker: m[1] || '', | ||
rule: m[2], | ||
quantifier: m[3] || '', | ||
repeating: m[3] === '*' || m[3] === '+', | ||
formula, | ||
marker, | ||
rule, | ||
quantifier, | ||
repeating, | ||
}; | ||
@@ -79,24 +90,51 @@ ret.push(triplet); | ||
triplet_re (t) { | ||
let ret = sterilize(this.pattern(t.rule)); | ||
const q = t.quantifier === '?' ? '?' : ''; | ||
let m = t.marker; | ||
if (m.length === 1) { | ||
m = '\\' + m; | ||
} | ||
if (!t.repeating) { | ||
if (t.marker.length > 1) { | ||
ret = '(' + m + '\\s*' + ret + ')' + q; | ||
} else if (q === '?') { | ||
ret = '(?:' + (m ? m + '\\s*' : '') + '(' + ret + '))' + q; | ||
} else { | ||
ret = m + '(' + ret + ')'; | ||
} | ||
} else { | ||
ret = '((?:' + m + '\\s*' + ret + '\\s*)' + t.quantifier + ')'; | ||
} | ||
return ret; | ||
} | ||
pattern (rule_name) { | ||
if (rule_name in this._patterns) { return this._patterns[rule_name]; } | ||
const triplets = this.triplets(rule_name); | ||
const is_chain = triplets.every(t => t.quantifier !== '|'); | ||
const pattern = triplets.map((t) => { | ||
let ret = sterilize(this.pattern(t.rule)); | ||
if (t.marker.length > 1) { | ||
ret = t.marker + ret; | ||
// detect chains, strip |, make regex | ||
let joined = ''; | ||
let chain = true; | ||
triplets.forEach((t) => { | ||
const p = this.triplet_re(t); | ||
if (chain) { | ||
if (t.quantifier === '|') { | ||
joined += '(?:'; | ||
chain = false; | ||
} else { | ||
if (joined) { | ||
joined += '\\s*'; | ||
} | ||
} | ||
joined += p; | ||
} else { | ||
joined += '|' + p; | ||
if (t.quantifier !== '|') { | ||
joined += ')'; | ||
chain = true; | ||
} | ||
} | ||
if (!t.repeating) { ret = '(' + ret + ')'; } | ||
if (t.marker.length === 1) { | ||
ret = '\\' + t.marker + ret; | ||
} | ||
if (t.quantifier && t.quantifier !== '|') { | ||
ret = '(?:' + ret + ')' + t.quantifier; | ||
} | ||
if (t.repeating) { | ||
ret = '(' + ret + ')'; | ||
} | ||
return ret; | ||
}); | ||
this._patterns[rule_name] = pattern.join(is_chain ? '\\s*' : '|'); | ||
this._patterns[rule_name] = joined; | ||
@@ -143,3 +181,3 @@ return this._patterns[rule_name]; | ||
Grammar.TRIPLET_RE = /(\[.*?\]|[^A-Za-z0-9\s]?)([A-Z][A-Z0-9_]+)([*+?|]?)/g; | ||
Grammar.TRIPLET_RE = /(\[.*?\]|"([^"]+)"|[^A-Za-z0-9\s])?([A-Z][A-Z0-9_]*)?([*+?|]|{\d+(?:,\d+)?})?/g; | ||
@@ -146,0 +184,0 @@ function sterilize (pattern) { |
const tap = require('tape'); | ||
const Grammar = require('..'); | ||
const SWARM_GRAMMAR_RULES = { | ||
const SWARM_GRAMMAR_RULES = { // swarm 1.9.99 grammar :) | ||
@@ -14,3 +14,3 @@ NUMBER: /\d+(\.\d+([eE]-?\d+)?)?/, | ||
SPEC: 'ID? .ID? @ID? :ID?', | ||
CONSTANT: 'NUMBER| STRING| >ID| EMPTY|', | ||
CONSTANT: 'NUMBER| STRING| >ID| EMPTY', | ||
@@ -66,3 +66,3 @@ RUN: 'INT /BASE? [+%-]INT?', | ||
tap.ok(grammar.is(' 0\n+0 ', 'ID')); | ||
tap.notOk(grammar.is('0+ 0', 'ID')); | ||
tap.ok(grammar.is('0+ 0', 'ID')); | ||
// tap.ok( grammar.is('{a:1, b: "two " }', 'MAP'), 'the MAP type' ); | ||
@@ -122,3 +122,3 @@ | ||
tap('grammar.01.E benchmark', (tap) => { | ||
const event_str = '#object+author.json@sometime+origin:field="value"'; | ||
const event_str = '#object+author.json@sometime+origin:field="value"\n'; | ||
let mln_str = ''; | ||
@@ -125,0 +125,0 @@ const ev_count = 100000; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
42654
17
352