Hard Light Productions Forums

FreeSpace Releases => Scripting Releases => Topic started by: X3N0-Life-Form on February 10, 2015, 11:07:24 am

Title: [RELEASE] FS-style table parser v1.0
Post by: X3N0-Life-Form on February 10, 2015, 11:07:24 am
Greetings, fellow modders

Earlier this year, I started working on a script capable of parsing text files written in the style of Freespace tables. This idea was to have a generic parser that would allow me to read config files for other scripts.

Source code is available here (https://raw.githubusercontent.com/X3N0-Life-Form/AVPoV/master/data/scripts/parse.lua).

How to use it:

Put parse.lua in data/scripts.

In data/tables/init-sct.tbm, under #Conditional Hooks:
Code: [Select]
$On Game Init: [[parse.lua]]

Call the function parseTableFile(filePath, fileName) on a $On Game Init: hook, and store its results in a variable. The resulting data is basically a big multi-dimensional lua table:
Note: the things in yellow can be change to whatever you want.


 
Since this structure is a bit difficult to manipulate, I recommend splitting that big blob into sub tables or objects or whatever you feel comfortable with. Note that the script doesn't check the type of the parsed data, or whether a required attribute is present or not.

Examples:
 
I currently have 3 different scripts that use this parser for their config data, so here are a few code samples on how to use it. Note: these are code samples, meaning that they are missing several vital components.


mission-wide ship variant
Here we have a fairly simple table, with multiple categories, each entry has a single attribute, "Variant" with an optional sub-attribute, "Wing". The script function takes a category name, then processes each entry in that category.

Table:
Code: [Select]
#12th Vasudan BG

; Hatshepsut class
$Name: Apep
$Variant: Combat

; Typhon class
$Name: Pharaoh
$Variant: Combat Refit

; Sobek class
$Name: Blade
$Variant: Standard
+Wing: 2

#End

#A01.fs2

; Rakshasa class
$Name: Haagenti
$Variant: Strike Cruiser

#End

Script:
Code: [Select]
shipVariantMissionsTable = parseTableFile("data/config/", "ship_variant_missions.tbl")

function setShipVariants(categoryName)
if not (shipVariantMissionsTable[categoryName] == nil) then
for shipName, attributes in pairs(shipVariantMissionsTable[categoryName]) do
local variantName = attributes['Variant']['value']

-- if this is a single ship
if (attributes['Variant']['sub']['Wing'] == nil) then
setVariant(shipName, variantName)
else -- or if this is a wing
local wingSize = attributes['Variant']['sub']['Wing']
for i = 1, i <= wingSize, i = i + 1 do
setVariant(shipName.." "..i, variantName)
end
end

end
else
ba.warning("[shipVariantMissions.lua] Could not find entry "..categoryName)
end
end

auto ssm strikes
Here we a table with a single category. Each entry has two required attributes, "Type" and "Cooldown", one of which accepts either a single value or a list of values, and an optional attribute, "Default Seeking Algorithm". The script sample splits the parsed data into a bunch of one-dimensional tables to make them easier to use afterwards.

Table:
Code: [Select]
#Automated Strikes

$Name: rr-barrage ; required
$Type: Shivan SSM Barrage ; required, must match ssm.tbl entry
$Cooldown: 22 ; required
$Default Seeking Algorithm: round-robin ; optional, defaults to list

$Name: moloch-std
$Type: Shivan SSM Strike
$Cooldown: 24, 20, 17, 15, 13

$Name: moloch-std-insane
$Type: Shivan SSM Strike
$Cooldown: 13

$Name: moloch-std-hard
$Type: Shivan SSM Strike
$Cooldown: 15

$Name: moloch-std-medium
$Type: Shivan SSM Strike
$Cooldown: 17

$Name: moloch-std-easy
$Type: Shivan SSM Strike
$Cooldown: 20

$Name: moloch-std-very-easy
$Type: Shivan SSM Strike
$Cooldown: 24

#End

Script:
Code: [Select]
auto_ssm_table = parseTableFile(auto_ssm_filePath, auto_ssm_fileName)
dPrint_autoSSM(getTableObjectAsString(auto_ssm_table))

local id = 0
for name, attributes in pairs(auto_ssm_table['Automated Strikes']) do
-- record the strike's id
strike_info_id[id] = name
dPrint_autoSSM("Name="..name.."\n")

-- for each attribute
for attribute, prefix in pairs(attributes) do
value = prefix['value']
if not (type(value) == 'table') then
dPrint_autoSSM("attribute="..attribute.."; value="..value.."\n")
else
local str = ""
for index, val in pairs(value) do
str = str..val.." "
end
dPrint_autoSSM(str.."\n")
end

-- store this attribute in the relevant array
if (attribute == "Type") then
strike_info_type[name] = value
elseif (attribute == "Cooldown") then
strike_info_cooldown[name] = value
elseif (attribute == "Default Seeking Algorithm") then
strike_info_seeker_algo[name] = value
else
ba.warning("[autoSSM.lua] Unrecognised attribute "..attribute.."\n");
end
end

-- increment id count
id = id + 1
end


I am open to suggestions, remarks, questions regarding both this script and the way it is presented in this thread (in other words: I'm not sure if I'm explaining things properly here).
Title: Re: [WiP - Beta] FS-style table parser
Post by: mjn.mixael on February 10, 2015, 11:09:13 am
I'm curious what you're using this for.
Title: Re: [WiP - Beta] FS-style table parser
Post by: X3N0-Life-Form on February 10, 2015, 11:24:01 am
I'm planning on using it for two things right now: an automated SSM strike framework that's still in the works, and for the ship variant script I released earlier this year.

I figured that since I would have at least two data files I need to parse, and that the existing parsing logic and format of the ship variant thing was crap, I might as well rewrite a generic parser, standardize my script data a bit and make it easier to read and use for FSO modders. That way, I could re-use the parsing logic for whatever I want in the future.
Title: Re: [WiP - Beta] FS-style table parser
Post by: mjn.mixael on February 10, 2015, 11:29:51 am
Neat. Axem should take note of this for his scripts like System Viewer and Journal... (Yeah, Axem, I said it again. I hate your JSON tables. :p )
Title: Re: [WiP - Beta] FS-style table parser
Post by: Axem on February 14, 2015, 08:46:02 am
Yeah, it would be simpler for people to edit but if I did make a switch over, I'd have to ask for a way to put data into numerical arrays real easy.

For instance defining the color of something would be easier to go

$Color: 128,128,128,192

rather than

$Color:
+R: 128
+G: 128
+B: 128
+A: 192

So if there where comma delimiting allows entries to go into a numerical based table, that would be so neat.
Title: Re: [WiP - Beta] FS-style table parser
Post by: X3N0-Life-Form on February 14, 2015, 01:38:29 pm
I'll add that to the TODO list then.
Title: Re: [WiP - Beta] FS-style table parser
Post by: X3N0-Life-Form on February 15, 2015, 10:45:33 am
:bump:
Updated the script so that it stuffs comma delimited values into tables.
Title: Re: [WiP - Beta] FS-style table parser
Post by: Axem on February 15, 2015, 05:58:34 pm
Okay, I have a few questions now on how it works with regards to sub-attributes.

So you have this...
Code: [Select]
$Attribute2: attribute 2 value
+sub attribute: sub value

which is supposed to generate this...

Code: [Select]
tab['entry name']['Attribute2'] = attribute 2 value
tab['entry name']['Attribute2']['sub']['sub attribute'] = sub value

Where does that 'sub' come from? Is that something the script generates?

And I'd like to be able to do this...
Code: [Select]
$AI:
  +MinCloak: 50
  +ActionTimeout: 10

Where it would generate...

Code: [Select]
tab['entry name']['AI'] = table (object only)
tab['entry name']['AI']['MinCloak'] = 50
tab['entry name']['AI']['ActionTimeout'] = 10

Possible maybe?
Title: Re: [WiP - Beta] FS-style table parser
Post by: X3N0-Life-Form on February 19, 2015, 07:49:37 am
Ugh, looks like I need to rethink my attribute/sub attribute handling a tiny bit. I don't have time to do that this week (or probably even next week), but the idea I have right now would be to have something like this:

Code: [Select]
$Attribute name: some value     ==>    table['entry name']['Attribute name']['value']       = some value
  +sub1: other value            ==>    table['entry name']['Attribute name']['sub']['sub1'] = other value
  +sub2: yet another value      ==>    table['entry name']['Attribute name']['sub']['sub2'] = yet another value
Title: Re: [WiP - Beta] FS-style table parser
Post by: X3N0-Life-Form on March 07, 2015, 04:46:14 am
Alright, since I'm obviously not going to have much spare time to work on FSO modding stuff, I've decided to take 10-15 minutes of my time to try and cook up something.
The modified script basically work as described in the post above: $Attribute: value results in ['Attribute']['value'] = value.

Note that it's received rather extensive testing (read: "launching the game to see if something chokes up on parsing"), so I'm still flagging this as beta for now.

EDIT - yup, it seems to be pretty broken right now

EDIT 2 - Should have been fixorized now. I'm probably going to review the category system before pushing out a 1.0.
Title: Re: [RELEASE] FS-style table parser v1.0
Post by: X3N0-Life-Form on November 10, 2015, 02:59:57 pm
Bumping for 1.0 release, see first post (http://www.hard-light.net/forums/index.php?topic=89168.msg1776654#msg1776654).
Title: Re: [RELEASE] FS-style table parser v1.0
Post by: Admiral MS on November 10, 2015, 04:31:01 pm
If this had been available 4 years ago I probably would have used it for my ship save/load script instead of that mess I ended up coding myself.
When I think about it adding reversed read functions as write functions would be enough. The script already creates one large table for each ship anyway.