Как сгруппировать непустые строки с PEG.js

Я пытаюсь проанализировать файл категорий с PEG.js

Как я могу сгруппировать категории (набор непустых строк, за которыми следует пустая строка)

stopwords:fr:aux,au,de,le,du,la,a,et,avec

synonyms:en:flavoured, flavored

synonyms:en:sorbets, sherbets

en:Artisan products
fr:Produits artisanaux

< en:Artisan products
fr:Gressins artisanaux

en:Baby foods
fr:Aliments pour bébé, aliment pour bébé, alimentation pour bébé, aliment bébé, alimentation bébé, aliments bébé

< en:Baby foods
fr:Céréales pour bébé, céréales bébé

< en:Whisky
fr:Whisky écossais
es:Whiskies escoceses
wikipediacategory:Q8718387

Сейчас я могу анализировать построчно этот код:

start = stopwords* synonyms* category+

language_and_words = l:[^:]+ ":" w:[^\n]+ {return {language: l.join(''), words: w.join('')};}

stopwords = "stopwords:" w:language_and_words "\n"+ {return {stopwords: w};}

synonyms = "synonyms:" w:language_and_words "\n"+ {return {synonyms: w};}

category_line = "< "? w:language_and_words "\n"+ {return w;}

category = c:category_line+ {return c;}

Я получил:

{
    "language": "en",
    "words": "Artisan products"
},
{
    "language": "fr",
    "words": "Produits artisanaux"
}

но я хочу (для каждой группы):

{
    {
        "language": "en",
        "words": "Artisan products"
    },
    {
        "language": "fr",
        "words": "Produits artisanaux"
    }
}

Я тоже это попробовал, но он не группировался, и я получил \n в начале некоторых строк.

category_line = "< "? w:language_and_words "\n" {return w;}

category = c:category_line+ "\n" {return c;}

2 ответа

Решение

Я нашел частичное решение:

start = category+

word = c:[^,\n]+ {return c.join('');}

words = w:word [,]? {return w.trim();}

parent = p:"< "? {return (p !== null);}

line = p:parent w:words+ "\n" {return {parent: p, words: w};}

category = l:line+ "\n"? {return l;}

Я могу разобрать это...

< fr:a,b
fr:aa,bb

en:d,e,f
fr:dd,ee, ffff

и сгруппировать:

[
    [ {...}, {...} ],
    [ {...}, {...} ]
]

Но есть проблема с "lang:" в начале каждой категории, если я пытаюсь разобрать "lang:" мои категории не сгруппированы...

Я считаю, что полезно итеративно разбивать синтаксический анализ (декомпозиция проблемы, old-school a la Wirth). Вот частичное решение, которое, я думаю, направит вас в правильном направлении (я не разбирал Line элементы категорий.

start = 
  stopwords 
  synonyms 
  category+

category "category"
  = category:(Line)+ categorySeparator { return category }

stopwords "stopwords"
  = stopwordLine*

stopwordLine "stopword line"
  = stopwordLine:StopWordMatch EndOfLine* { return stopwordLine }

StopWordMatch 
  = "stopwords:" match:Text { return match }

synonyms "stopwords"
  = synonymLine*

synonymLine "stopword line"
  = synonymLine:SynonymMatch EndOfLine* { return synonymLine }

SynonymMatch 
  = "synonyms:" match:Text { return match }

Line "line"
  = line:Text [\n] { return line }

Text "text"
  = [^\n]+ { return text() }

EndOfLine "(end of line)"
  = '\n'

EndOfFile 
  = !. { return "EOF"; }

categorySeparator "separator"
  = EndOfLine EndOfLine* / EndOfLine? EndOfFile

Я использую смешанный случай произвольно и не очень стильно. Есть также способ сохранить решения в Интернете: http://peg.arcanis.fr/2WQ7CZ/

Другие вопросы по тегам