grammars for entries parsing now LALR(1), which is much faster
This commit is contained in:
@ -1,21 +1,26 @@
|
||||
start: title description property+ (_E note)? _E building
|
||||
start: title description property+ note? building
|
||||
title: "#" /(?! ).+(?<! )/ _NL // not starting or ending with a space
|
||||
|
||||
title: "#" /(?! ).+(?<! )/ "\n" _E // not starting or ending with a space
|
||||
|
||||
description: "_" /(?! ).+(?<![ _])/ "_\n" _E // single line not ending with underscore
|
||||
|
||||
note: /(?![\-#]).*\n/* // Unstructured text, not starting with - or #
|
||||
|
||||
building: "## Building\n" (_E property+)? (_E note)? // the "building" section
|
||||
|
||||
property: "-" _key ":" _values "\n"? // a property on a single line "- key: value"
|
||||
description: "_" /(?! ).+(?<![ _])/ "_" _NL // single line not ending with underscore
|
||||
property: "-" _key ":" _values _NL
|
||||
_key : /(?! ).+?(?=:)(?<! )/ // key: everything until next ":", not beginning or ending with a space
|
||||
_values: [_value ("," _value)*] // a comma separated list
|
||||
_value: quoted_value | unquoted_value // quoted or unquoted values
|
||||
_values : [_value ("," _value)*]
|
||||
_value : quoted_value | unquoted_value
|
||||
quoted_value : /\".+?\"/ // with quotation marks, can contain commas
|
||||
unquoted_value: /(?![ \"])[^,\n]+(?<![ ])/ // cannot contain commas, cannot start or end with quotation mark
|
||||
unquoted_value : /(?![ \"])[^,\n]+(?<![ \"])/ // cannot contain commas, cannot start or end with quotation mark
|
||||
|
||||
_E: /^$\n/m // empty new line
|
||||
note.3: /(?![\-#]).*\n/+ // Unstructured text, not starting with - or #
|
||||
|
||||
building: "## Building" _NL property* note? // the "building" section
|
||||
|
||||
|
||||
_NUMBER: /[0-9]+/
|
||||
|
||||
CR : /\r/
|
||||
LF : /\n/
|
||||
_NL : CR? LF
|
||||
WS : (" "|/\t/)+
|
||||
_EL.2 : /^$\n/m
|
||||
|
||||
%import common.WS
|
||||
%ignore WS
|
||||
%ignore _EL
|
||||
|
@ -1,6 +1,6 @@
|
||||
start: entry*
|
||||
entry: "##" name "[" _NUMBER "]\n" property+
|
||||
property: "-" _key ":" _values "\n"
|
||||
start: _COMMENT _HEADER entry*
|
||||
entry: "##" name "[" _NUMBER "]" _NL property+
|
||||
property: "-" _key ":" _values _NL
|
||||
_key : /(?! ).+?(?=:)(?<! )/ // key: everything until next ":", not beginning or ending with a space
|
||||
_values : [_value ("," _value)*]
|
||||
_value : quoted_value | unquoted_value
|
||||
@ -11,8 +11,13 @@ name: /(?! ).+?(?= \[)/ // developer name: everything until " ["
|
||||
|
||||
_NUMBER: /[0-9]+/
|
||||
|
||||
%import common.WS
|
||||
CR : /\r/
|
||||
LF : /\n/
|
||||
_NL : CR? LF
|
||||
WS : (" "|/\t/)+
|
||||
_EL : /^$\n/m
|
||||
_COMMENT : /^\[comment\]: #.*$\n/m // [comment]: # xxx
|
||||
_HEADER : /^# .+$\n/m
|
||||
|
||||
%ignore WS
|
||||
%ignore /^\[comment\]: #.*$\n/m // [comment]: # xxx
|
||||
%ignore /^# .+$\n/m // the line starting with "# "
|
||||
%ignore /^$\n/m // empty lines
|
||||
%ignore _EL
|
||||
|
@ -2,6 +2,7 @@
|
||||
Maintenance of inspirations.md and synchronization with the inspirations in the entries.
|
||||
"""
|
||||
|
||||
import time
|
||||
from utils import constants as c, utils, osg, osg_ui
|
||||
|
||||
|
||||
@ -33,8 +34,14 @@ if __name__ == "__main__":
|
||||
|
||||
|
||||
# assemble info
|
||||
t0 = time.process_time()
|
||||
entries = osg.read_entries()
|
||||
entries = osg.assemble_infos()
|
||||
print('took {}s'.format(time.process_time()-t0))
|
||||
t0 = time.process_time()
|
||||
# entries = osg.assemble_infos()
|
||||
osg.write_entries(entries)
|
||||
print('took {}s'.format(time.process_time()-t0))
|
||||
|
||||
|
||||
# assemble inspirations info from entries
|
||||
entries_inspirations = {}
|
||||
|
@ -37,8 +37,10 @@ essential_fields = ('Home', 'State', 'Keywords', 'Code repository', 'Code langua
|
||||
|
||||
# only these fields can be used currently (in this order)
|
||||
valid_fields = (
|
||||
'Home', 'Media', 'State', 'Play', 'Download', 'Platform', 'Keywords', 'Code repository', 'Code language',
|
||||
'Code license', 'Code dependencies', 'Assets license', 'Developer', 'Build system', 'Build instructions')
|
||||
'Home', 'Media', 'Inspirations', 'State', 'Play', 'Download', 'Platform', 'Keywords', 'Code repository', 'Code language',
|
||||
'Code license', 'Code dependencies', 'Assets license', 'Developer')
|
||||
|
||||
valid_building_fields = ('Build system', 'Build instructions')
|
||||
|
||||
# these are the only valid platforms currently (and must be given in this order)
|
||||
valid_platforms = ('Windows', 'Linux', 'macOS', 'Android', 'iOS', 'Web')
|
||||
|
@ -86,7 +86,7 @@ class EntryTransformer(lark.Transformer):
|
||||
"""
|
||||
if not x:
|
||||
raise lark.Discard
|
||||
return 'note', x[0].value
|
||||
return 'note', ''.join((x.value for x in x))
|
||||
|
||||
def building(self, x):
|
||||
d = {}
|
||||
@ -401,7 +401,7 @@ def read_and_parse(content_file: str, grammar_file: str, transformer: lark.Trans
|
||||
"""
|
||||
content = utils.read_text(content_file)
|
||||
grammar = utils.read_text(grammar_file)
|
||||
parser = lark.Lark(grammar, debug=False)
|
||||
parser = lark.Lark(grammar, debug=False, parser='lalr')
|
||||
tree = parser.parse(content)
|
||||
return transformer.transform(tree)
|
||||
|
||||
@ -565,7 +565,7 @@ def read_entries():
|
||||
# setup parser
|
||||
grammar_file = os.path.join(code_path, 'grammar_entries.lark')
|
||||
grammar = utils.read_text(grammar_file)
|
||||
parser = lark.Lark(grammar, debug=False)
|
||||
parser = lark.Lark(grammar, debug=False, parser='lalr')
|
||||
|
||||
# setup transformer
|
||||
transformer = EntryTransformer()
|
||||
@ -576,16 +576,20 @@ def read_entries():
|
||||
# iterate over all entries
|
||||
for file, _, content in entry_iterator():
|
||||
|
||||
print(file)
|
||||
if not content.endswith('\n'):
|
||||
content += '\n'
|
||||
|
||||
# parse and transform entry content
|
||||
try:
|
||||
tree = parser.parse(content)
|
||||
entry = transformer.transform(tree)
|
||||
except Exception as e:
|
||||
print(file)
|
||||
print(e)
|
||||
continue
|
||||
|
||||
# TODO check entry
|
||||
|
||||
# add file information
|
||||
entry['file'] = file
|
||||
|
||||
@ -594,6 +598,74 @@ def read_entries():
|
||||
|
||||
return entries
|
||||
|
||||
def write_entries(entries):
|
||||
"""
|
||||
|
||||
:return:
|
||||
"""
|
||||
|
||||
# iterate over all entries
|
||||
entries = entries[:20]
|
||||
for entry in entries:
|
||||
write_entry(entry)
|
||||
|
||||
def write_entry(entry):
|
||||
"""
|
||||
|
||||
:param entry:
|
||||
:return:
|
||||
"""
|
||||
# TODO check entry
|
||||
|
||||
# get path
|
||||
entry_path = os.path.join(entries_path, entry['file'])
|
||||
|
||||
# create output content
|
||||
content = create_entry_content(entry)
|
||||
|
||||
# write entry
|
||||
utils.write_text(entry_path, content)
|
||||
|
||||
|
||||
def create_entry_content(entry):
|
||||
"""
|
||||
|
||||
:param entry:
|
||||
:return:
|
||||
"""
|
||||
|
||||
# title and description
|
||||
content = '# {}\n\n_{}_\n\n'.format(entry['title'], entry['description'])
|
||||
|
||||
# now properties in the recommended order
|
||||
for field in valid_fields:
|
||||
field_name = field.lower()
|
||||
if field_name in entry:
|
||||
content += '- {}: {}\n'.format(field, ', '.join(entry[field_name]))
|
||||
content += '\n'
|
||||
|
||||
# if there is a note, insert it
|
||||
if 'note' in entry:
|
||||
content += entry['note'] + '\n'
|
||||
|
||||
# building header
|
||||
content += '## Building\n\n'
|
||||
|
||||
# building properties if present
|
||||
has_properties = False
|
||||
for field in valid_building_fields:
|
||||
field_name = field.lower()
|
||||
if field_name in entry['building']:
|
||||
has_properties = True
|
||||
content += '- {}: {}\n'.format(field, ', '.join(entry['building'][field_name]))
|
||||
|
||||
# if there is a note, insert it
|
||||
if 'note' in entry['building']:
|
||||
if has_properties:
|
||||
content += '\n'
|
||||
content += entry['building']['note'] + '\n'
|
||||
|
||||
return content
|
||||
|
||||
def compare_entries_developers(entries, developers):
|
||||
"""
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 0 A.D.
|
||||
|
||||
_0 A.D. is a free, open-source, cross-platform real-time strategy game._
|
||||
_Real-time strategy game._
|
||||
|
||||
- Home: https://play0ad.com/, https://sourceforge.net/projects/zero-ad/
|
||||
- Media: <https://en.wikipedia.org/wiki/0_A.D._(video_game)>
|
||||
|
@ -3,10 +3,11 @@
|
||||
_Clone of Achtung, die Kurve!, a simple skill game._
|
||||
|
||||
- Home: https://kurve.se/
|
||||
- Inspirations: "Achtung, die Kurve!"
|
||||
- State: mature
|
||||
- Play: https://kurve.se/
|
||||
- Platform: Web
|
||||
- Keywords: action, clone, inspired by "Achtung, die Kurve!", multiplayer local, open content
|
||||
- Keywords: action, clone, multiplayer local, open content
|
||||
- Code repository: https://github.com/SimonAlling/kurve.git
|
||||
- Code language: JavaScript
|
||||
- Code license: AGPL-3.0
|
||||
|
@ -1,10 +1,10 @@
|
||||
# Battles of Antargis
|
||||
|
||||
_A real-time-strategy (RTS) game, which is a mixture of 3 three games: Powermonger, Settlers, Warcraft._
|
||||
_A real-time-strategy (RTS) game._
|
||||
|
||||
- Home: https://plus.google.com/101003433246259562872,
|
||||
- Home: https://plus.google.com/101003433246259562872
|
||||
- State: beta, inactive since 2014
|
||||
- Keywords: strategy
|
||||
- Keywords: strategy, inspired by Powermonger + Settlers + Warcraft
|
||||
- Code repository: https://github.com/godrin/antargis.git
|
||||
- Code language: C, C++
|
||||
- Code license: GPL-2.0
|
||||
|
@ -3,8 +3,9 @@
|
||||
_Remake of Achtung, die Kurve!._
|
||||
|
||||
- Home: https://pwmarcz.pl/netacka/
|
||||
- Inspirations: "Achtung, die Kurve!"
|
||||
- State: mature
|
||||
- Keywords: remake, inspired by "Achtung, die Kurve!", skill
|
||||
- Keywords: remake, skill
|
||||
- Code repository: https://github.com/pwmarcz/netacka.git
|
||||
- Code language: C
|
||||
- Code license: MIT
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
_Multimedia library for Python._
|
||||
|
||||
- Home: http://pyglet.org/,
|
||||
- Home: http://pyglet.org/
|
||||
- State: mature
|
||||
- Download: https://pypi.org/project/pyglet/
|
||||
- Platform: Windows, Linux, macOS
|
||||
|
@ -1,10 +1,11 @@
|
||||
# Star-Wars-III
|
||||
|
||||
_Remake of Star Wars (1983 arcade game)._
|
||||
_Remake of Star Wars (1983) arcade game._
|
||||
|
||||
- Home: https://github.com/abhinandanramesh/Star-Wars-III
|
||||
- Inspirations: Star Wars (1983 arcade game)
|
||||
- State: mature, inactive since 2014
|
||||
- Keywords: arcade, inspired by "Star Wars (1983 arcade game)", remake, skill
|
||||
- Keywords: arcade, remake, skill
|
||||
- Code repository: https://github.com/abhinandanramesh/Star-Wars-III.git
|
||||
- Code language: Python
|
||||
- Code license: GPL-2.0
|
||||
|
@ -3,10 +3,11 @@
|
||||
_Remake of Survivor (1986)._
|
||||
|
||||
- Home: http://www.schillmania.com/survivor/
|
||||
- Inspirations: Survivor (1986)
|
||||
- State: mature
|
||||
- Play: http://www.schillmania.com/survivor/
|
||||
- Platform: Web
|
||||
- Keywords: remake, inspired by "Survivor (1986)"
|
||||
- Keywords: remake
|
||||
- Code repository: https://github.com/scottschiller/SURVIVOR.git
|
||||
- Code language: JavaScript
|
||||
- Code license: CC-BY-NC-3.0
|
||||
|
@ -4,8 +4,9 @@ _Remake of Where in the World Is Carmen Sandiego? (1985)._
|
||||
|
||||
- Home: https://github.com/Ponup/thiefcatcher
|
||||
- Media: <https://en.wikipedia.org/wiki/Where_in_the_World_Is_Carmen_Sandiego%3F_(1985_video_game)>
|
||||
- Inspirations: Where in the World Is Carmen Sandiego? (1985)
|
||||
- State: beta
|
||||
- Keywords: strategy, educational, inspired by "Where in the World Is Carmen Sandiego? (1985)", remake
|
||||
- Keywords: strategy, educational, remake
|
||||
- Code repository: https://github.com/Ponup/thiefcatcher.git
|
||||
- Code language: C++
|
||||
- Code license: GPL-3.0
|
||||
|
@ -3,10 +3,11 @@
|
||||
_Remake of a 2D multiplayer game similar to the Tron movie-themed light cycle games and snake games._
|
||||
|
||||
- Home: http://zatacka.sourceforge.net/, https://sourceforge.net/projects/zatacka/
|
||||
- Inspirations: "Achtung, die Kurve!"
|
||||
- State: beta, inactive since 2007
|
||||
- Download: http://zatacka.sourceforge.net/index.php?id=download, https://sourceforge.net/projects/zatacka/files/
|
||||
- Platform: Windows, Linux
|
||||
- Keywords: arcade, 2D, inspired by "Achtung, die Kurve!", multiplayer
|
||||
- Keywords: arcade, 2D, multiplayer
|
||||
- Code repository: http://zatacka.cvs.sourceforge.net (cvs)
|
||||
- Code language: C, C++
|
||||
- Code license: GPL-2.0
|
||||
|
@ -3,8 +3,9 @@
|
||||
_Remake of Achtung, die Kurve!._
|
||||
|
||||
- Home: https://github.com/simenheg/zatackax
|
||||
- Inspirations: "Achtung, die Kurve!"
|
||||
- State: beta
|
||||
- Keywords: action, inspired by "Achtung, die Kurve!", remake
|
||||
- Keywords: action, remake
|
||||
- Code repository: https://github.com/simenheg/zatackax.git
|
||||
- Code language: C
|
||||
- Code license: GPL-3.0
|
||||
|
Reference in New Issue
Block a user