Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Archived » B3 » b3 build files DSL in XText - annotaded sample b3 file
b3 build files DSL in XText - annotaded sample b3 file [message #491290] Wed, 14 October 2009 01:15 Go to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------050506050007010709020406
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi,
I have been working with a XText based DSL for the proposed b3 build
language for a week or so. I got fed up trying to describe the syntax on
the wiki - it felt like I should use a proper tool.

The experience using XText was very positive. I managed to get a default
editor up and running quikcly. I now have the majority of the wanted
features covered by the DSL.

Here follows the sample file that I use to test it. I added a bunch of
comments regarding what the statements are supposed to do.
Since I am trying to test every possible variation on syntax - the
sample is perhaps not the easiest read as it does not describe a build
of something - so all the names are just gibberish...

I think it is at a point where it meaningful to share though...

(I could do with some help on Xtext if there is someone out there that
would like to help with a few questions...)

regards
- henrik


--------------050506050007010709020406
Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0";
name="test1.b3"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="test1.b3"

LyoKKiogQSAuYjMgZmlsZQoqKiBjb25zaXN0cyBvZiBpbXBvcnQgc3RhdGVt ZW50cyBmb2xs
b3dlZCBieSBhIHNpbmdsZSAidW5pdCIuIFRoaXMgaXMgYW5hbG9nb3VzIHdp dGggYSAuamF2
YSBmaWxlIGhhdmluZyBpbXBvcnRzCioqIGFuZCBhIHNpbmdsZSBsYW5ndWFn ZSBlbGVtZW50
IChjbGFzcywgaW50ZXJmYWNlKS4KKioKKiogVGhpcyBmaWxlIGlzIGEgc2Ft cGxlciB1c2Vk
IHRvIHRlc3Qgc3ludGF4LiBUaGUgZXhhbXBsZXMgYXJlIG5vdCByZWFsaXN0 aWMgKHlvdSB3
aWxsIGZpbmQgcGxlbnR5IG9mIGEsIGIsIGMsIGZlZSBhbmQgZm9vLi4uKQoq LwoKLyoKKiog
Q09NTUVOVFMKKiogQm90aCBzaW5nbGUgbGluZSBhbmQgbXVsdGkgbGluZSBj b21tZW50cyBh
cmUgc3VwcG9ydGVkLgoqLwoJLy8gU2luZ2xlIGxpbmUgY29tbWVudAoJLyog TXVsdGkgbGlu
ZSBjb21tZW50CgkgKi8KCQovKiAKKiogSU1QT1JUCioqIElzIHVzZWQgdG8g aW1wb3J0IGNs
YXNzZXMgKGp1c3QgbGlrZSBpbiBqYXZhKS4gVGhpcyBpcyBkb25lIHNvIG5v biBxdWFsaWZp
ZWQgbmFtZXMgY2FuIGJlIHVzZWQgZm9yIGNsYXNzZXMKKiogRElTQ1VTUzog SW1wb3J0cyBh
cmUgcHJvYmFibHkgdHJhbnNsYXRlZCB0byBtZXRhIHJlcXVpcmVtZW50cyB3 aGVuIHJlc29s
dmluZy4gQXMgdGhleSBhcmUgcmVxdWlyZW1lbnRzIG9uIHRoZSBlbnZpcm9u bWVudC4KKi8K
aW1wb3J0IG9yZy5lY2xpcHNlLmIzLmRlZmF1bHQuUmVzb2x2ZXJzLio7Cgov KgoqKiBVTklU
CioqIEEgVW5pdCBpcyBhIEJ1aWxkIFVuaXQuIEl0IGlzIHVzZWQgZm9yIHNl dmVyYWwgcHVy
cG9zZXM6CioqIC0gYXMgYSBmaWxlIHRoYXQgZGVzY3JpYmVzICJ0b3AgbGV2 ZWwiIHJlcXVp
cmVtZW50cyAod2hhdCB0byBpbXBvcnQgaW50byBhIHdvcmtzcGFjZSwgcmVz b2x2ZXJzIHRv
IHVzZSBldGMuKQoqKiAtIGFzIGFkdmljZSB0aGF0IGV4dGVuZHMgbWV0YSBk YXRhIHRyYW5z
bGF0aW9uCioqIC0gYXMgdGhlIG1ldGEgZGF0YSB0aGF0IGRlc2NyaWJlcyBh IHVuaXQsIHdo
ZW4gdGhlcmUgaXMgbm8gb3RoZXIgbWV0YSBkYXRhCioqCioqIEEgVW5pdCBo YXM6CioqIC0g
UHJvcGVydGllcwoqKiAtIFByb3ZpZGVkIENhcGFiaWxpdGllcwoqKiAtIFJl cXVpcmVkIENh
cGFiaWxpdGllcyAoYW5kIE1ldGEgUmVxdWlyZWQgQ2FwYWJpbGl0aWVzKQoq KiAtIFBhcnRz
IChhbmFsb2dvdXMgd2l0aCBtZW1iZXJzIGluIGEgY2xhc3MpLiBUaGVyZSBh cmUgZm91ciBr
aW5kcyBvZiBwYXJ0czogCioqCQktIEFydGlmYWN0cyAoZXhpc3RpbmcgZmls ZXMpCioqCQkt
IEdyb3VwIChBZ2dyZWdhdGlvbiBvZiBvdGhlciBwYXJ0cykKKioJCS0gQWN0 aW9uIChQcm9k
dWN0aW9uIG9mIG5ldyBmaWxlcyAob3Igc2lkZSBlZmZlY3QpCioqCQktIFJl c3VsdCAoQSBz
ZXQgb2YgZmlsZXMgcHJvZHVjZWQgYnkgYW4gQWN0aW9uIH49IGdlbmVyYXRl ZCBBcnRpZmFj
dHMpCioqIC0gQWR2aWNlIChQYXRoL1ByZWRpY2F0ZSBiYXNlZCBhY2Nlc3Mg dG8gZWxlbWVu
dHMgdGhhdCBkbyBub3QgeWV0IGV4aXN0IGluIHRoZSBtb2RlbCkuIFVzZWQg dG8gc2V0IG9w
dGlvbnMsIG1ha2UKKioJIG92ZXJyaWRlcywgZXRjLgoqKiAtIFJlcG9zaXRv cmllcyAtIGEg
Y29uZmlndXJhdGlvbiB0aGF0IGlzIHVzZWQgdG8gcmVzb2x2ZSAobG9vayB1 cCkgdW5pdHMu
CioqIC0gU3luY2hyb25pemF0aW9uIC0gZGVmaW5lcyBtb25pdG9ycyBhY3Jv c3MgdW5pdHMg
dGhhdCBoZWxwIHNvbHZlIGlzc3VlcyBpbiBwYXJhbGxlbCBidWlsZHMKKioK KiogQSB1bml0
IGNhbiBiZSBtYXJrZWQgYXMgc3luY2hyb25pemVkIC0gdGhpcyBtZWFucyB0 aGF0IHJlcXVl
c3RzIHRvIGl0cyBwYXJ0cyBhcmUgc2VyaWFsaXplZC4KKiogQSB1bml0IGNh biBpbXBsZW1l
bnQgaW50ZXJmYWNlcy4gVGhlc2UgaW50ZXJmYWNlcyBhcmUgImJ1aWxkIHRp bWUgaW50ZXJm
YWNlcyIgYW5kIHRlbGxzIGIzIGFib3V0IAoqKiB3aGljaCBwYXJ0cyBpdCBj YW4gZXhwZWN0
LiBUaGlzIGFsc28gaGVscHMgYW4gYXV0aG9yIG9mIGV4dGVuZGVkIGNvbXBv bmVudHMsIGFu
ZCBmcmVzaGx5IGNyZWF0ZWQgY29tcG9uZW50cwoqKiBjb21wbHkgd2l0aCBr bm93biBidWls
ZCBpbnRlcmZhY2VzIC0gaS5lLiB0aGlzIHRoaW5nIGJ1aWxkcyBsaWtlIGFu IG9zZ2kuYnVu
ZGxlLgoqLwpzeW5jaHJvbml6ZWQgdW5pdCAibXkudW5pdCIgdmVyc2lvbiAy LjMgIGltcGxl
bWVudHMgb3NnaS5idW5kbGUsIGVjbGlwZS5lY29yZS5tb2RlbCB7CgoJLyog UFJPUEVSVElF
UyAKCSoqIFByb3BlcnRpZXMgc3VwcG9ydHMgc3RyaW5ncywgaW50ZWdlcnMs IGJvb2xlYW5z
LCBleHByZXNzaW9ucyBhbmQgcmVmZXJlbmNlcyB0byBwcm9wZXJ0aWVzCgkq LwkKCXByb3Bl
cnR5IGZvbz0gImhlbGxvIjsKCS8vIGEgcHJvcGVydHkgY2FuIGJlIHNldCB0 byBudWxsIChi
dXQgbm90IGltbXV0YWJsZSBwcm9wZXJ0aWVzKQoJcHJvcGVydHkgZm9vOwoJ aW1tdXRhYmxl
IHByb3BlcnR5IGJhciA9IDMyOwoJaW1tdXRhYmxlIHByb3BlcnR5IGJhciA9 IDMyKzEwOwoJ
CgkvLyBjaGVja3MgaWYgYSBjYWxjdWxhdGlvbiBoYXMgdGhlIHNhbWUgdmFs dWUgYXMgYSBw
cm9wZXJ0eQoJaW1tdXRhYmxlIHByb3BlcnR5IG1lYW5pbmdmdWwgPSAzMisx MCA9PSB0aGUu
bWVhbmluZy5vZi5saWZlOwoJCgkvLyBhIHByb3BlcnR5IGNhbiBiZSAidW5z ZXQiLCB0aGF0
IG1lYW5zIHRoYXQgaWYgaXQgd2FzIHNldCBpbiB0aGlzIGNvbnRleHQsIGl0 IHdpbGwgcmV2
ZXJ0IHRvCgkvLyBpdCdzIHZhbHVlIChpZiBhbnkpIGluIGFuIGVuY2xvc2lu ZyBjb250ZXh0
LgoJLy8KCXVuc2V0IHByb3BlcnR5IHllbGxvdy5iYW5hbmE7CgkKCS8vIFNl dmVyYWwgcHJv
cGVydGllcyBjYW4gYmUgc2V0IGluIGEgY29tcG91bmQgInByb3BlcnRpZXMi IGNsYXVzZS4g
SXQgYWxzbyB3b3JrcyBmb3IgdW5zZXQuCgkvLyBOb3RlIHRoYXQgdGhlICJw cm9wZXJ0eSIg
a2V5d29yZCBpcyBubyBsb25nZXIgcmVxdWlyZWQgcGVyIHNldHRpbmcuCglw cm9wZXJ0aWVz
IHsKCQliYXIgPSAiYmFyIjsKCQlpbW11dGFibGUgcG9saXRpY2lhbiA9ICJv eHltb3JvbiI7
CgkJdW5zZXQgeWVsbG93LmJhbmFuYTsKCQl9CgkKCS8qIFBST1ZJREVTCgkq KiBQcm92aWRl
cyBjbGF1c2UgaXMgdXNlZCB0byBkZWNsYXJlIHRoYXQgdGhlIEJ1aWxkVW5p dCBwcm92aWRl
cyBjYXBhYmlsaXRpZXMuCgkqKiBBIGNhcGFiaWxpdHkgY29uc2lzdHMgb2Yg aW50ZXJmYWNl
L3VuaXRuYW1lIGFuZCBhbiBvcHRpb25hbCAvdmVyc2lvbiBhdCB0aGUgZW5k LgoJKiogSWYg
YW4gaW50ZXJmYWNlLCB1bml0bmFtZSBvciB2ZXJzaW9uIHJlcXVpcmVzIHVz ZSBvZiByZXNl
cnZlZCB3b3JkcyBvciBjaGFyYWN0ZXJzLCB0aGUgY29ycmVzcG9uZGluZwoJ KiogcGFydCBp
cyBlbnRlcmVkIGFzIGEgc3RyaW5nIChpLmUuIHdpdGhpbiAiICIpLgoJKiog QXMgd2l0aCBw
cm9wZXJ0aWVzLCB0aGVyZSBpcyBhIGNvbXBvdW5kIHByb3ZpZGVzIGNsYXVz ZS4KCSoqIAoJ
KiogUHJvdmlkZSBDYXBhYmlsaXRpZXMgY2FuIGJlIGZpbHRlcmVkIC0gc29t ZSBjYXBhYmls
aXRpZXMgbWF5IG9ubHkgYmUgcHJvdmlkZWQgdW5kZXIgY2VydGFpbiBjaXJj dW1zdGFuY2Vz
LgoJKiogVGhpcyBpcyBkZWNsYXJlZCB3aXRoIGEgbGVhZGluZyB3aGVuKEJv b2xlYW5FeHBy
ZXNzaW9uKS4KCSovCglwcm92aWRlcyBvc2dpLmJ1bmRsZS9idW5kbGViYXI7 Cglwcm92aWRl
cyBvc2dpLmJ1bmRsZS9idW5kbGViYXIvMS4wOwoJcHJvdmlkZXMgewoJCW9z Z2kuYnVuZGxl
L2JhcmJhcmEuYnVuZGxlLzIuMDsKCQllY2xpcHNlLmZlYXR1cmUvaW5mbGF0 ZWFibGUucGxl
YXN1cmUvNi42LjY7CgkJCXdoZW4odGFyZ2V0LnBsYXRmb3JtID09IHBsYXRm b3Jtcy53aW4z
MikgbmF0aXZlLnRoaW5nL3dpbmRvd3NJbnN0YWxsZXIvMTIuMjMucjEyMzQ7 CgkJfQoJcHJv
dmlkZXMgd2hlbih0YXJnZXQucGxhdGZvcm0gPT0gcGxhdGZvcm1zLndpbjMy KSAgbmF0aXZl
LnRoaW5nL3dpbmRvd3NJbnN0YWxsZXIvMTIuMjMucjEyMzQ7CgkKCS8qIFJF UVVJUkVTIAoJ
KiogUmVxdWlyZXMgY2xhdXNlIGlzIHVzZWQgdG8gZGVjbGFyZSB0aGF0IHRo ZSBCdWlsZFVu
aXQgcmVxdWlyZXMgY2VydGFpbiBjYXBhYmlsaXRpZXMuIAoJKiogVGhlIGRp ZmZlcmVuY2Vz
IGJldHdlZW4gcmVxdWlyZWQgYW5kIHByb3ZpZGVkIGNhcGFiaWxpdGllcyBh cmUgdGhhdDoK
CSoqIC0gdGhlIHZlcnNpb24gaXMgYWx3YXlzIGEgcmFuZ2UgKGFsdGhvdWcg YSBzaW5nbGUg
dmVyc2lvbiBtZWFucyA+PSB2ZXJzaW9uCgkqLwoJcmVxdWlyZXMgb3NnaS5i dW5kbGUvYWly
LzEuMDsKCXJlcXVpcmVzIHdoZW4gKCF0YXJnZXQucGxhdGZvcm0gIT0gInNw YXJjIiAmJiB0
YXJnZXQucGxhdGZvcm0gPCAiaHBVeCIpIG9zZ2kuYnVuZGxlL3BpbGxvdy8z LjAgOwoJcmVx
dWlyZXMgewoJCW9zZ2kuYnVuZGxlL3BpbGxvdy8xLjA7CgkJd2hlbiAoYSA9 PSBiKSBvc2dp
LmJ1bmRsZS9ibGFua2V0LzEuMDsKCQl9CgkKCS8qIE1FVEEgUkVRVUlSRVMg CgkqKiBXaXRo
IGEgbGVhZGluZyBtZXRhIGtleXdvcmQsIHRoZSByZXF1aXJlbWVucyBhcmUg cmVxdWlyZW1l
bnRzIG9uIHRoZSBlbnZpcm9ubWVudCAoaS5lLiBvbiBiMyBpdHNlbGYpCgkq KiBBcyBhbiBl
eGFtcGxlLCBhIG1ldGEgcmVxdWlyZW1lbnQgbWF5IGJlIHRoYXQgYSBjZXJ0 YWluIG1ldGEg
ZGF0YSBwcm92aWRlciBpcyBpbnN0YWxsZWQgb3IgaXQgd2lsbCBiZSBpbXBv c3NpYmxlIHRv
CgkqKiB1c2UgdGhpcyBkZWZpbml0aW9uLiAKCSovCgltZXRhIHJlcXVpcmVz IG9zZ2kuYnVu
ZGxlL2Fpci8xLjA7CgltZXRhIHJlcXVpcmVzIHdoZW4gKDQyID49IDMyKSBv c2dpLmJ1bmRs
ZS9waWxsb3cvIjMuMCI7CgltZXRhIHJlcXVpcmVzIHsKCQlvc2dpLmJ1bmRs ZS9waWxsb3cv
MS4wOwoJCXdoZW4gKG15b3JnLmZvbyB+PSAiW2Etel0uKiIpIG9zZ2kuYnVu ZGxlL2JsYW5r
ZXQvMS4wOwoJCX0KCQoJLyogQVJUSUZBQ1RTCgkqKiBBcnRpZmFjdCBpcyBh IHZlY3RvciBv
ZiBwYXRoIGdyb3Vwcy4KCSoqIEEgZ3JvdXAgb2YgcGF0aHMgbWF5IGhhdmUg YSBiYXNlIHBh
dGggLSB0aGUgcmVzdCBvZiB0aGUgcGF0aHMgaW4gdGhlIGdyb3VwIGFyZSBy ZWxhdGl2ZSB0
byB0aGUKCSoqIGJhc2UgcGF0aC4KCSoqIEZpbGUgbmFtZXMgdGhhdCBpbmNs dWRlIHJlc2Vy
dmVkIHdvcmRzIG9yIHJlc2VydmVkIGNoYXJhY3RlcnMgYXJlIGVudGVyZWQg d2l0aGluICIg
IgoJKiogRmlsZSBuYW1lcyBjb250YWluaW5nIHNwYWNlcyBtdXN0IGFsd2F5 cyBiZSBxdW90
ZWQsIGFzIHRoZSBjb21waWxlciByZW1vdmVzIHdoaXRlc3BhY2UgZnJvbSBu b24gc3RyaW5n
cy4KCSoqIFN0YW5kYXJkICBYVGV4dCBpbXBsZW1lbnRhdGlvbiBhbGxvd3Mg YSB1bmFyeSBe
IGJlZm9yZSBhIGtleXdvcmQgYXMgYW4gZXNjYXBlIChSZW1vdmU/KQoJKiog SW5jbHVzaW9u
IG9mIGEgdmVjdG9yIGNhbiBiZSBjb250cm9sbGVkIHdpdGggYSBsZWFkaW5n IHdoZW4oQm9v
bGVhbkV4cHJlc3Npb24pLgoJKioKCSoqIFZJU0lCSUxJVFkKCSoqIFZpc2li aWxpdHkgaXMg
ZWl0aGVyIHByaXZhdGUgb3IgcHVibGljICh0aGUgZGVmYXVsdCkuIFByaXZh dGUgbWVhbnMg
dGhhdCB0aGUgcGFydCBpcyBvbmx5IGFjY2VzYWJsZQoJKiogZnJvbSB3aXRo aW4gdGhlIGIz
IHVuaXQgd2hlbmUgdGhlIHBhcnQgaXMgZGVjbGFyZWQuCgkqKgoJKiogUFJP UEVSVElFUwoJ
KiogSXQgaXMgcG9zc2libGUgdG8gc2V0IChhbmQgdW5zZXQpIHByb3BlcnRp ZXMgaW4gdGhl
IGxpc3QgdXNpbmcgYmFzaWMgb3IgY29tcG91bmQgcHJvcGVydHkgc3RhdGVt ZW50cy4KCSoq
IFRoZXNlIHByb3BlcnRpZXMgYXJlIHNldCBvbiB0aGUgcmVzdWx0aW5nIHBh dGggZ3JvdXAg
dmVjdG9yIGFuZCBhcmUgYXZhaWxhYmxlIHRvIHRoZSB1c2VyIG9mIHRoZQoJ Kiogc2V0IG9m
IGZpbGVzLiAKCSoqIFNpbmNlIGZpbGUgZ3JvdXAgdmVjdG9ycyBhcmUgbWVy Z2VkLCBzbyB3
aWxsIHRoZSBwcm9wZXJ0aWVzLiBVc2Ugb2YgaW1tdXRhYmxlIHByb3BlcnRp ZXMgd2lsbCBn
dWFyYW50ZWUKCSoqIHRoYXQgdGhlIHByb3BlcnR5IHZhbHVlcyBzZXQgd2ls bCBzdXJmYWNl
IChvciBhbiBlcnJvciB3aWxsIGJlIGdlbmVyYXRlZCBpZiBtZXJnaW5nIGNh dXNlcyB0aGUg
dmFsdWUKCSoqIHRvIGNoYW5nZSksIGJ1dCBpcyBvayBpZiBtdWx0aXBsZSB2 ZWN0b3JzIGFy
ZSB0YWdnZWQgdGhlIHNhbWUgd2F5LgoJKiogCgkqKiBOb3RlIHRoYXQgaW5k aXZpZHVhbCBw
cm9wZXJ0eSBzZXR0aW5ncyBwZXIgZmlsZSBpcyBub3Qgc3VwcG9ydGVkLiBU byBmbGFnIGFu
IGluZGl2aWR1YWwgZmlsZSBpdCBpcwoJKiogcmVjb21tZW5kZWQgdG8gdXNl IGRvdHRpZWZp
ZWQgcHJvcGVydGllcyAtIGV4YW1wbGUgLSBtYXJrIHRoZSBwYXRoIC9hL2Ig YXMgYmVpbmcg
bGl0dGxlIGVuZGlhbgoJKiogcHJvcGVydHkgb3JnLm15b3JnLmZpbGVpbmZv LmVuZGlhbi5h
LmI9bGl0dGxlLgoJKioKCSoqIERJU0NVU1MgLSBpcyBpdCBvZiB2YWx1ZSB0 byBoYXZlIHBy
b3BlcnRpZXMvYW5ub3RhdGlvbnMgcGVyIGZpbGU/CgkqKiAKCSovCglwcml2 YXRlIGFydGlm
YWN0cyB0ZXN0LmExIHByb3ZpZGVzIG15b3JnLmZvb2QvZnJ1aXQuc2FsbGFk LzIuMCwgbXlv
cmcucHJvamVjdGlsZXMvZnJ1aXQuc2FsYWQKCQl7CgkJYTsgLy8gYSB2ZWN0 b3Igd2l0aCBv
bmUgZW50cnkKCQlhLCBiOyAvLyBhIHZlY3RvciB3aXRoIHR3byBlbnRyaWVz CgkJYSBbIGIs
IGNdOyAvLyBhIGJhc2UgcGF0aCAoYSksIHdpdGggdHdvIHJlbGF0aXZlIHBh dGhzIGluIGEg
dmVjdG9yCgkJL2EvYjsKCQkvIGEgLyBiIDsgLy8gaXMgZXF1aXZhbGVudCB0 byAvYS9iIC0g
bm90IC8iIGEiLyIgYiIKCQkgCgkJCgkJLy8gbmFtZXMgdGhhdCBtdXN0IGJl IHF1b3RlZAoJ
CSJ1bml0IjsgLy8gYSBrZXl3b3JkCgkJIjFhIjsgLy8gZG9lcyBub3QgbG9v ayBsaWtlIGEg
cXVhbGlmaWVkIG5hbWUKCQkiYSBiIjsgLy8gaGFzIHNwYWNlIGluIG5hbWUK CQkiYYyKmiI7
IC8vIGhhcyBOTFMgY2hhcmFjdGVycwoJCSIvL2YiOyAvLyBsb29rcyBsaWtl IGEgY29tbWVu
dAoJCSIxMjMiOyAvLyBpcyBhbiBpbnRlZ2VyCgkJCgkJIm15LnVuaXQiLCAi bXkudW5pdCI7
IC8vIHVuaXQgaXMgYSBrZXl3b3JkCgkJbXkuXnVuaXQ7IC8vIHVuaXQgaXMg a2V5d29yZCAt
IHN0YW5kYXJkIFhUZXh0IGdyYW1tYXIgZXNjYXBlIG9mIGtleXdvcmRzIGlu IElECgkJd2hl
bih0YXJnZXQucGxhdGZvcm0gPT0gIm9zeCIpICBNYWNBcHAuYXBwIDsKCQl3 aGVuKHRydWUp
IGJhbmFuYS50eHQsIHBpbmVhcHBsZS50eHQsIG1hbmdvLnR4dDsKCQl3aGVu ICh0cnVlKSBl
eG90aWMgWyByYW1idXN0YW4udHh0LCB0YW1hcmluZC50eHQgXTsKCQlhMSBb YXBwbGUudHh0
LCAiYmFuIGFuYS50eHQiXTsKCQlmZWUvYXBhLmJvbyBbIGEvYi9jLmQsIGEu Yi5jLmQsIG8v
Yi9kIF07CgkJcHJvcGVydHkgYXBhPSJiYW5hbiI7CgkJcHJvcGVydHkgZGVm YXVsdHNUb051
bGw7CgkJcHJvcGVydGllcyB7IGE7IGI7IH0KCQl9CgkKCS8vIEFuIGVtcHR5 IGFydGlmYWN0
cyB2ZWNvcgkKCWFydGlmYWN0cyBlbXB0eSB7Cgl9CgkKCS8qIEFSVElGQUNU UyBQUk9WSURJ
TkcgQ0FQQUJJTElUSUVTCgkqKiBJdCBpcyBwb3NzaWJsZSB0byBkZWNsYXJl IHRoYXQgdGhl
IHJlc3VsdGluZyBwYXRoIGdyb3VwIHZlY3RvciBpcyBhIGNhcGFiaWxpdHkg bGF5ZWQgb3V0
IG9uIGRpc2suCgkqKiBUaGV5IGxheW91dCBjYW4gcmVwcmVzZW50IG1hbnkg Y2FwYWJpbGl0
aWVzIGF0IHRoZSBzYW1lIHRpbWUuCgkqLwoJYXJ0aWZhY3RzIHByb3ZpZGVz TWFueSBwcm92
aWRlcyAgYS9iLzEuMCwgYy9kLzIuMCwgeC95LzMuMCB7YTt9CgkKCS8qIEdS T1VQCgkqKiBB
IGdyb3VwIGlzIHNpbWlsYXIgdG8gYXJ0aWZhY3RzIGluIHRoYXQgaXQgY3Jl YXRlcyBhIHBh
dGggZ3JvdXAgdmVjdG9yLCBidXQgaXQgY3JlYXRlcyB0aGlzCgkqKiBieSBh Z2dyZWdhdGlu
ZyBwYXRoIGdyb3VwIHZlY3RvcnMgZnJvbSBvdGhlciBwYXJ0cy4gCgkqKiBK dXN0IGFzIHdp
dGggYXJ0aWZhY3RzOyB0aGUgcmVzdWx0aW5nIHBhdGggZ3JvdXAgdmVjdG9y IGNhbiByZXBy
ZXNlbnQgY2FwYWJpbGl0aWVzLgoJKioKCSoqIFRoZSBncm91cCBjb25zaXN0 cyBvZiBhIGxp
c3Qgb2YgcmVxdWlyZWQgY2FwYWJpbGl0aWVzLiBUaGUgc3ludGF4IGlzIHRo ZSBzYW1lIGFz
IGZvcgoJKiogdGhlIHVuaXRzIHJlcXVpcmVzIHsgfSBjbGF1c2UsIHdpdGgg dGhlIGZvbGxv
d2luZyBhZGRpdGlvbnM6CgkqKiAtIEEgdHJhaWxpbmcgJyNwYXJ0bmFtZScg IGlzIHVzZWQg
YWZ0ZXIgdGhlIHJlcXVpcmVtZW50IHRvIHBpY2sgYSBwYXJ0aWN1bGFyIHBh cnQuCgkqKiAt
IEEgcmVmZXJlbmNlIGNhbiBiZSBtYWRlIHRvIHBhcnRzIGluIHRoZSBzYW1l IGJ1aWxkIHVu
aXQgYnkgdXNpbmcgYSBzaW5nbGUgaWRlbnRpZmllcgoJKiogLSBBIHJlZmVy ZW5jZSB0byBh
IHJlcXVpcmVkIGNhcGFiaWxpdHkgd2l0aG91dCBhIHRyYWlsaW5nICcjcGFy dG5hbWUnIGlz
IHRha2VuIGFzIGEgcmVmZXJlbmNlIHRvICcjc2VsZicsIG1lYW5pbmcgdGhl CgkqKiAgIGFn
Z3JlZ2F0aW9uIG9mIGFsbCBpdHMgcHVibGljIHBhcnRzLgoJKiogLSBJdCBp cyBwb3NzaWJs
ZSB0byBkZWZpbmUgYSBjbG9zdXJlIHdoZXJlIHByb3BlcnRpZXMgYW5kIGFk dmlzZSBhcmUg
ZGVjbGFyZWQuIFRoZXkgaGF2ZSBkb3duc3RyZWFtIGVmZmVjdAoJKiogICAo aS5lLiB3aGVu
IGV2YWx1YXRpbmcgdGhlIHBhcnQpLiBUaGUgY2xvc3VyZSBpcyBkZWZpbmVk IHVzaW5nIGEg
dHJhaWxpbmcgd2l0aCB7IH0gc3RhdGVtZW50LgoJKiogLSBBIGNsb3N1cmUg Y2FuIGJlIGRl
ZmluZWQgZm9yIHNldmVyYWwgcmVxdWlyZW1lbnRzIGF0IHRoZSBzYW1lIHRp bWUgYnkgZW5j
bG9zaW5nIHRoZSByZXF1aXJlbWVudHMgaW4gY3VybHkKCSoqICAgYnJhY2tl dHMge3IgciBy
fSB3aXRoIHsgfQoJKiogLSBBIGxlYWRpbmcgdm9pZCBrZXl3b3JkIGluZGlj YXRlcyB0aGF0
IHRoZSByZXN1bHRpbmcgcGF0aCBncm91cCB2ZWN0b3IgZnJvbSB0aGUgZXZh bHVhdGlvbiBv
ZiB0aGUgcGFydCBzaG91bGQKCSoqICAgbm90IGJlIGluY2x1ZGVkIGluIHRo ZSByZXN1bHRp
bmcgcGF0aCBncm91cCB2ZWN0b3IuCgkqKiAtIFRoZSByZXN1bHQgb2YgaW5k aXZpZHVhbCBw
YXJ0IGV2YWx1YXRpb24sIG9yIGV2YWx1YXRpb24gb2YgYSBncm91cCBvZiBy ZXF1aXJlbWVu
dHMgY2FuIGJlIGFzc2lnbmVkIHRvIGFuIGFsaWFzLgoJKiogICBUaGUgYWxp YXMgaXMgYSBw
cm9wZXJ0eSB0aGF0IGlzIGluY2x1ZGVkIGluIHRoZSByZXN1bHRpbmcgcGF0 aCBncm91cCB2
ZWN0b3IuIFRoaXMgbWFrZXMgaXQgcG9zc2libGUgZm9yIGEgdXNlcgoJKiog ICBvZiB0aGUg
dmVjdG9yIHRvIHJlZmVyZW5jZSBhIHBhcnRpY3VsYXIgcGFydCBvZiB0aGUg c2V0LgoJKiog
LSB2b2lkIGFuZCBhbGlhcyBjYW4gYmUgdXNlZCBhdCB0aGUgc2FtZSB0aW1l LCBidXQgZm9y
IGEgZ3JvdXAgdGhhdCByZXByZXNlbnRzIGEgcGFydCAoYXMgaW4gdGhpcyBj YXNlKSwgbmVp
dGhlciB0aGUKCSoqICAgcHJvcGVydHkgbm9yIGl0cyB2YWx1ZSBzdXJ2aXZl IHRoZSBncm91
cCdzIGNvbnRleHQuIEZvciBvdGhlciB0eXBlcyBvZiBncm91cGluZyAoaW4g YWN0aW9ucyks
IHRoaXMgaXMgdmVyeQoJKiogICB2YWx1YWJsZSwgYnV0IGluIGEgZ3JvdXAg cGFydCwgdGhp
cyBjb25zdHJ1Y3Qgc2ltcGx5IGhhcyBubyBlZmZlY3QuIAoJKioKCSoqIFdJ VEggQ0xPU1VS
RQoJKiogSW4gdGhlIHdpdGggY2xvc3VyZSwgcHJvcGVydGllcyBjYW4gYmUg c2V0IHVzaW5n
IHRoZSBzaW5nbGUgb3IgY29tcG91bmQgcHJvcGVydGllcyBzdGF0ZW1lbnRz LgoJKiogQWR2
aWNlIGNhbiBiZSBzZXQgdXNpbmcgYWR2aWNlIHN5bnRheC4KCSoqIAoJKi8K CXByaXZhdGUg
c3luY2hyb25pemVkIGdyb3VwICJmb28vYmFyIiBwcm92aWRlcyAgbXlvcmcu Zm9vZC9mcnVp
dC5jb2N0YWlsLzIuMCwgYSAvIGIgLyAiMi4zIgoJewoJIAlhOyAvLyByZWZl cmVuc2UgdG8g
cGFydCBpbiBzZWxmCgkJZm9vL2JhcjsgLy8gcmVmZXJlbmNlIHRvICNzZWxm IGluIGludGVy
ZmFjZSBmb28sIG5hbWUgYmFyCgkJYS9hI2I7IC8vIHJlZmVyZW5jZSB0byAj YiBpbiBpbnRl
cmZhY2UgYSwgbmFtZSBhCgkJZnViYmxhPSBvc2dpLmJ1bmRsZS9mb28uYmFy LzEuMDsgLy8g
c2V0cyB0aGUgcHJvcGVydHkgZnViYmxhIHRvIHRvIHRoZSBwYXRoR3JvdXAg cmVmZXJlbmNl
IGluIHJ1bnRpbWUgLSB0eXBpY2FsbHkgbm90IHVzZWQgaW4gZ3JvdXBzCgkJ b3NnaS5idW5k
bGUvZmVlLmZ1bS8xLjAjamFyczsKCQlvc2dpLmJ1bmRsZS96ZUJ1bmRsZS8x LjAjamFyczsK
CQl2b2lkIGEvYSNiOyAvLyBvbmx5IHBlcmZvcm1lZCBmb3Igc2lkZSBlZmZl Y3QKCQl2b2lk
IGFsaWFzLm5icjEgPSBiOyAvLyBvbmx5IHBlcmZvcm1lZCBmb3Igc2lkZSBl ZmZlY3QsIGJ1
dCBzZXRzIGEgcHJvcGVydHkgdG8gdGhlIHJlc3VsdCAodGhhdCBpcyB0aGVu IGlnbm9yZWQp
CgkJYS9hI2Igd2l0aCB7IHByb3BlcnR5IG5pY2UgPSAieWVzIjsgfTsgLy8g c2V0cyBhbmQg
cGFzc2VzIHRoZSBwcm9wZXJ0eSBuaWNlIGRvd25zdGVhbQoJCWEvYSNiIHdp dGggeyAvLyBw
YXNzZXMgc2V2ZXJhbCBwcm9wZXJ0aWVzIGRvd25zdHJlYW0uCgkJCXByb3Bl cnRpZXMgewoJ
CQkJYT0iMiI7IGI9IjIiOyBjPSIzIjsKCQkJCX0KCQkJfTsKCQkvLyBpbmNs dWRlcyByZXN1
bHQgb2YgdGhyZWUgcmVmZXJlbmNlcywgYWxsIHdpdGggdGhlIHNhbWUgc2V0 IG9mIGRvd25z
dHJlYW0gcHJvcGVydGllcwkKCQl7IGEvYSNiOyBhL2IjYzsgYS9jI2Q7IH0g d2l0aCB7IHBy
b3BlcnR5IHRhcmdldC5wbGF0Zm9ybT0ic3BhcmMiOyB9OyAKCQkvLyBzZXRz IGFuIGFsaWFz
IG9uIGEgbm9uIGluY2x1ZGVkIHJlc3VsdCwgcmVzdWx0IGlzIGEgZ3JvdXAg b2YgaXRlbXMg
d2l0aCBkb3duc3RyZWFtIHByb3BlcnRpZXMKCQl2b2lkIGFsaWFzZWRCdXRO b3RJbmNsdWRl
ZCA9IHsgYS9hI2I7IGEvYiNjOyBhL2MjZDsgfSB3aXRoIHsgcHJvcGVydHkg Zm9vPSJocHV4
IjsgfTsKCQkvLyBzZXRzIGFuIGFsaWFzIG9uIGFuIGluY2x1ZGVkIGl0ZW0s IHJlc3VsdCBp
cyBhIGdyb3VwIG9mIGl0ZW1zIHdpdGggZG93bnN0cmVhbSBwcm9wZXJ0aWVz LCBhIG5lc3Rl
ZCBhbGlhcyBpcyBzZXQKCQlhbGlhc2VkQW5kSW5jbHVkZWQgPSB7IGFsaWFz Lm5icjM9YS9h
I2I7IGEvYiNjOyBhL2MjZDsgfSB3aXRoIHsgcHJvcGVydHkgZm9vPSJocHV4 IjsgfTsKCQkK
CQkvLyBpbmNsdXNpb24gY2FuIGJlIGZpbHRlcmVkIHdpdGggYSBib29sZWFu IGV4cHJlc3Np
b24gLSBoZXJlICJ0cnVlIiBtYWtlcyBpdCBhbHdheXMgaW5jbHVkZWQKCQl3 aGVuICh0cnVl
KSB7IGEvYSNiOyBhL2IjYzsgYS9jI2Q7IH0gd2l0aCB7IHByb3BlcnR5IGZv bz0iejgwIjsg
fTsKCQkvLyBmaWx0ZXJpbmcgLSBoZXJlLCBuZXZlciBldmVyIGluY2x1ZGVk IGJlY2F1c2Ug
Ym9vbGVhbiB2YWx1ZSBpcyBmYWxzZQoJCXdoZW4gKGZhbHNlKSBhL2EjYjsK CQkvLyBhIG5v
biBpbmNsdWRlZCBhbmQgZmlsdGVyZWQgcmVmZXJlbmNlIHRvIGEvYSNiCgkJ dm9pZCB3aGVu
ICh0cnVlKSBhL2EjYjsKCX0gCgoJLy8gVGhlIGtleXdvcmQgJ3N5bmNyb25p emVkJyBkZWNs
YXJlcyB0aGF0IHBhcmFsbGVsbCBleGVjdXRpb24gb2YgYW55IHBhcnQgaXMg ZGlzc2FsbG93
ZWQKCXByaXZhdGUgc3luY2hyb25pemVkIGdyb3VwIGZvbyB7fQoJcHVibGlj IHN5bmNocm9u
aXplZCBncm91cCBmb28ge30KCXByaXZhdGUgZ3JvdXAgZm9vIHt9Cglncm91 cCBmb28ge30K
CXN5bmNocm9uaXplZCAgZ3JvdXAgZm9vIHt9CgkKCQkKCS8qCgkqKiBBQ1RJ T04KCSoqIEFu
IGFjdGlvbiBoYXMgYW4gZW1iZWRkZWQgZ3JvdXAgZGVjbGFyYXRpb24gdGhh dCBkZWZpbmVz
IHRoZSBpbnB1dCB0byBhbiBhY3Rvci4gVGhlIGFjdG9yIGlzIHRvbGQgdG8K CSoqIHByb2R1
Y2UgdGhlIHJlc3VsdChzKSBkZWNhbHJlZCBmb3IgdGhlIGlucHV0IGdyb3Vw LiBJbnB1dCBn
cm91cHMgYW5kIHJlc3VsdHMgY2FuIGJlIG5lc3RlZC4KCSoqIFRoaXMgaXMg dXNlZCB0byBk
ZWNhbHJlIGNvbW1vbiBpbnB1dCwgaW5wdXQgZm9yIGEgZ3JvdXAgb2YgcmVz dWx0cyAoc3Vj
aCBhcyBpbnB1dCB0byBhY3Rpb25zIGZvciBsaW51eCksCgkqKiBhbmQgdGhl biBzcGVjaWZp
YyBpbnB1dCBmb3IgYnVpbGRpbmcgYSBsaW54IGZsYXZvciwgZm9yIGRpZmZl cmVudCB3aW5k
b3dpbmcgc3lzdGVtcyBldGMuCgkqKgoJKiogVGhlIHJlc3VsdCBjYW4gY29u c2lzdCBiZSBk
ZWNsYXJlZCB3aXRoIHB1YmxpYyBvciBwcml2YXRlIHZpc2liaWxpdHksIG9y IGZvbGxvdyB0
aGUgdmlzaWJpbGl0eSBvZiB0aGUgYWN0aW9uLgoJKiogUHVibGljIHJlc3Vs dCBhcmUgYXZh
aWxhYmxlIGFzIGZpcnN0IGNsYXNzIG1lbWJlcnMgb2YgdGhlIHVuaXQgKGV2 ZW4gaWYgdGhl
IGVuY2xvc2luZyBhY3Rpb24gaXMgcHJpdmF0ZSkuCgkqKiBQdWJsaWMgcmVz dWx0IG11c3Qg
YmUgbmFtZWQuIFByaXZhdGUgcmVzdWx0IG11c3QgYmUgbmFtZWQgaWYgaXQg c2hvdWxkIGJl
IHJlZmVyZW5jZWQgaW5kaXZpZHVhbGx5IChhbmQgbm90IGFzCgkqKiBwYXJ0 IG9mIHRoZSBh
Y3Rpb24ncyByZXN1bHQpLgoJKioKCSoqIFRoZSBhY3RvciBpcyBkZWNsYXJl ZCBpbiB0aGUg
cHJlYW1ibGUgb2YgdGhlIGFjdGlvbiBwYXJ0IGFuZCBpcyBpbnN0YW50aWF0 ZWQgb25jZS4K
CSoqIFBhcmFtZXRlcnMgdG8gdGhlIGFjdG9yIGluc3RhbnRpYXRpb24gY2Fu IGJlIHBhc3Nl
ZCB3aXRoIHBhcmVudGhlc2VzIHVzaW5nIG5hbWVkIHBhcmFtZXRlcnMKCSoq IChvcmRlciBp
cyBub3QgaW1wb3J0YW50KS4KCSoqIC0gQW4gYWN0aW9uIGNhbiBwcm92aWRl IHRoZSByZXN1
bHRpbmcgcGF0aCBncm91cCB2ZWN0b3IgYXMgcHJvdmlkZWQgY2FwYWJpbGl0 aWVzCgkqKgoJ
KiogQWxpYXNlcwoJKiogQWxpYXNlcyBmb3IgaW5wdXQgcGFydHMgaGF2ZSBh biBhZGRpdGlv
bmFsIG1lYW5pbmcgaW4gYWN0aW9ucyAtIHRoZXNlIHByb3BlcnRpZXMgYXJl IGF2YWlsYWJs
ZSB0byB0aGUgYWN0b3IuCgkqKiBUaGlzIG1lYW5zIHRoYXQgdGhlIGNvbWJp bmF0aW9uIG9m
IHZvaWQgYWxpYXM9eyB9IGlzIG1lYW5pbmdmdWwgKGFzIG9wcG9zZWQgdG8g d2hlbiB1c2Vk
IGluIGEgZ3JvdXAgcGFydCkuCgkqKgoJKiogUkVTVUxUCgkqKiBSZXN1bHQg Y2xhdXNlcyBi
ZWhhdmUgbGlrZSBhcnRpZmFjdCBwYXJ0cywgYnV0IHRoZXkgdHlwaWNhbGx5 IHJlZmVyIHRv
IGZpbGVzIHRoYXQgd2VyZSBwcm9kdWNlIGJ5IHRoZSBhY3Rvci4KCSoqIFBy b3BlcnRpZXMg
aW4gdGhlc2Ugc2V0cyBtYXkgYmUgc2V0IGJ5IHRoZSBhY3Rvci4gVGhpcyBt ZWFucyB0aGF0
IGFuIGFjdG9yIGNhbiBwYXNzIGluZm9ybWF0aW9uIGJhY2sgLSBzdWNoIGFz CgkqKiBhIHZl
cnNpb24gcXVhbGlmaWVyLCBsb2NhdGlvbiBvZiBjZXJ0YWluIGZpbGVzIG9u IGRpc2sgZXRj
LgoJKiogCgkqLwoJcHJpdmF0ZSBzeW5jaHJvbml6ZWQgYWN0aW9uIGZvbyAK CQlhY3RvciBa
aXBBY3RvcihzZXJ2aWNlS2V5PSJXb29Ib28gLSB3b290IikKCQlwcm92aWRl cyAgbXlvcmcu
Zm9vZC9mcnVpdC5jb2N0YWlsLzIuMAoJewoJCWdyb3VwIHsKCQkJYTsgLy8g ZGVmYXVsdHMg
dG8gI3NlbGYKCQkJd2hlbiAoYXBhID4gMTEpIGEvYSNiOwoJCQlvc2dpLmJ1 bmRsZS9mb28u
YmFyLyIxLjIuMy5xdWFsaWZpZXIjLC4vIiNqYXJzOyAvLyBkZWZhdWx0cyB0 byAjc2VsZgoJ
CQkKCQkJCgkJCW9zZ2kuYnVuZGxlL2ZlZS5mdW0vMS4wI2phcnM7CgkJCW9z Z2kuYnVuZGxl
L3plQnVuZGxlI2phcnM7CgkJCXZvaWQgYS9hI2I7IC8vIG9ubHkgcGVyZm9y bWVkIGZvciBz
aWRlIGVmZmVjdAoJCQl2b2lkIGFsaWFzLm5icjEgPSBhL2EjYjsgLy8gb25s eSBwZXJmb3Jt
ZWQgZm9yIHNpZGUgZWZmZWN0CgkJCWEvYSNiIHdpdGggeyBwcm9wZXJ0eSBu aWNlID0gInll
cyI7IH07CgkJCWEvYSNiIHdpdGggewoJCQkJcHJvcGVydGllcyB7CgkJCQkJ YT0iMiI7IGI9
IjIiOyBjPSIzIjsKCQkJCQl9CgkJCQl9OwoJCQl7IGEvYSNiOyBhL2IjYzsg YS9jI2Q7IH0g
d2l0aCB7IHByb3BlcnR5IHRhcmdldC5wbGF0Zm9ybT0ic3BhcmMiOyB9OwoJ CQl2b2lkIHsg
YS9hI2I7IGEvYiNjOyBhL2MjZDsgfSB3aXRoIHsgcHJvcGVydHkgZm9vPSJo cHV4IjsgfTsK
CQkJdm9pZCBhbGlhcy5uYnIyID0geyBhbGlhcy5uYnIzPWEvYSNiOyBhL2Ij YzsgYS9jI2Q7
IH0gd2l0aCB7IHByb3BlcnR5IGZvbz0iaHB1eCI7IH07CgkJCXdoZW4gKHRy dWUpIHsgYS9h
I2I7IGEvYiNjOyBhL2MjZDsgfSB3aXRoIHsgcHJvcGVydHkgZm9vPSJ6ODAi OyB9OwoJCQl3
aGVuIChmYWxzZSkgYS9hI2I7CgkJCXZvaWQgd2hlbiAodHJ1ZSkgYS9hI2I7 CgkJCX17IAoJ
CQkJcmVzdWx0IGEgeyBhOyB9CgkJCX0KCX0KCWFjdGlvbiB0ZXN0MSBhY3Rv ciBUZXN0KHRl
c3Q9InRlc3QiKSBwcm92aWRlcyBhL2IvIjEiCgl7CS8vIG5vIGRlcGVuZGVu Y2llcywgbm8g
c3BlY2lhbCBpbnB1dCwganVzdCAiZG8gaXQgYW5kIHByb2R1Y2UgcmVzdWx0 IgoJCQlyZXN1
bHQgYiB7IGIudHh0OyB9Cgl9CglhY3Rpb24gdGVzdDIgYWN0b3IgVGVzdCh0 ZXN0PSJ0ZXN0
IikgcHJvdmlkZXMgYS9iLyIxIgoJewkvLyBubyBkZXBlbmRlbmNpZXMsIG5v IHNwZWNpYWwg
aW5wdXQsIGp1c3QgImRvIGl0IGFuZCBwcm9kdWNlIHJlc3VsdCIKCQkvLyBi dXQgc2V0IGEg
cHJvcGVydGllcwoJCS8vCgkJCXJlc3VsdCBiIHsgYi50eHQ7IH0gd2l0aCB7 IHByb3BlcnR5
IHRhcmdldC5wbGF0Zm9ybSA9ICJ3aW4zMiI7IH0KCX0KCi8qIE5PTiBXT1JL SU5HIFNZTlRB
WCwgZHVlIHRvIHByb2JsZW1zIGluIGxhbmd1YWdlIHNwZWNpZmljYXRpb24u IEhlbHAgV2Fu
dGVkLgoKCWFjdGlvbiB0ZXN0MyBhY3RvciBUZXN0KHRlc3Q9InRlc3QiKSBw cm92aWRlcyBh
L2IvIjEiCgl7CgkvLyBOT04gd29ya2luZyBleGFtcGxlIC0gbmVlZCBoZWxw IHdpdGggcGFy
c2VyCgoJCS8vIGdyb3VwIGlucHV0IHRvIG9uZSByZXN1bHRzCgkJZ3JvdXAg eyAKCQkJYTsK
CQkJfSAKCQlyZXN1bHQgYiB7IGIudHh0OyB9Cgl9CiovCgkKCWFjdGlvbiB0 ZXN0MyBhY3Rv
ciBUZXN0KHRlc3Q9InRlc3QiKSBwcm92aWRlcyBhL2IvIjEiCgl7CgkJLy8g Z3JvdXAgaW5w
dXQgdG8gb25lIG9yIHNldmVyYWwgcmVzdWx0cwoJCWdyb3VwIHsgYTsgfQoJ CQl7CgkJCXJl
c3VsdCBiIHsgYi50eHQ7IH0KCQkJfQoJfQoJYWN0aW9uIFRlc3QgYWN0b3Ig VGVzdCh0ZXN0
PSJ0ZXN0IikgcHJvdmlkZXMgYS9iLyIxIgoJewoJCWdyb3VwIHsgYTsKCQl9 IHsKCQkJcmVz
dWx0IGIgeyBiOyB9CgkJCXJlc3VsdCBiIHsgYjsgfQoJCQlyZXN1bHQgYiB7 IGI7IH0KCQl9
Cgl9CglhY3Rpb24gVGVzdCBhY3RvciBUZXN0KHRlc3Q9InRlc3QiKSBwcm92 aWRlcyBhL2Iv
IjEiCgl7CgkJZ3JvdXAgeyBhOwoJCX0gewoJCQlncm91cCAgeyB4OyB9IHsg cmVzdWx0IGIg
eyBiOyB9IH0KCQkJcmVzdWx0IGIge2I7fQkJCQoJCQlncm91cCAgeyB4OyB9 IHsgcmVzdWx0
IGIgeyBiOyB9IH0gCgkJfQoJfQoJCglhY3Rpb24gbWFrZVdpbjMyWmlwIAoJ YWN0b3IgWmlw
QWN0b3Ioc2VydmljZUtleT0idGpvaG8iKQoJcHJvdmlkZXMgZm9vZHN0dWZm LnNhbGxhZC9m
cnVpdHNhbGxhZC8xLjAsIHgvYi8iMjMiCgl7CgkJZ3JvdXAgewoJCQl7IHNp dGUgPSBjcmVh
dGVTaXRlOyB9IHdpdGggeyBwcm9wZXJ0eSB0YXJnZXQucGxhdGZvcm09Indp bjMyIjt9OwoJ
CX17CgkJCWdyb3VwIHsgCgkJCQlleHRyYUlucHV0ID0gYS9hLzIuMCNqYXJG aWxlczsgCgkJ
CX17CgkJCQlwdWJsaWMgcmVzdWx0IG1ha2VTb21lb25lSGFwcHkgIHsKCQkg ICAgCQlhcGEv
YmFuYW4uemlwIDsKCQkJCQl3aGVuKHRydWUpIGNoaW1wL2JhbmFuLnppcCA7 IAoJCQkJfSB3
aXRoIHsgcHJvcGVydGllcyB7IHRhcmdldC5wbGF0Zm9ybSA9ICJ3aW4zMiI7 IHByZXJlcXVp
c2l0ZS5mbGFnID0gImEjYiI7IH19CgkJCQkKCQkJCWdyb3VwIHsKCQkJCQlz cGVjaWFsOwoJ
CQkJfXsKCQkJCQl3aGVuICh0cnVlKSBwcml2YXRlIHJlc3VsdCBhIHsgYTt9 IHdpdGggeyAv
KiBmb3IgYSBvbmx5ICovIH0KCQkJCQl3aGVuICh0cnVlKSByZXN1bHQgYiB7 fSB3aXRoIHsg
LyogZm9yIGIgb25seSAqLyB9CgkJCQl9IHdpdGggeyAvKiBmb3IgYSBhbmQg YiAqLyB9CgkJ
CX0KCQl9Cgl9CgkKCS8qKiBTeW5jaHJvbml6ZSBjbGF1c2VzIGFsbG93cyBz eW5jcm9uaXph
dGlvbiB0byBiZSBzcGVjaWZpZWQgYWNyb3NzIHVuaXRzL2FjdGlvbnMuCgkq KiBXaGVuIGV4
ZWN1dGluZyBhIGJ1aWxkIGluIHBhcmFsbGVsbCwgYW4gZW5naW5lIHNob3Vs ZCBzZXJpYWxp
emUgdGhlIGV2YWx1YXRpb24gKGJ1aWxkKSBvZiB0aGUKCSoqIHNwZWNpZmll ZCBlbGVtZW50
cy4gU2VyaWFsaXphdGlvbiBvZiBleGVjdXRpb24gbWF5IHNlcmlhbGl6ZSBt b3JlIHRoYW4g
d2hhdCBpcyBzcGVjaWZpZWQgYnV0IG5ldmVyIGxlc3MuCgkqKiBFYWNoIHN5 bmNocm9uaXpl
ZCBsaXN0IHNwZWNpZmllcyBhIGdyb3VwIHRoYXQgd2lsbCBiZSBzZXJpYWxp emVkLiBSZWZl
cmVuY2VzIGFyZSB0byBwYXJ0IG5hbWVzIGluIHRoaXMgdW5pdCwgb3IKCSoq IHRvIHBhcnQg
bmFtZXMgaW4gb3RoZXIgdW5pdHMuIAoJKioKCSoqIERJU0NVU1M6IGFsdGhv dWdoIHZlcnkg
dXNlZnVsLCBzdGF0ZW1lbnRzIHRoYXQgc3luY2hyb25pemVkIG9uIGludGVy ZmFjZS8qLCBh
bmQgb24gYWN0b3JzIGFyZSBhbHNvIHVzZWZ1bC4KCSoqIFN5bnRheCBzaG91 bGQgcHJvYmFi
bHkgYmUgeHBhdGgvcXVlcnkgbGlrZS4KCSovCQoJc3luY2hyb25pemUgYSxi LGM7CglzeW5j
aHJvbml6ZSBhL2EjeCxiL2IjeCxjL2M7CgkKCXN5bmNocm9uaXplIHsgYSxi LGM7IGQsZSxm
OyB9IAoJCgkvKiogUkVQT1NJVE9SSUVTCgkqKiBUaGUgcmVwb3NpdG9yeSBj bGF1c2UgZGVm
aW5lcyB0aGUgb3JkZXIgaW4gd2hpY2ggcmVwb3NpdG9yaWVzIGFyZSBzZWFy Y2hlZC4KCSoq
IFRoZXJlIGFyZSB0d28gZm9ybXMgb2YgZW50cmllcyAtIHRoZSBtb3N0IGNv bW1vbiBpcyBl
eHBlY3RlZCB0byBiZSB0aGUgc2hvcnQgZm9ybSwgd2hlcmUKCSoqIGJvdGgg dGhlIGxvY2F0
aW9uLCBhbmQgcmVwb3NpdG9yeSB0eXBlIGlzIHNwZWNpZmllZCB3aXRoIGEg VVJJLiBUaGUg
VVJJIHNjaGVtZSBpcyB1c2VkIHRvIHNlbGVjdAoJKiogYSByZXNvbHZlci4g Rm9yIGNhc2Vz
IHdoZXJlIHRoaXMgaXMgbm90IHBvc3NpYmxlLCB0aGUgbG9uZ2VyIGZvcm0g aXMgdG8gZGVj
bGFyZSB0aGF0IGEgcmVzb2x2ZXIgc2hvdWxkIGJlCgkqKiB1c2VkLCBhbmQg dGhlIGxvY2F0
aW9uIChhIGdlbmVyYWwgVVJMKSBpcyB0aGVuIHNldCB1c2luZyBhZHZpY2Ug KGlmIGluZGVl
ZCB0aGUgc2VsZWN0ZWQgcmVzb2x2ZXIgbmVlZHMgYSBsb2NhdGlvbikuCgkq KiAKCSoqIAoJ
Ki8KCXJlcG9zaXRvcmllcyB7CgkJICJodHRwOi8vYmFyL2ZlZSIgeyB9OwoJ CSAiaHR0cDov
L2Jhci9mb28iOwoJCSAiaHR0cDovL2Jhci9mdW0iOwoJCSByZXNvbHZlciBm b28uYmFyIHsK
CQkgCS8vIFN0YXRlbWVudHMgaGVyZSBhcmUgYWR2aWNlIHJlbGF0aXZlIHRv IGEgcmVzb2x2
ZXIuIChpLmUuICcuJyBpcyBhIHJlc29sdmVyKQoJCSAJLy8gCgkJIAlsb2Nh dGlvbj0iaHR0
cDo6Ly93d3cuc29tZXdoZXJlLmNvbSI7CgkJIAlhcGEgPSAxMDsKCQkgCWJv b2xlYW5GbGFn
ID0gMTA7CgkJIAlvcHRpb25zL2FkdmFuY2VkW2ZlYXR1cmVBIH49IlthLXpd KiJdLz9bYT4y
M10vYi8/PyB7CgkJIAkJb3B0aW9uMSA9IDEwOwoJCSAJCW9wdGlvbjIgPSAy MDsKCQkgCQlv
cHRpb24zID0gImhlbGxvIjsKCQkgCQl9OwoJCSAJfTsKCQkgfQoJYWR2aWNl IGltcG9ydF9B
ZHZpY2UgewoJICAgIC9yZXF1ZXN0c1tuYW1lfj0ib3JnLm15b3JnLioiXS9v cHRpb25zIHsK
CSAgICAgICAgc291cmNlPXRydWU7CgkgICAgICAgIG11dGFibGU9dHJ1ZTsK CSAgICAgICAg
fTsKCSAgICAvcmVzb2x1dGlvbnNbbmFtZX49Im9yZy5lY2xpcHNlLioiXS9v cHRpb25zIHsK
CSAgICAgICAgbG9jYXRpb24gPSAicGxhdGZvcm06L3BsdWdpbi8iOwoJICAg ICAgICB9OwoJ
fQkgCn0=
--------------050506050007010709020406--
Re: b3 build files DSL in XText - annotaded sample b3 file [message #491322 is a reply to message #491290] Wed, 14 October 2009 07:22 Go to previous messageGo to next message
Matthias Sohn is currently offline Matthias SohnFriend
Messages: 1268
Registered: July 2009
Senior Member
Looks like the forum application doesn't understand attachments and hence doesn't decode the base64 transfer-encoding. Could you post your samples as inline text ?
Re: b3 build files DSL in XText - annotaded sample b3 file [message #491333 is a reply to message #491290] Wed, 14 October 2009 07:52 Go to previous messageGo to next message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
Hi Henrik,
Lots of questions :-)

Properties:
property foo= "hello";
// a property can be set to null (but not immutable properties)
property foo;

Wouldn't it be better to explicitly assign null in this case? It looks like an uninitialized variable. So

property foo = null;

or
property foo = empty; // Since empty apparently is a keyword?


Expressions:
You have this expression in the file:

when (!target.platform != "sparc" && target.platform < "hpUx")

which I interpret as a not operation on a string which probably would result in an
UnsupportedOperationException?

How do we plan to handle expression type priorities? I.e. which one of these are true:

"4" + 2 == 6
"4" + 2 == "42"
"4" + 2 == Exception, different types of operands.

What does:

target.platform < "hpUx"

mean? If it's a lexical compare, is it sensitive to Locale? I can see use cases for both locale sensitive compare and
plain ASCII. Do we need additional operators for this?


Artifacts:

** Standard XText implementation allows a unary ^ before a keyword as an escape (Remove?)

I'd vote yes to that. I'd prefer if we quote keywords where needed (paths, requirements, etc.) and prohibits the use of
keywords as names in other places. Like Java.

You have an example:

"my.unit", "my.unit"; // unit is a keyword
my.^unit; // unit is keyword - standard XText grammar escape of keywords in ID

I understand why 'unit' needs to be quoted, but why do I need to quote 'my.unit'? Isn't that one single token? Can I write:

my . "unit" // (with spaces surrounding the dot)

?


NLS:
"aŒŠš"; // has NLS characters

What character encoding is used (related to the locale sensitive compare)?


Artifact paths:

/ a / b ; // is equivalent to /a/b - not /" a"/" b"

That looks really odd to me. I haven't seen any language to date that does that and I don't think we should either. It's
an incomprehensible syntax to most people. Perhaps you can have PATH recognized by the lexer and then specializations of
that (REFERENCE and REQUEST for instance, allowing a version and version range) also recognized? I.e. that:

requestElement:
PATH
| REFERENCE
| REQUEST
;

referenceElement:
PATH
| REFERENCE
;

artifactElement:
PATH

etc.

Group:
Regarding parallel or sequential execution. You have

// The keyword 'syncronized' declares that parallell execution of any part is dissallowed

this confuses me. synchronized usually mean that two threads cannot execute the same piece simultaneously. One must wait
for the other. So a synchronized group would be a group that you expect multiple threads to call on for execution and
that the threads must wait in line when that happens.

I would like to turn things around and say:

private sequential group foo {} // Execute the parts of this group sequentially (the default)
private parallel group foo {} // Allow parallel execution of the parts of this group

I.e. executing things in parallel is a conscious decision. We can have synchronized too of course, but I think it's
unusual that you'd want actions or groups that are not synchronized (in my sense of the word).

Action:
Your non-working example:

action test3 actor Test(test="test") provides a/b/"1"
{
// NON working example - need help with parser

// group input to one results
group {
a;
}
result b { b.txt; }
}
*/

How about turning it inside out, like this:

action test3 actor Test(test="test") provides a/b/"1"
{
result b { b.txt } with { group { a; } }
}

Since the result is at top, nested groups wouldn't work so your example:

action Test actor Test(test="test") provides a/b/"1"
{
group { a;
} {
group { x; } { result b { b; } }
result b {b;}
group { x; } { result b { b; } }
}
}

would need to be rewritten as:

action Test actor Test(test="test") provides a/b/"1"
{
result b { b; } with { group { a; x; } }
result b { b; } with { group { a } }
result b { b; } with { group { a; x; } }
}

which in my opinion vastly increases the readability. It becomes even more clear when you mix groups and properties:

action Test actor Test(test="test") provides a/b/"1"
{
result b { b; } with { group { a; x; } property foo="z80" }
result b { b; } with { group { a } }
result b { b; } with { group { a; x; } property foo="i8080" }
}

One argument in favor of your syntax is that repeating 'a' is cumbersome if it is complex. The counter argument to that
is; when that happens, just make 'a' a private group outside of the action.

Regards,
Thomas Hallgren
Re: b3 build files DSL in XText - annotaded sample b3 file [message #491335 is a reply to message #491322] Wed, 14 October 2009 07:55 Go to previous messageGo to next message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
Hi Matthias,
Here it is, in plain ISO8859-1 encoded text:

/*
** A .b3 file
** consists of import statements followed by a single "unit". This is analogous with a .java file having imports
** and a single language element (class, interface).
**
** This file is a sampler used to test syntax. The examples are not realistic (you will find plenty of a, b, c, fee and
foo...)
*/

/*
** COMMENTS
** Both single line and multi line comments are supported.
*/
// Single line comment
/* Multi line comment
*/

/*
** IMPORT
** Is used to import classes (just like in java). This is done so non qualified names can be used for classes
** DISCUSS: Imports are probably translated to meta requirements when resolving. As they are requirements on the
environment.
*/
import org.eclipse.b3.default.Resolvers.*;

/*
** UNIT
** A Unit is a Build Unit. It is used for several purposes:
** - as a file that describes "top level" requirements (what to import into a workspace, resolvers to use etc.)
** - as advice that extends meta data translation
** - as the meta data that describes a unit, when there is no other meta data
**
** A Unit has:
** - Properties
** - Provided Capabilities
** - Required Capabilities (and Meta Required Capabilities)
** - Parts (analogous with members in a class). There are four kinds of parts:
** - Artifacts (existing files)
** - Group (Aggregation of other parts)
** - Action (Production of new files (or side effect)
** - Result (A set of files produced by an Action ~= generated Artifacts)
** - Advice (Path/Predicate based access to elements that do not yet exist in the model). Used to set options, make
** overrides, etc.
** - Repositories - a configuration that is used to resolve (look up) units.
** - Synchronization - defines monitors across units that help solve issues in parallel builds
**
** A unit can be marked as synchronized - this means that requests to its parts are serialized.
** A unit can implement interfaces. These interfaces are "build time interfaces" and tells b3 about
** which parts it can expect. This also helps an author of extended components, and freshly created components
** comply with known build interfaces - i.e. this thing builds like an osgi.bundle.
*/
synchronized unit "my.unit" version 2.3 implements osgi.bundle, eclipe.ecore.model {

/* PROPERTIES
** Properties supports strings, integers, booleans, expressions and references to properties
*/
property foo= "hello";
// a property can be set to null (but not immutable properties)
property foo;
immutable property bar = 32;
immutable property bar = 32+10;

// checks if a calculation has the same value as a property
immutable property meaningful = 32+10 == the.meaning.of.life;

// a property can be "unset", that means that if it was set in this context, it will revert to
// it's value (if any) in an enclosing context.
//
unset property yellow.banana;

// Several properties can be set in a compound "properties" clause. It also works for unset.
// Note that the "property" keyword is no longer required per setting.
properties {
bar = "bar";
immutable politician = "oxymoron";
unset yellow.banana;
}

/* PROVIDES
** Provides clause is used to declare that the BuildUnit provides capabilities.
** A capability consists of interface/unitname and an optional /version at the end.
** If an interface, unitname or version requires use of reserved words or characters, the corresponding
** part is entered as a string (i.e. within " ").
** As with properties, there is a compound provides clause.
**
** Provide Capabilities can be filtered - some capabilities may only be provided under certain circumstances.
** This is declared with a leading when(BooleanExpression).
*/
provides osgi.bundle/bundlebar;
provides osgi.bundle/bundlebar/1.0;
provides {
osgi.bundle/barbara.bundle/2.0;
eclipse.feature/inflateable.pleasure/6.6.6;
when(target.platform == platforms.win32) native.thing/windowsInstaller/12.23.r1234;
}
provides when(target.platform == platforms.win32) native.thing/windowsInstaller/12.23.r1234;

/* REQUIRES
** Requires clause is used to declare that the BuildUnit requires certain capabilities.
** The differences between required and provided capabilities are that:
** - the version is always a range (althoug a single version means >= version
*/
requires osgi.bundle/air/1.0;
requires when (!target.platform != "sparc" && target.platform < "hpUx") osgi.bundle/pillow/3.0 ;
requires {
osgi.bundle/pillow/1.0;
when (a == b) osgi.bundle/blanket/1.0;
}

/* META REQUIRES
** With a leading meta keyword, the requiremens are requirements on the environment (i.e. on b3 itself)
** As an example, a meta requirement may be that a certain meta data provider is installed or it will be impossible to
** use this definition.
*/
meta requires osgi.bundle/air/1.0;
meta requires when (42 >= 32) osgi.bundle/pillow/"3.0";
meta requires {
osgi.bundle/pillow/1.0;
when (myorg.foo ~= "[a-z].*") osgi.bundle/blanket/1.0;
}

/* ARTIFACTS
** Artifact is a vector of path groups.
** A group of paths may have a base path - the rest of the paths in the group are relative to the
** base path.
** File names that include reserved words or reserved characters are entered within " "
** File names containing spaces must always be quoted, as the compiler removes whitespace from non strings.
** Standard XText implementation allows a unary ^ before a keyword as an escape (Remove?)
** Inclusion of a vector can be controlled with a leading when(BooleanExpression).
**
** VISIBILITY
** Visibility is either private or public (the default). Private means that the part is only accesable
** from within the b3 unit whene the part is declared.
**
** PROPERTIES
** It is possible to set (and unset) properties in the list using basic or compound property statements.
** These properties are set on the resulting path group vector and are available to the user of the
** set of files.
** Since file group vectors are merged, so will the properties. Use of immutable properties will guarantee
** that the property values set will surface (or an error will be generated if merging causes the value
** to change), but is ok if multiple vectors are tagged the same way.
**
** Note that individual property settings per file is not supported. To flag an individual file it is
** recommended to use dottiefied properties - example - mark the path /a/b as being little endian
** property org.myorg.fileinfo.endian.a.b=little.
**
** DISCUSS - is it of value to have properties/annotations per file?
**
*/
private artifacts test.a1 provides myorg.food/fruit.sallad/2.0, myorg.projectiles/fruit.salad
{
a; // a vector with one entry
a, b; // a vector with two entries
a [ b, c]; // a base path (a), with two relative paths in a vector
/a/b;
/ a / b ; // is equivalent to /a/b - not /" a"/" b"


// names that must be quoted
"unit"; // a keyword
"1a"; // does not look like a qualified name
"a b"; // has space in name
"aŒŠš"; // has NLS characters
"//f"; // looks like a comment
"123"; // is an integer

"my.unit", "my.unit"; // unit is a keyword
my.^unit; // unit is keyword - standard XText grammar escape of keywords in ID
when(target.platform == "osx") MacApp.app ;
when(true) banana.txt, pineapple.txt, mango.txt;
when (true) exotic [ rambustan.txt, tamarind.txt ];
a1 [apple.txt, "ban ana.txt"];
fee/apa.boo [ a/b/c.d, a.b.c.d, o/b/d ];
property apa="banan";
property defaultsToNull;
properties { a; b; }
}

// An empty artifacts vecor
artifacts empty {
}

/* ARTIFACTS PROVIDING CAPABILITIES
** It is possible to declare that the resulting path group vector is a capability layed out on disk.
** They layout can represent many capabilities at the same time.
*/
artifacts providesMany provides a/b/1.0, c/d/2.0, x/y/3.0 {a;}

/* GROUP
** A group is similar to artifacts in that it creates a path group vector, but it creates this
** by aggregating path group vectors from other parts.
** Just as with artifacts; the resulting path group vector can represent capabilities.
**
** The group consists of a list of required capabilities. The syntax is the same as for
** the units requires { } clause, with the following additions:
** - A trailing '#partname' is used after the requirement to pick a particular part.
** - A reference can be made to parts in the same build unit by using a single identifier
** - A reference to a required capability without a trailing '#partname' is taken as a reference to '#self', meaning the
** aggregation of all its public parts.
** - It is possible to define a closure where properties and advise are declared. They have downstream effect
** (i.e. when evaluating the part). The closure is defined using a trailing with { } statement.
** - A closure can be defined for several requirements at the same time by enclosing the requirements in curly
** brackets {r r r} with { }
** - A leading void keyword indicates that the resulting path group vector from the evaluation of the part should
** not be included in the resulting path group vector.
** - The result of individual part evaluation, or evaluation of a group of requirements can be assigned to an alias.
** The alias is a property that is included in the resulting path group vector. This makes it possible for a user
** of the vector to reference a particular part of the set.
** - void and alias can be used at the same time, but for a group that represents a part (as in this case), neither the
** property nor its value survive the group's context. For other types of grouping (in actions), this is very
** valuable, but in a group part, this construct simply has no effect.
**
** WITH CLOSURE
** In the with closure, properties can be set using the single or compound properties statements.
** Advice can be set using advice syntax.
**
*/
private synchronized group "foo/bar" provides myorg.food/fruit.coctail/2.0, a / b / "2.3"
{
a; // referense to part in self
foo/bar; // reference to #self in interface foo, name bar
a/a#b; // reference to #b in interface a, name a
fubbla= osgi.bundle/foo.bar/1.0; // sets the property fubbla to to the pathGroup reference in runtime - typically not
used in groups
osgi.bundle/fee.fum/1.0#jars;
osgi.bundle/zeBundle/1.0#jars;
void a/a#b; // only performed for side effect
void alias.nbr1 = b; // only performed for side effect, but sets a property to the result (that is then ignored)
a/a#b with { property nice = "yes"; }; // sets and passes the property nice downsteam
a/a#b with { // passes several properties downstream.
properties {
a="2"; b="2"; c="3";
}
};
// includes result of three references, all with the same set of downstream properties
{ a/a#b; a/b#c; a/c#d; } with { property target.platform="sparc"; };
// sets an alias on a non included result, result is a group of items with downstream properties
void aliasedButNotIncluded = { a/a#b; a/b#c; a/c#d; } with { property foo="hpux"; };
// sets an alias on an included item, result is a group of items with downstream properties, a nested alias is set
aliasedAndIncluded = { alias.nbr3=a/a#b; a/b#c; a/c#d; } with { property foo="hpux"; };

// inclusion can be filtered with a boolean expression - here "true" makes it always included
when (true) { a/a#b; a/b#c; a/c#d; } with { property foo="z80"; };
// filtering - here, never ever included because boolean value is false
when (false) a/a#b;
// a non included and filtered reference to a/a#b
void when (true) a/a#b;
}

// The keyword 'syncronized' declares that parallell execution of any part is dissallowed
private synchronized group foo {}
public synchronized group foo {}
private group foo {}
group foo {}
synchronized group foo {}


/*
** ACTION
** An action has an embedded group declaration that defines the input to an actor. The actor is told to
** produce the result(s) decalred for the input group. Input groups and results can be nested.
** This is used to decalre common input, input for a group of results (such as input to actions for linux),
** and then specific input for building a linx flavor, for different windowing systems etc.
**
** The result can consist be declared with public or private visibility, or follow the visibility of the action.
** Public result are available as first class members of the unit (even if the enclosing action is private).
** Public result must be named. Private result must be named if it should be referenced individually (and not as
** part of the action's result).
**
** The actor is declared in the preamble of the action part and is instantiated once.
** Parameters to the actor instantiation can be passed with parentheses using named parameters
** (order is not important).
** - An action can provide the resulting path group vector as provided capabilities
**
** Aliases
** Aliases for input parts have an additional meaning in actions - these properties are available to the actor.
** This means that the combination of void alias={ } is meaningful (as opposed to when used in a group part).
**
** RESULT
** Result clauses behave like artifact parts, but they typically refer to files that were produce by the actor.
** Properties in these sets may be set by the actor. This means that an actor can pass information back - such as
** a version qualifier, location of certain files on disk etc.
**
*/
private synchronized action foo
actor ZipActor(serviceKey="WooHoo - woot")
provides myorg.food/fruit.coctail/2.0
{
group {
a; // defaults to #self
when (apa > 11) a/a#b;
osgi.bundle/foo.bar/"1.2.3.qualifier#,./"#jars; // defaults to #self


osgi.bundle/fee.fum/1.0#jars;
osgi.bundle/zeBundle#jars;
void a/a#b; // only performed for side effect
void alias.nbr1 = a/a#b; // only performed for side effect
a/a#b with { property nice = "yes"; };
a/a#b with {
properties {
a="2"; b="2"; c="3";
}
};
{ a/a#b; a/b#c; a/c#d; } with { property target.platform="sparc"; };
void { a/a#b; a/b#c; a/c#d; } with { property foo="hpux"; };
void alias.nbr2 = { alias.nbr3=a/a#b; a/b#c; a/c#d; } with { property foo="hpux"; };
when (true) { a/a#b; a/b#c; a/c#d; } with { property foo="z80"; };
when (false) a/a#b;
void when (true) a/a#b;
}{
result a { a; }
}
}
action test1 actor Test(test="test") provides a/b/"1"
{ // no dependencies, no special input, just "do it and produce result"
result b { b.txt; }
}
action test2 actor Test(test="test") provides a/b/"1"
{ // no dependencies, no special input, just "do it and produce result"
// but set a properties
//
result b { b.txt; } with { property target.platform = "win32"; }
}

/* NON WORKING SYNTAX, due to problems in language specification. Help Wanted.

action test3 actor Test(test="test") provides a/b/"1"
{
// NON working example - need help with parser

// group input to one results
group {
a;
}
result b { b.txt; }
}
*/

action test3 actor Test(test="test") provides a/b/"1"
{
// group input to one or several results
group { a; }
{
result b { b.txt; }
}
}
action Test actor Test(test="test") provides a/b/"1"
{
group { a;
} {
result b { b; }
result b { b; }
result b { b; }
}
}
action Test actor Test(test="test") provides a/b/"1"
{
group { a;
} {
group { x; } { result b { b; } }
result b {b;}
group { x; } { result b { b; } }
}
}

action makeWin32Zip
actor ZipActor(serviceKey="tjoho")
provides foodstuff.sallad/fruitsallad/1.0, x/b/"23"
{
group {
{ site = createSite; } with { property target.platform="win32";};
}{
group {
extraInput = a/a/2.0#jarFiles;
}{
public result makeSomeoneHappy {
apa/banan.zip ;
when(true) chimp/banan.zip ;
} with { properties { target.platform = "win32"; prerequisite.flag = "a#b"; }}

group {
special;
}{
when (true) private result a { a;} with { /* for a only */ }
when (true) result b {} with { /* for b only */ }
} with { /* for a and b */ }
}
}
}

/** Synchronize clauses allows syncronization to be specified across units/actions.
** When executing a build in parallell, an engine should serialize the evaluation (build) of the
** specified elements. Serialization of execution may serialize more than what is specified but never less.
** Each synchronized list specifies a group that will be serialized. References are to part names in this unit, or
** to part names in other units.
**
** DISCUSS: although very useful, statements that synchronized on interface/*, and on actors are also useful.
** Syntax should probably be xpath/query like.
*/
synchronize a,b,c;
synchronize a/a#x,b/b#x,c/c;

synchronize { a,b,c; d,e,f; }

/** REPOSITORIES
** The repository clause defines the order in which repositories are searched.
** There are two forms of entries - the most common is expected to be the short form, where
** both the location, and repository type is specified with a URI. The URI scheme is used to select
** a resolver. For cases where this is not possible, the longer form is to declare that a resolver should be
** used, and the location (a general URL) is then set using advice (if indeed the selected resolver needs a location).
**
**
*/
repositories {
"http://bar/fee" { };
"http://bar/foo";
"http://bar/fum";
resolver foo.bar {
// Statements here are advice relative to a resolver. (i.e. '.' is a resolver)
//
location="http:://www.somewhere.com";
apa = 10;
booleanFlag = 10;
options/advanced[featureA ~="[a-z]*"]/?[a>23]/b/?? {
option1 = 10;
option2 = 20;
option3 = "hello";
};
};
}
advice import_Advice {
/requests[name~="org.myorg.*"]/options {
source=true;
mutable=true;
};
/resolutions[name~="org.eclipse.*"]/options {
location = "platform:/plugin/";
};
}
}
Re: b3 build files DSL in XText - annotaded sample b3 file [message #491365 is a reply to message #491333] Wed, 14 October 2009 11:02 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
Hi,
comments in-line...

- henrik

On 10/14/09 9:52 AM, Thomas Hallgren wrote:
> Lots of questions :-)
>
Feedback apreciated :-)

> Properties:
> property foo= "hello";
> // a property can be set to null (but not immutable properties)
> property foo;
>
> Wouldn't it be better to explicitly assign null in this case? It looks
> like an uninitialized variable. So
>
You suggested having uninitialized properties. The rationale was to use
them as part of result path group vectors. You agreed that that they
could be set to null in that case. I agree that it is not very good...
(read on)...
> property foo = null;
>
> or
> property foo = empty; // Since empty apparently is a keyword?
>
I think we should not allow uninitialized properties.
We can use "null" if we want to, "empty" is not a keyword, it is the
name of a property in the sample :-).

However, there is one more option that also increases quality, and that
is to set the property to a special keyword that indicates that it is
expected to be set by an action. Then, on return from the actor, a check
can be made that the property was actually set.

For instance, if there is an expectancy that the actor will assign a
revision number or similar and it doesn't - then sometimes later, things
will appear broken as the property is uninitialized.

One possibility, would be to allow the following in result path group
vector (but only there):

immutable property revision;

Since immutable means it can't be changed - it is clear that this is not
allowed, and hence, that a value must be provided. The above is
different from:

immutable property revision = "r101010";

Since this forbids the actor to change the value. And it is different from:

property revision = "r101010";

which specifies revision with a default value, that the actor may
override. If specifying:

property revision;

Then, this would mean - revision implicetly set to null, actor may or
may not set it. I think this is likely to cause problems (that are much
harder to find), and suggest that we do not support this at all anywhere.

>
> Expressions:
> You have this expression in the file:
>
> when (!target.platform != "sparc" && target.platform < "hpUx")
>
> which I interpret as a not operation on a string which probably would
> result in an
> UnsupportedOperationException?
>
Yes, the expression would throw an exception. I made it like that in the
sample on purpose to trigger the discussion on how to handle such issues :)

> How do we plan to handle expression type priorities? I.e. which one of
> these are true:
>
> "4" + 2 == 6
> "4" + 2 == "42"
> "4" + 2 == Exception, different types of operands.
>
We can:
- Have generality on types and convert to the more general type -
int/string becomes int. Since we don't have float, double and other
types (although we may add collections) it is not that hard.
- Only use string. (Don't like this solution though).

So, I opt for:

"4" + 2 = "42"

It is more an issue of interpreting properties set in properties files,
or from the command line. How is the distinction made between a string
and an int property there?

A related question. Should we support "real" (i.e. double). ?

> What does:
>
> target.platform < "hpUx"
>
> mean? If it's a lexical compare, is it sensitive to Locale? I can see
> use cases for both locale sensitive compare and plain ASCII. Do we need
> additional operators for this?
>
Very good question(s):

a) It would mean lexical compare if we implement it ;)

b) I see two ways of implementing specification of NLS

- having a bunch of operators that say that the compare is NLS, say @<
@> @<= @>= @== @!= (ugly, and makes it hard to specify locale).

- handle NLS strings as a type more general than string.
@ "This is a NLS String in current locale"
@us_EN "This is a NLS String in US English"
@se_SE "En svensk tiger"

The following would then apply:

"x" < @ "y"

"x" is converted to NLS in current locale before compare.

@ca_FR "Je suis une ficelle rouge"
==
@fi_FI "Olen punainen merkkijono"

Would throw an exception since the locale's are different. The fact that
the two strings mean the same thing could possibly be detected by
feeding them to google translator :) - but lets leave this feature
outside the scope of b3 :)

Any Babel people reading this... suggestions?

>
> Artifacts:
>
> ** Standard XText implementation allows a unary ^ before a keyword as an
> escape (Remove?)
>
> I'd vote yes to that. I'd prefer if we quote keywords where needed
> (paths, requirements, etc.) and prohibits the use of keywords as names
> in other places. Like Java.
>
I think so too.

> You have an example:
>
> "my.unit", "my.unit"; // unit is a keyword
> my.^unit; // unit is keyword - standard XText grammar escape of keywords
> in ID
>
> I understand why 'unit' needs to be quoted, but why do I need to quote
> 'my.unit'? Isn't that one single token? Can I write:
>
> my . "unit" // (with spaces surrounding the dot)
>
yes, since there is a bug when letting the parser do the lexing.
The use of hidden() in parser rules prohibits WS globbing in the lexer,
and thus spaces in the QualifiedName will generate syntax errors.
However, since the parser handles this instead of the lexer, it will see
"unit" as a keyword token.

Handling QualifiedName as a lexer token solves this. It however has
other consequences as it will gobble all occurrences of ID('.' ID)*
which makes it mask ID - there are places where a non Qualified ID is
wanted. The check could perhaps be deferred to data type checking, but
may cause problems. Currently there is the need to use ID (instead of
Qualified ID) in two places:

- in version which makes use of:
AlfanumSym : (ID | INT) (Separator|ID|INT)* ;
- in expressions where (Expression '.' ID) is a method call on
a LHS expression.

So, right now - I handle QualifiedName including WS globbing, since if I
turn it on, things are screwed up. If I solve it in the lexer I get
other problems.

Would prefer a solution where keywords in subparts of QualifiedName are
not recognized as keywords, provided we solve parsing of version and
method call (subject to debate if method call should be supported).

> NLS:
> "aŒŠš"; // has NLS characters
>
> What character encoding is used (related to the locale sensitive compare)?
>
Good question. What do you propose?
a) That we support one, and only one encoding of b3 files (like UTF8).
If so, which one?
b) That encoding is declared in the file, but with a default of a
standard encoding?

>
> Artifact paths:
>
> / a / b ; // is equivalent to /a/b - not /" a"/" b"
>
> That looks really odd to me. I haven't seen any language to date that
> does that and I don't think we should either.

Agree - it is a consequence of the hidden() bug in xtext. Should not be
allowed IMO.

> It's an incomprehensible
> syntax to most people. Perhaps you can have PATH recognized by the lexer
> and then specializations of that (REFERENCE and REQUEST for instance,
> allowing a version and version range) also recognized? I.e. that:
>
As stated above, the problem is coming up with lexer rules that makes it
possible to parse:
- versions
- version ranges
- qualified names
- unqualified names
- ints
- file paths
- advice paths

I think this is quite difficult. If hidden() works, then the only
consequence is that user must string quote if a keyword token is found
inside the element.

BTW - if anyone happens to be a lexer guru, feel free to come up with a
sequence of lex rules that handles all of the above. Free Beer offered :)

> Group:
> Regarding parallel or sequential execution. You have
>
> // The keyword 'syncronized' declares that parallell execution of any
> part is dissallowed
>
> this confuses me. synchronized usually mean that two threads cannot
> execute the same piece simultaneously. One must wait for the other. So a
> synchronized group would be a group that you expect multiple threads to
> call on for execution and that the threads must wait in line when that
> happens.
>
That is how I also thought of this.

> I would like to turn things around and say:
>
> private sequential group foo {} // Execute the parts of this group
> sequentially (the default)
> private parallel group foo {} // Allow parallel execution of the parts
> of this group
>
> I.e. executing things in parallel is a conscious decision. We can have
> synchronized too of course, but I think it's unusual that you'd want
> actions or groups that are not synchronized (in my sense of the word).
>
I can replace synchronized with sequential, and have that be the
default. That works for me language wise. BUT - in practice it makes the
mechanism useless as every component would then be specified to be
sequential (if that is the default).

So - I propose the following: It is parallel by default, and the
keywords are sequential and parallel.

And, agree that java synchronized semantics is always on. It is quite
meaningless to have a compiler compile the same thing to the same
location more than once at the same time. The only exception would be
some special actions - but that would be very special, and they can just
as well always be synchronized too.

> Action:
> Your non-working example:
>
> action test3 actor Test(test="test") provides a/b/"1"
> {
> // NON working example - need help with parser
>
> // group input to one results
> group {
> a;
> }
> result b { b.txt; }
> }
> */
>
> How about turning it inside out, like this:
>
> action test3 actor Test(test="test") provides a/b/"1"
> {
> result b { b.txt } with { group { a; } }
> }
>
I like that, and will make the changes. Agree with your reasoning.
The complex structure one has to write to get nested groups is not easy
to read anyway. Prefer the slight overhead for the complex case as it is
much clearer what you are doing. And, it removes the confusion over how
many times the actor should be invoked.

One addition is that it should be possible to specify several results
with a following with clause - i.e.:

{ result{} result{} } with { }
action - group - result syntax [message #491374 is a reply to message #491333] Wed, 14 October 2009 11:42 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
From the b3 DSL discussion... breaking it out...

On 10/14/09 9:52 AM, Thomas Hallgren wrote:

> Action:
> action Test actor Test(test="test") provides a/b/"1"
> {
> result b { b; } with { group { a; x; } property foo="z80" }
> result b { b; } with { group { a } }
> result b { b; } with { group { a; x; } property foo="i8080" }
> }
>
After thinking a bit, I think this syntax is slightly confusing. The
properties set would have no effect on the evaluation of the group.

For example:
result b { b; } with {
property bar="10";
group { a; x; }
property foo="i8080"
}

.... may be interpreted as the property bar being set in the scope of
group evaluation. Are you ok with this potential confusion?

The alternative would be to keep the group outside of the with clause.
In that case it would make most sense to do it as follows:

result {} with {} group {}

Since
result {} group {} with {}

Looks like the with clause sets the properties for the group closure.
Currently, a with clause on the group is not supported - you would have
to use the following

group { {x; y; z;} with {} }

to set a closure on all the stuff in the group. An alternative is

result {} with {} group {} with {}

where the closures are optional.

I think that is a better solution.

Thoughts?
- henrik
Re: b3 build files DSL in XText - annotaded sample b3 file [message #491377 is a reply to message #491365] Wed, 14 October 2009 11:57 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
On 10/14/09 1:02 PM, Henrik Lindberg wrote:

Typo !!

> - in expressions where ((Expression '.' ID) is a method call on
> a LHS expression.
>
Should have been:

- in expressions where ((Expression '.' ID) '(' Parameters* ')') is a
method call on a LHS expression.

- henrik
Re: b3 build files DSL in XText - annotaded sample b3 file [message #491404 is a reply to message #491365] Wed, 14 October 2009 12:58 Go to previous messageGo to next message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
More comments inline...

On 10/14/2009 01:02 PM, Henrik Lindberg wrote:
>> Properties:
>> property foo= "hello";
>> // a property can be set to null (but not immutable properties)
>> property foo;
>>
>> Wouldn't it be better to explicitly assign null in this case? It looks
>> like an uninitialized variable. So
>>
> You suggested having uninitialized properties. The rationale was to use
> them as part of result path group vectors. You agreed that that they
> could be set to null in that case. I agree that it is not very good...
> (read on)...
>
I remember that discussion. There's a subtle difference between declaring an expectation that a property will be part of
a result and actually declaring one (read on)...

> However, there is one more option that also increases quality, and that
> is to set the property to a special keyword that indicates that it is
> expected to be set by an action. Then, on return from the actor, a check
> can be made that the property was actually set.
>
> For instance, if there is an expectancy that the actor will assign a
> revision number or similar and it doesn't - then sometimes later, things
> will appear broken as the property is uninitialized.
>
> One possibility, would be to allow the following in result path group
> vector (but only there):
>
> immutable property revision;
>
> Since immutable means it can't be changed - it is clear that this is not
> allowed, and hence, that a value must be provided. The above is
> different from:
>
> immutable property revision = "r101010";
>
> Since this forbids the actor to change the value. And it is different from:
>
> property revision = "r101010";
>
> which specifies revision with a default value, that the actor may
> override. If specifying:
>
> property revision;
>
> Then, this would mean - revision implicetly set to null, actor may or
> may not set it. I think this is likely to cause problems (that are much
> harder to find), and suggest that we do not support this at all anywhere.
>
That would mean that we have to allow:

immutable property revision;

but not

property revision;

in a result. I think that is hard to understand. In that case it's better to say that the lack of assignment means that
the actor will (and must) provide a value. Even better perhaps using a keyword as you suggest.

property revision = derived;

or similar but then it becomes unclear how to set a default. Perhaps it could look like this:

property revision = derived("r101010");

alternatively, we turn it around:

derived property revision;

and with a default:

derived property revision = "r101010";


>> How do we plan to handle expression type priorities? I.e. which one of
>> these are true:
>>
>> "4" + 2 == 6
>> "4" + 2 == "42"
>> "4" + 2 == Exception, different types of operands.
>>
> We can:
> - Have generality on types and convert to the more general type -
> int/string becomes int. Since we don't have float, double and other
> types (although we may add collections) it is not that hard.
> - Only use string. (Don't like this solution though).
>
> So, I opt for:
>
> "4" + 2 = "42"
>
Agree. That's also what Java does.


> It is more an issue of interpreting properties set in properties files,
> or from the command line. How is the distinction made between a string
> and an int property there?
>
> A related question. Should we support "real" (i.e. double). ?
>
I believe we should. It's simple enough.


>> NLS:
>> "aŒŠš"; // has NLS characters
>>
>> What character encoding is used (related to the locale sensitive
>> compare)?
>>
> Good question. What do you propose?
> a) That we support one, and only one encoding of b3 files (like UTF8).
> If so, which one?
> b) That encoding is declared in the file, but with a default of a
> standard encoding?
>
a) sounds simpler. We can always implement b) later should there be a demand for it.


>>
>> Artifact paths:
>>
>> / a / b ; // is equivalent to /a/b - not /" a"/" b"
>>
>> That looks really odd to me. I haven't seen any language to date that
>> does that and I don't think we should either.
>
> Agree - it is a consequence of the hidden() bug in xtext. Should not be
> allowed IMO.
>
OK, let's revisit all issues related to WS once we have a better understanding on how to deal with this bug.

> I can replace synchronized with sequential, and have that be the
> default. That works for me language wise. BUT - in practice it makes the
> mechanism useless as every component would then be specified to be
> sequential (if that is the default).
>
Why? There's nothing stopping you from running different actions in parallel even though these actions in themselves are
both synchronized and sequential. It works as long as you don't try to run the same group or action simultaneously using
different threads.


> So - I propose the following: It is parallel by default, and the
> keywords are sequential and parallel.
>
Not too fond of having things running in parallel by default. I think most builds are inherently sequential and will
break when running things in parallel. Some specific tasks can execute in parallel but IMO, that's the exception and you
should declare them if needed, not the opposite.

- thomas
Re: action - group - result syntax [message #491406 is a reply to message #491374] Wed, 14 October 2009 13:04 Go to previous messageGo to next message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
On 10/14/2009 01:42 PM, Henrik Lindberg wrote:
> From the b3 DSL discussion... breaking it out...
>
> On 10/14/09 9:52 AM, Thomas Hallgren wrote:
>
>> Action:
>> action Test actor Test(test="test") provides a/b/"1"
>> {
>> result b { b; } with { group { a; x; } property foo="z80" }
>> result b { b; } with { group { a } }
>> result b { b; } with { group { a; x; } property foo="i8080" }
>> }
>>
> After thinking a bit, I think this syntax is slightly confusing. The
> properties set would have no effect on the evaluation of the group.
>
> For example:
> result b { b; } with {
> property bar="10";
> group { a; x; }
> property foo="i8080"
> }
>
> ... may be interpreted as the property bar being set in the scope of
> group evaluation. Are you ok with this potential confusion?
>
Perhaps my proposed 'derived' keyword would make the distinction clearer?


> The alternative would be to keep the group outside of the with clause.
> In that case it would make most sense to do it as follows:
>
> result {} with {} group {}
>
> Since
> result {} group {} with {}
>
> Looks like the with clause sets the properties for the group closure.
> Currently, a with clause on the group is not supported - you would have
> to use the following
>
> group { {x; y; z;} with {} }
>
> to set a closure on all the stuff in the group. An alternative is
>
> result {} with {} group {} with {}
>
> where the closures are optional.
>
> I think that is a better solution.
>
The keyword 'with' suggests that whatever is enclosed is input to the actor. That includes the group IMO. An alternative
to my 'derived' keyword that would solve the input/output property issue would be:

result {} with { group{} property ... } defines { property ... }

- thomas
derived properties... [message #491431 is a reply to message #491404] Wed, 14 October 2009 14:40 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
Splitting this up into smaller subthreads...

On 10/14/09 2:58 PM, Thomas Hallgren wrote:
> derived property revision;
>
> and with a default:
>
> derived property revision = "r101010";
>
I like that - an additional keyword. But I think it is fine.

- henrik
Re: action - group - result syntax [message #491447 is a reply to message #491406] Wed, 14 October 2009 15:45 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
On 10/14/09 3:04 PM, Thomas Hallgren wrote:
> On 10/14/2009 01:42 PM, Henrik Lindberg wrote:
>> From the b3 DSL discussion... breaking it out...
>>
>> On 10/14/09 9:52 AM, Thomas Hallgren wrote:
>>
>>> Action:
>>> action Test actor Test(test="test") provides a/b/"1"
>>> {
>>> result b { b; } with { group { a; x; } property foo="z80" }
>>> result b { b; } with { group { a } }
>>> result b { b; } with { group { a; x; } property foo="i8080" }
>>> }
>>>
>> After thinking a bit, I think this syntax is slightly confusing. The
>> properties set would have no effect on the evaluation of the group.
>>
>> For example:
>> result b { b; } with {
>> property bar="10";
>> group { a; x; }
>> property foo="i8080"
>> }
>>
>> ... may be interpreted as the property bar being set in the scope of
>> group evaluation. Are you ok with this potential confusion?
>>
> Perhaps my proposed 'derived' keyword would make the distinction clearer?
>
Well, it helps with a different issue - the distinction between
properties set inside the result body (that was not shown in this
example). I was pointing out a closure problem.

The mix of group and properties inside the with is what is causing the
trouble. The properties set there are in the closure of the result, and
not in the closure of evaluating the group.


> The keyword 'with' suggests that whatever is enclosed is input to the
> actor. That includes the group IMO. An alternative to my 'derived'
> keyword that would solve the input/output property issue would be:
>
> result {} with { group{} property ... } defines { property ... }

I don't like the with{ group{} } construct, as it mixes properties,
advice and group - it is confusing what exactly the apply to. Also not
fond of the "defines property" at the end as I want to have the same
mechanism everywhere, and it would have an effect on artifacts. I like
it the way it is.

If with{} should apply to both result and group, and always do so, then
I suggest

result{} group{} with{}

Then, it is not possible to have different sets of properties and advice
for the group and the result. (Which could be useful to specify
"agnostic group", "specific result" for instance).

An alternative, if we want to support this - i.e.

result{} with {} group with{}

Then we just need to specify that the group closure surrounds the result
closure.

Example:

result {}
with {target.platform="sparc"}
group { buildSite }
with {target.platform = "*" useBuild="N12345" }

Which works well with a compound result

{ result a {} with { target.platform="sparc" }
result b {} with { target.platform="z80"
} group { buildSite } with {target.platform="*" }


This would present target.platform = "*" and useBuild="N12345" to the
closure when evaluating the group. And present target.platform="sparc"
useBuild="N12345" when calling the actor for a, and with
target.platform="z80" useBuild="N12345" when calling the actor for b.

Most commonly used would be:
result{} group{} with {}

As you most likely would want the same properties in both cases.

Regards
- henrik
Re: action - group - result syntax [message #491451 is a reply to message #491447] Wed, 14 October 2009 15:56 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
Typo - sorry
> { result a {} with { target.platform="sparc" }
> result b {} with { target.platform="z80"
> } group { buildSite } with {target.platform="*" }
>

{ result a {} with { target.platform="sparc" }
result b {} with { target.platform="z80"}
} group { buildSite } with {target.platform="*" }

> Regards
> - henrik
Re: action - group - result syntax [message #491463 is a reply to message #491451] Wed, 14 October 2009 17:17 Go to previous messageGo to next message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
On 10/14/2009 05:56 PM, Henrik Lindberg wrote:
>
> Typo - sorry
>> { result a {} with { target.platform="sparc" }
>> result b {} with { target.platform="z80"
>> } group { buildSite } with {target.platform="*" }
>>
>
> { result a {} with { target.platform="sparc" }
> result b {} with { target.platform="z80"}
> } group { buildSite } with {target.platform="*" }
>
I think one thing that confuses me with this syntax is the fact that a group is also a closure (a property scope). Let's
remove that for a second (I'll come back to that).

I like the idea that the actor produces a 'result' 'with' given input. The input being both groups and properties. So to
me, the 'result' and 'with' are tightly bound.

I think that:

action products ... {
result a{} with { group { buildSite }, property target.platform="sparc" }
result b{} with { group { buildSite }, property target.platform="z80" }
}

is much clearer than:


action products ... {
{ result a {} with { target.platform="sparc" }
result b {} with { target.platform="z80"}
} group { buildSite }
}

even if the latter is more compact. The closure for the 'buildSite' group is lost here however. What happens if we
introduce that as separate specialization? I.e.

closure a {
group { buildSite }
property target.platform="*"
}

or

closure a {
group { buildSite }
properties { target.platform="*"; ... }
}


I think that is more clear than:

group a { buildSite }
with { target.platform="*" }

Using the former syntax, we can also establish one important difference between 'closure' and 'with':

- The 'closure' propagates the properties to the 'group' that it contains.
- The 'with' just defines groups and properties that are input to the actor. The properties are *not* propagated to the
group. This means that we can express:

result a{} with { property target.platform="sparc"; closure { group { buildSite }; property target.platform="*" } };

OR, spelled out:

closure buildSiteEnvelope {
group { buildSite }
property targetPlatform="*"
}

result a{} with { property target.platform="sparc" group { buildSiteEnvelope } }

Another thought that strikes me when I read that syntax is that perhaps 'using' is a better keyword then 'with'. The
full products example could then be written as:

action buildSite ... {
result using { properties { target.platform="*"; ... } group { <whatever artifacts needed> } }
}

action products ... {
result a using { group { buildSite }; properties { target.platform="sparc"; ... }; }
result b using { group { buildSite }; properties { target.platform="z80"; ... }; }
}

OR

action buildSite ... {
result using { group { <whatever groups needed> } } // Look mum, no properties
}

action products ... {
// We overrided the target.platform for the actor invocation only. Not propagated to the buildSite group.
result a using { group { buildSite } properties { target.platform="sparc"; ... } }
result b using { group { buildSite } properties { target.platform="z80"; ... } }
}

closure buildAll {
group { products; }
properties { target.platform="*"; ... } // Here we set the default TP
}


Thoughs?

- thomas
Re: b3 build files DSL in XText - annotaded sample b3 file [message #491507 is a reply to message #491365] Wed, 14 October 2009 20:03 Go to previous messageGo to next message
Sven Efftinge is currently offline Sven EfftingeFriend
Messages: 1823
Registered: July 2009
Senior Member
Hi all,

some comments inlined.

Henrik Lindberg wrote:
>> Artifacts:
>>
>> ** Standard XText implementation allows a unary ^ before a keyword as an
>> escape (Remove?)
>>
>> I'd vote yes to that. I'd prefer if we quote keywords where needed
>> (paths, requirements, etc.) and prohibits the use of keywords as names
>> in other places. Like Java.
>>
> I think so too.

Why do you want to constrain that?
It would just make your language more complicated because you need two
different versions of an identifier (an escapeable an a non-escapeable).
What kind of harm could one do with the escape character?

>
>> You have an example:
>>
>> "my.unit", "my.unit"; // unit is a keyword
>> my.^unit; // unit is keyword - standard XText grammar escape of keywords
>> in ID
>>
>> I understand why 'unit' needs to be quoted, but why do I need to quote
>> 'my.unit'? Isn't that one single token? Can I write:
>>
>> my . "unit" // (with spaces surrounding the dot)
>>
> yes, since there is a bug when letting the parser do the lexing.
> The use of hidden() in parser rules prohibits WS globbing in the lexer,
> and thus spaces in the QualifiedName will generate syntax errors.
> However, since the parser handles this instead of the lexer, it will see
> "unit" as a keyword token.
>
> Handling QualifiedName as a lexer token solves this. It however has
> other consequences as it will gobble all occurrences of ID('.' ID)*
> which makes it mask ID - there are places where a non Qualified ID is
> wanted. The check could perhaps be deferred to data type checking, but
> may cause problems. Currently there is the need to use ID (instead of
> Qualified ID) in two places:
>
> - in version which makes use of:
> AlfanumSym : (ID | INT) (Separator|ID|INT)* ;
> - in expressions where (Expression '.' ID) is a method call on
> a LHS expression.
>
> So, right now - I handle QualifiedName including WS globbing, since if I
> turn it on, things are screwed up. If I solve it in the lexer I get
> other problems.
>
> Would prefer a solution where keywords in subparts of QualifiedName are
> not recognized as keywords, provided we solve parsing of version and
> method call (subject to debate if method call should be supported).

I highly recommend to stick with parser rules here.
Are you aware of the fact that in most programming languages (Java
incl.) qualified names are parsed exactly like that?
I.e. you can write

package foo . /* fddfdf */ stuff;

but can't

package foo.bar.class;

But is this really a problem?

That said, we'll of course fix the hidden()-bug ASAP.

>
>> It's an incomprehensible
>> syntax to most people. Perhaps you can have PATH recognized by the lexer
>> and then specializations of that (REFERENCE and REQUEST for instance,
>> allowing a version and version range) also recognized? I.e. that:
>>
> As stated above, the problem is coming up with lexer rules that makes it
> possible to parse:
> - versions
> - version ranges
> - qualified names
> - unqualified names
> - ints
> - file paths
> - advice paths
>
> I think this is quite difficult. If hidden() works, then the only
> consequence is that user must string quote if a keyword token is found
> inside the element.
>
> BTW - if anyone happens to be a lexer guru, feel free to come up with a
> sequence of lex rules that handles all of the above. Free Beer offered :)

The problem with implementing all these as lexer rules is not defining
the rule, but that the lexing is completely context free. Having lots of
lexer rules, which don't shadow each other is often just impossible and
can't be solved.
For no beer in the world, unfortunately ;-)

So my advice here is again, to use parser rules and I'ld even allow
whitespace and comments inbetween if it is not ambigous.
People are usually smart enough to layout their scripts in a readable way.

If you want to guide the user you can add warnings or even errors in te
validation phase. That also allows for nicer error messages.

if you have any technical questions regarding Xtext, just use our
newsgroup.
We're looking forward to b3 :-)

Cheers,
Sven

--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
Re: action - group - result syntax [message #491542 is a reply to message #491463] Wed, 14 October 2009 22:54 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
On 10/14/09 7:17 PM, Thomas Hallgren wrote:
> On 10/14/2009 05:56 PM, Henrik Lindberg wrote:

>> { result a {} with { target.platform="sparc" }
>> result b {} with { target.platform="z80"}
>> } group { buildSite } with {target.platform="*" }
>>
> I think one thing that confuses me with this syntax is the fact that a
> group is also a closure (a property scope). Let's remove that for a
> second (I'll come back to that).
>
> I like the idea that the actor produces a 'result' 'with' given input.
> The input being both groups and properties. So to me, the 'result' and
> 'with' are tightly bound.
>
> I think that:
>
> action products ... {
> result a{} with { group { buildSite }, property target.platform="sparc" }
> result b{} with { group { buildSite }, property target.platform="z80" }
> }
>
I don't like that because the group is out of band wrt. the order in the
with clause. The rest of the statements, when executed, are done in the
order they are presented.

with { property a = 10; property b = a + 10; }

Makes property b have the value 20.

If you mix this with a group, which may have when() filters that
references properties, you may think that properties have the values as
computed in the sequence.

result a with {
property a = 10;
group {
derived property a = 10;
when(a == 10) x;
when(a == 20) y;
when(a == 30) z;
derived property a = a + 20;
}
property a = 20;
}

This will result in a == 20 to the actor.
What is the content of the group? x or y?
I can argue all three cases depending on the order the engine performs
the evaluations.

I also think it is wrong to place "derived properties" in the group -
they should not be derived. Derived properties should only be used in
the result. There is confusion there as well with the mixture of
statement sequence and declarative "requirements". I think we need to
revisit the decision to place properties directly in the group and
artifacts lists.

> is much clearer than:
>
> action products ... {
> { result a {} with { target.platform="sparc" }
> result b {} with { target.platform="z80"}
> } group { buildSite }
> }
>
Not really, I think it replaces one problem with another,

> even if the latter is more compact. The closure for the 'buildSite'
> group is lost here however. What happens if we introduce that as
> separate specialization? I.e.
>
> closure a {
> group { buildSite }
> property target.platform="*"
> }
>
I don't like the mix of statement sequence with group.

> closure a {
> group { buildSite }
> properties { target.platform="*"; ... }
> }
>
That is already possible by doing as follows:
group { {buildSite} with { property target.platform="*"; }}

As it is possible to set closures around selected parts in the group,
instead of just around an individual part. Wrapping all of the parts in
the group like eliminates the need for a with outside of the group. The
following two syntax examples are equivalent:

group { {} with{} ) === group { } with {}.


> Using the former syntax, we can also establish one important difference
> between 'closure' and 'with':
>
> - The 'closure' propagates the properties to the 'group' that it contains.
> - The 'with' just defines groups and properties that are input to the
> actor. The properties are *not* propagated to the group. This means that
> we can express:
>
The same concept is used throughout the syntax. Where it is possible
"with" allows setting properties, and advice that takes effect in the
closure the with clause is advising. It is always "around" something.
Why an additional concept - this just makes it more difficult to understand.

> result a{} with{ property target.platform="sparc"; closure { group {
> buildSite }; property target.platform="*" } };
>
> OR, spelled out:
>
> closure buildSiteEnvelope {
> group { buildSite }
> property targetPlatform="*"
> }
>
> result a{} with { property target.platform="sparc" group {
> buildSiteEnvelope } }
>
> Another thought that strikes me when I read that syntax is that perhaps
> 'using' is a better keyword then 'with'. The full products example could
> then be written as:
>
You are only looking at actions. The word "using" works less well
elsewhere. Maybe we should pick a different word - but lets keep the
ones we have been using until we know in what order we are going to have
the darned clauses :)

I will see if I can come up with an improvement that solves all of the
above issues:
- properties in the path group vectors
- understandable nesting of result, group and closures
- understandable order of evaluation of properties.

- henrik
Re: b3 build files DSL in XText - annotaded sample b3 file [message #491550 is a reply to message #491507] Thu, 15 October 2009 00:05 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
Hi Sven,
Thanks for helping out. Much appreciated. Comments inline.

On 10/14/09 10:03 PM, Sven Efftinge wrote:
> Henrik Lindberg wrote:
>>> ** Standard XText implementation allows a unary ^ before a keyword as an
>>> escape (Remove?)
>> I think so too.
>
> Why do you want to constrain that?
> It would just make your language more complicated because you need two
> different versions of an identifier (an escapeable an a non-escapeable).
> What kind of harm could one do with the escape character?
>
We need to handle strange names anyway - names with NLS, spaces, and all
sorts of delimiters, or names that starts with digits. We opted for
quoting all non 'ID (. ID)*' names. So ^ adds a second escape mechanism
- just one more concept to explain. We are not in full control over the
naming standard as we map from other domains, hence the construct. And
to keep it simple - "if names include funny or reserved characters/words
- escape the name as a string". These names are not used as typical
variables in the language (so does not clash with expressions), but user
deals with them in many places, so it is nice to be able to write
typical names without having to handle them as strings at all times.

I also have an issue with ^keyword as I keep reading it as "raised to
the power of keyword" :)

> I highly recommend to stick with parser rules here.
> Are you aware of the fact that in most programming languages (Java
> incl.) qualified names are parsed exactly like that?
> I.e. you can write
>
> package foo . /* fddfdf */ stuff;
>
> but can't
>
> package foo.bar.class;
>
> But is this really a problem?
>
I have only found esoteric issues - I doubt anyone will ever have an
issue with those.

> That said, we'll of course fix the hidden()-bug ASAP.
>
Ah - great. That makes things so much easier since the parser rules
makes it possible to deal with "lexing in context" - I prefer that.

What I want to avoid is that someone thinks they entered a name with a
space in it. I.e entering "Program Files" as Program Files (only to get
white space sucked out of it). Better to spank them with a syntax error
- to allow them to enter either Program%20Files, "Program Files", (or
"Program%20Files"). (We will need to use the %nn notation in URLs, and
some names will be derived from URLs).

>> As stated above, the problem is coming up with lexer rules that makes
>> it possible to parse:
>> - versions
>> - version ranges
>> - qualified names
>> - unqualified names
>> - ints
>> - file paths
>> - advice paths
>>
>> I think this is quite difficult. If hidden() works, then the only
>> consequence is that user must string quote if a keyword token is found
>> inside the element.
>>
>> BTW - if anyone happens to be a lexer guru, feel free to come up with
>> a sequence of lex rules that handles all of the above. Free Beer
>> offered :)
>
> The problem with implementing all these as lexer rules is not defining
> the rule, but that the lexing is completely context free. Having lots of
> lexer rules, which don't shadow each other is often just impossible and
> can't be solved.
> For no beer in the world, unfortunately ;-)
>
If you have all the beer in the world, you won't care :)

> So my advice here is again, to use parser rules and I'ld even allow
> whitespace and comments inbetween if it is not ambigous.
> People are usually smart enough to layout their scripts in a readable way.
>
I will not even attempt to write the lexer rules, and instead use the
parser. I don't mind the embedded comments - if someone was smart enough
to figure out that it is possible and use it for some reason, they
probably know what they are doing.

> If you want to guide the user you can add warnings or even errors in te
> validation phase. That also allows for nicer error messages.
>
Yep - I got that. There are many things we need to handle there that can
not be solved by parsing alone.

> if you have any technical questions regarding Xtext, just use our
> newsgroup.

Thanks.

> We're looking forward to b3 :-)
>
I am very excited about b3 - have been able to make a lot of progress on
a very short time thanks to EMF, and XText.

Starting to ues XText was a very pleasant experience! Kudos. I wrote a
java like language 20 years ago using lex, yacc, and C++ - and I
probably produced as much in 1 week with Xtext (and got an editor with
syntax coloring at no extra effort) as I did in several months with the
lex, yacc, C++ combo. Kudos for a fantastic tool!

The only thing that causes me headache is when my grammar introduces
indirect left recursion. Precedence and associativity was easier to deal
with in yacc. Read that it is possible to make a packrat parser support
left recursion - http://www.vpri.org/pdf/tr2007002_packrat.pdf any
chance anything like that will make it into the XText packrat parser ?

Regards
- henrik
Re: action - group - result syntax [message #491559 is a reply to message #491542] Thu, 15 October 2009 02:38 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
I wrote :)
> I will see if I can come up with an improvement that solves all of the
> above issues:
> - properties in the path group vectors
> - understandable nesting of result, group and closures
> - understandable order of evaluation of properties.

I started hacking at syntax... but realized that we probably are talking
past each other.

So, to reset the thinking I came up with an alternative way to describe
what it is we are trying to cover with the b3 syntax.

I think it is as follows:

DEFINE ARTIFACTS =
PATHS (p0, ... pn)
WHEN(EFFECTIVE CLOSURE EXPR == TRUE) PATHS (p0, ... pn)
WITH 'NEW' ANNOTATIONS (a0 = v0 ... an = vn) ;

DEFINE GROUP =
DEFINE PROPERTIES (p0, .. pn) IN GROUP'S CLOSURE
APPLY ADVICE (a0 .. an) IN GROUP'S CLOSURE
COLLECT 'PARTS AND ANNOTATIONS' (p0, p1, .. pa)
WITH DEFAULT ANNOTATIONS (a0 = v0 ... an = vn)
ADD 'NEW NON COLLECTED' ANNOTATIONS (a0 = v0 ... an = vn)
ASSERT THESE ANNOTATIONS HAVE VALUE (a0 .. an)
POP THE GROUP'S CLOSURE
RETURN 'COLLECTED PARTS AND RESULTING ANNOTATIONS'
;

DEFINE ACTION =

DEFINE PROPERTIES (p0, .. pn) IN ACTION'S CLOSURE
APPLY ADVICE (a0 .. an) IN ACTION'S CLOSURE

CALL ACTOR (A) // initialized earlier
WITH THE FOLLOWING INPUT:
COLLECTED 'PARTS AND ANNOTATIONS' (p0, .. pn)
WITH DEFAULT ANNOTATIONS (a0 = v0 ... an = vn)
ADD 'NEW NON COLLECTED' ANNOTATIONS (a0 = v0 ... an = vn)
ASSERT ANNOTATIONS HAVE A VALUE (a0 .. an)
'CONVERT ANNOTATIONS TO PROPERTIES' IN ACTION'S CLOSURE

DEFINE PART x =
PATHS(xp0, ... xpn)
WHEN(EFFECTIVE CLOSURE EXPR == TRUE) PATHS (p0, ... pn)
"COLLECT" ANNOTATIONS FROM THE ACTOR
WITH DEFAULT ANNOTATIONS (a0 = v0 ... an = vn)
ADD 'NEW NON COLLECTED' ANNOTATIONS (a0 = v0 ... an = vn)
ASSERT ANNOTATIONS HAVE VALUE (a0 .. an)


COLLECT ALL PARTS AND ANNOTATIONS DEFINED IN THE ACTION
POP THE ACTION'S CLOSURE
RETURN 'COLLECTED PARTS AND ANNOTATIONS DEFINED IN THE ACTION'
;

I left out compound variants to make sure we have the basic steps
described first. (I deliberately left out when() in the description of
collecting parts and annotations, but that should be possible).

I hope my pseudo syntax is understandable, and that it is clear how I
think the various concepts interact.

- henrik
Re: action - group - result syntax [message #491598 is a reply to message #491559] Thu, 15 October 2009 07:59 Go to previous messageGo to next message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
Hi Henrik,
Yes this makes sense to me. One thing that I've been thinking about is if we don't need defaults for parts as well, i.e.

WITH DEFAULT ANNOTATIONS (a0 = v0 ... an = vn)

becomes

WITH DEFAULT 'PARTS AND ANNOTATIONS' (a0 = v0 ... an = vn)

to cover cases like "This actor might optionally produce a configuration file. If it doesn't, this is the default".

Another thing I've been thinking about is asserts. I think that we need them on the artifacts as well. Perhaps a bit
esoteric but it could be used in cases where you want to make sure that at least 1 of 2 files is present in a folder.

I see that you place the assert before you pop the closure. Why is that? Shouldn't the assert execute as the absolute
last thing to avoid side-effects from the closure?

- thomas


On 10/15/2009 04:38 AM, Henrik Lindberg wrote:
> I wrote :)
>> I will see if I can come up with an improvement that solves all of the
>> above issues:
>> - properties in the path group vectors
>> - understandable nesting of result, group and closures
>> - understandable order of evaluation of properties.
>
> I started hacking at syntax... but realized that we probably are talking
> past each other.
>
> So, to reset the thinking I came up with an alternative way to describe
> what it is we are trying to cover with the b3 syntax.
>
> I think it is as follows:
>
> DEFINE ARTIFACTS =
> PATHS (p0, ... pn)
> WHEN(EFFECTIVE CLOSURE EXPR == TRUE) PATHS (p0, ... pn)
> WITH 'NEW' ANNOTATIONS (a0 = v0 ... an = vn) ;
>
> DEFINE GROUP =
> DEFINE PROPERTIES (p0, .. pn) IN GROUP'S CLOSURE
> APPLY ADVICE (a0 .. an) IN GROUP'S CLOSURE
> COLLECT 'PARTS AND ANNOTATIONS' (p0, p1, .. pa)
> WITH DEFAULT ANNOTATIONS (a0 = v0 ... an = vn)
> ADD 'NEW NON COLLECTED' ANNOTATIONS (a0 = v0 ... an = vn)
> ASSERT THESE ANNOTATIONS HAVE VALUE (a0 .. an)
> POP THE GROUP'S CLOSURE
> RETURN 'COLLECTED PARTS AND RESULTING ANNOTATIONS'
> ;
>
> DEFINE ACTION =
>
> DEFINE PROPERTIES (p0, .. pn) IN ACTION'S CLOSURE
> APPLY ADVICE (a0 .. an) IN ACTION'S CLOSURE
>
> CALL ACTOR (A) // initialized earlier
> WITH THE FOLLOWING INPUT:
> COLLECTED 'PARTS AND ANNOTATIONS' (p0, .. pn)
> WITH DEFAULT ANNOTATIONS (a0 = v0 ... an = vn)
> ADD 'NEW NON COLLECTED' ANNOTATIONS (a0 = v0 ... an = vn)
> ASSERT ANNOTATIONS HAVE A VALUE (a0 .. an)
> 'CONVERT ANNOTATIONS TO PROPERTIES' IN ACTION'S CLOSURE
>
> DEFINE PART x =
> PATHS(xp0, ... xpn)
> WHEN(EFFECTIVE CLOSURE EXPR == TRUE) PATHS (p0, ... pn)
> "COLLECT" ANNOTATIONS FROM THE ACTOR
> WITH DEFAULT ANNOTATIONS (a0 = v0 ... an = vn)
> ADD 'NEW NON COLLECTED' ANNOTATIONS (a0 = v0 ... an = vn)
> ASSERT ANNOTATIONS HAVE VALUE (a0 .. an)
>
>
> COLLECT ALL PARTS AND ANNOTATIONS DEFINED IN THE ACTION
> POP THE ACTION'S CLOSURE
> RETURN 'COLLECTED PARTS AND ANNOTATIONS DEFINED IN THE ACTION'
> ;
>
> I left out compound variants to make sure we have the basic steps
> described first. (I deliberately left out when() in the description of
> collecting parts and annotations, but that should be possible).
>
> I hope my pseudo syntax is understandable, and that it is clear how I
> think the various concepts interact.
>
> - henrik
Re: b3 build files DSL in XText - annotaded sample b3 file [message #491604 is a reply to message #491550] Thu, 15 October 2009 08:27 Go to previous messageGo to next message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
On 10/15/2009 02:05 AM, Henrik Lindberg wrote:
> I also have an issue with ^keyword as I keep reading it as "raised to
> the power of keyword" :)
>
x=a^b; // Binary op: x equals a XOR b


>> I highly recommend to stick with parser rules here.
>> Are you aware of the fact that in most programming languages (Java
>> incl.) qualified names are parsed exactly like that?
>> I.e. you can write
>>
>> package foo . /* fddfdf */ stuff;
>>
>> but can't
>>
>> package foo.bar.class;
>>
>> But is this really a problem?
>>
> I have only found esoteric issues - I doubt anyone will ever have an
> issue with those.
>
One less esoteric issue is that the path:

/ a/ b/

silently becomes:

/a/b/

The desired behavior is a syntax error, making the user aware that he must write:

/%20a/%20b/

Regards,
Thomas Hallgren
Re: b3 build files DSL in XText - annotaded sample b3 file [message #491767 is a reply to message #491290] Thu, 15 October 2009 17:31 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
On 10/14/09 3:15 AM, Henrik Lindberg wrote:
> Hi,
> I have been working with a XText based DSL for the proposed b3 build
> language for a week or so. I got fed up trying to describe the syntax on
> the wiki - it felt like I should use a proper tool.
>
>
And there was much feedback and discussion, and I am working a new
revision where there will be simplifications made.

So stay tuned...

- henrik
Re: b3 build files DSL in XText - annotaded sample b3 file [message #491861 is a reply to message #491550] Fri, 16 October 2009 09:04 Go to previous message
Sven Efftinge is currently offline Sven EfftingeFriend
Messages: 1823
Registered: July 2009
Senior Member
Hi

Henrik Lindberg wrote:
>
> I also have an issue with ^keyword as I keep reading it as "raised to
> the power of keyword" :)


The '^' is just a default.
See the ID rule in TerminalRules. Just override it and remove or change
the escape character.

>> I have only found esoteric issues - I doubt anyone will ever have an
>> issue with those.
>>
> One less esoteric issue is that the path:
>
> / a/ b/
>
> silently becomes:
>
> /a/b/
>
> The desired behavior is a syntax error, making the user aware that he
> must write:
>

Agreed.

>
> What I want to avoid is that someone thinks they entered a name with a
> space in it. I.e entering "Program Files" as Program Files (only to get
> white space sucked out of it). Better to spank them with a syntax error
> - to allow them to enter either Program%20Files, "Program Files", (or
> "Program%20Files"). (We will need to use the %nn notation in URLs, and
> some names will be derived from URLs).

For the time beeing (as long as the hidden() bug exists) you could
raise an error using the validation hook, when there's whitespace.

You get access to the underlying text of an EMF model by obtaining the
attached node model.

org.eclipse.xtext.parsetree.NodeUtil.getNodeAdapter(EObject)


> I will not even attempt to write the lexer rules, and instead use the
> parser. I don't mind the embedded comments - if someone was smart enough
> to figure out that it is possible and use it for some reason, they
> probably know what they are doing.

Exactly. Frameworks and languages shouldn't constrain users but guide them.
If they want to shoot their own foot, let them do it.
But we need to avoid any suggestions in that direction :-)

>
>> We're looking forward to b3 :-)
>>
> I am very excited about b3 - have been able to make a lot of progress on
> a very short time thanks to EMF, and XText.
>
> Starting to ues XText was a very pleasant experience! Kudos. I wrote a
> java like language 20 years ago using lex, yacc, and C++ - and I
> probably produced as much in 1 week with Xtext (and got an editor with
> syntax coloring at no extra effort) as I did in several months with the
> lex, yacc, C++ combo. Kudos for a fantastic tool!

Very nice words. Thank you very much.

>
> The only thing that causes me headache is when my grammar introduces
> indirect left recursion. Precedence and associativity was easier to deal
> with in yacc. Read that it is possible to make a packrat parser support
> left recursion - http://www.vpri.org/pdf/tr2007002_packrat.pdf any
> chance anything like that will make it into the XText packrat parser ?

Actually, Antlr is a very nice and sophisticated parser generator. We
don't want to reinvent the wheel here. The packrat parser was mainly
developed in order to solve some IP-problems. And we don't have plans to
improve it much in future.

Cheers,
Sven


--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
Re: b3 build files DSL in XText - annotaded sample b3 file [message #581661 is a reply to message #491290] Wed, 14 October 2009 07:22 Go to previous message
Matthias Sohn is currently offline Matthias SohnFriend
Messages: 1268
Registered: July 2009
Senior Member
Looks like the forum application doesn't understand attachments and hence doesn't decode the base64 transfer-encoding. Could you post your samples as inline text ?
Re: b3 build files DSL in XText - annotaded sample b3 file [message #581669 is a reply to message #491290] Wed, 14 October 2009 07:52 Go to previous message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
Hi Henrik,
Lots of questions :-)

Properties:
property foo= "hello";
// a property can be set to null (but not immutable properties)
property foo;

Wouldn't it be better to explicitly assign null in this case? It looks like an uninitialized variable. So

property foo = null;

or
property foo = empty; // Since empty apparently is a keyword?


Expressions:
You have this expression in the file:

when (!target.platform != "sparc" && target.platform < "hpUx")

which I interpret as a not operation on a string which probably would result in an
UnsupportedOperationException?

How do we plan to handle expression type priorities? I.e. which one of these are true:

"4" + 2 == 6
"4" + 2 == "42"
"4" + 2 == Exception, different types of operands.

What does:

target.platform < "hpUx"

mean? If it's a lexical compare, is it sensitive to Locale? I can see use cases for both locale sensitive compare and
plain ASCII. Do we need additional operators for this?


Artifacts:

** Standard XText implementation allows a unary ^ before a keyword as an escape (Remove?)

I'd vote yes to that. I'd prefer if we quote keywords where needed (paths, requirements, etc.) and prohibits the use of
keywords as names in other places. Like Java.

You have an example:

"my.unit", "my.unit"; // unit is a keyword
my.^unit; // unit is keyword - standard XText grammar escape of keywords in ID

I understand why 'unit' needs to be quoted, but why do I need to quote 'my.unit'? Isn't that one single token? Can I write:

my . "unit" // (with spaces surrounding the dot)

?


NLS:
"aŒŠš"; // has NLS characters

What character encoding is used (related to the locale sensitive compare)?


Artifact paths:

/ a / b ; // is equivalent to /a/b - not /" a"/" b"

That looks really odd to me. I haven't seen any language to date that does that and I don't think we should either. It's
an incomprehensible syntax to most people. Perhaps you can have PATH recognized by the lexer and then specializations of
that (REFERENCE and REQUEST for instance, allowing a version and version range) also recognized? I.e. that:

requestElement:
PATH
| REFERENCE
| REQUEST
;

referenceElement:
PATH
| REFERENCE
;

artifactElement:
PATH

etc.

Group:
Regarding parallel or sequential execution. You have

// The keyword 'syncronized' declares that parallell execution of any part is dissallowed

this confuses me. synchronized usually mean that two threads cannot execute the same piece simultaneously. One must wait
for the other. So a synchronized group would be a group that you expect multiple threads to call on for execution and
that the threads must wait in line when that happens.

I would like to turn things around and say:

private sequential group foo {} // Execute the parts of this group sequentially (the default)
private parallel group foo {} // Allow parallel execution of the parts of this group

I.e. executing things in parallel is a conscious decision. We can have synchronized too of course, but I think it's
unusual that you'd want actions or groups that are not synchronized (in my sense of the word).

Action:
Your non-working example:

action test3 actor Test(test="test") provides a/b/"1"
{
// NON working example - need help with parser

// group input to one results
group {
a;
}
result b { b.txt; }
}
*/

How about turning it inside out, like this:

action test3 actor Test(test="test") provides a/b/"1"
{
result b { b.txt } with { group { a; } }
}

Since the result is at top, nested groups wouldn't work so your example:

action Test actor Test(test="test") provides a/b/"1"
{
group { a;
} {
group { x; } { result b { b; } }
result b {b;}
group { x; } { result b { b; } }
}
}

would need to be rewritten as:

action Test actor Test(test="test") provides a/b/"1"
{
result b { b; } with { group { a; x; } }
result b { b; } with { group { a } }
result b { b; } with { group { a; x; } }
}

which in my opinion vastly increases the readability. It becomes even more clear when you mix groups and properties:

action Test actor Test(test="test") provides a/b/"1"
{
result b { b; } with { group { a; x; } property foo="z80" }
result b { b; } with { group { a } }
result b { b; } with { group { a; x; } property foo="i8080" }
}

One argument in favor of your syntax is that repeating 'a' is cumbersome if it is complex. The counter argument to that
is; when that happens, just make 'a' a private group outside of the action.

Regards,
Thomas Hallgren
Re: b3 build files DSL in XText - annotaded sample b3 file [message #581690 is a reply to message #491322] Wed, 14 October 2009 07:55 Go to previous message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
Hi Matthias,
Here it is, in plain ISO8859-1 encoded text:

/*
** A .b3 file
** consists of import statements followed by a single "unit". This is analogous with a .java file having imports
** and a single language element (class, interface).
**
** This file is a sampler used to test syntax. The examples are not realistic (you will find plenty of a, b, c, fee and
foo...)
*/

/*
** COMMENTS
** Both single line and multi line comments are supported.
*/
// Single line comment
/* Multi line comment
*/

/*
** IMPORT
** Is used to import classes (just like in java). This is done so non qualified names can be used for classes
** DISCUSS: Imports are probably translated to meta requirements when resolving. As they are requirements on the
environment.
*/
import org.eclipse.b3.default.Resolvers.*;

/*
** UNIT
** A Unit is a Build Unit. It is used for several purposes:
** - as a file that describes "top level" requirements (what to import into a workspace, resolvers to use etc.)
** - as advice that extends meta data translation
** - as the meta data that describes a unit, when there is no other meta data
**
** A Unit has:
** - Properties
** - Provided Capabilities
** - Required Capabilities (and Meta Required Capabilities)
** - Parts (analogous with members in a class). There are four kinds of parts:
** - Artifacts (existing files)
** - Group (Aggregation of other parts)
** - Action (Production of new files (or side effect)
** - Result (A set of files produced by an Action ~= generated Artifacts)
** - Advice (Path/Predicate based access to elements that do not yet exist in the model). Used to set options, make
** overrides, etc.
** - Repositories - a configuration that is used to resolve (look up) units.
** - Synchronization - defines monitors across units that help solve issues in parallel builds
**
** A unit can be marked as synchronized - this means that requests to its parts are serialized.
** A unit can implement interfaces. These interfaces are "build time interfaces" and tells b3 about
** which parts it can expect. This also helps an author of extended components, and freshly created components
** comply with known build interfaces - i.e. this thing builds like an osgi.bundle.
*/
synchronized unit "my.unit" version 2.3 implements osgi.bundle, eclipe.ecore.model {

/* PROPERTIES
** Properties supports strings, integers, booleans, expressions and references to properties
*/
property foo= "hello";
// a property can be set to null (but not immutable properties)
property foo;
immutable property bar = 32;
immutable property bar = 32+10;

// checks if a calculation has the same value as a property
immutable property meaningful = 32+10 == the.meaning.of.life;

// a property can be "unset", that means that if it was set in this context, it will revert to
// it's value (if any) in an enclosing context.
//
unset property yellow.banana;

// Several properties can be set in a compound "properties" clause. It also works for unset.
// Note that the "property" keyword is no longer required per setting.
properties {
bar = "bar";
immutable politician = "oxymoron";
unset yellow.banana;
}

/* PROVIDES
** Provides clause is used to declare that the BuildUnit provides capabilities.
** A capability consists of interface/unitname and an optional /version at the end.
** If an interface, unitname or version requires use of reserved words or characters, the corresponding
** part is entered as a string (i.e. within " ").
** As with properties, there is a compound provides clause.
**
** Provide Capabilities can be filtered - some capabilities may only be provided under certain circumstances.
** This is declared with a leading when(BooleanExpression).
*/
provides osgi.bundle/bundlebar;
provides osgi.bundle/bundlebar/1.0;
provides {
osgi.bundle/barbara.bundle/2.0;
eclipse.feature/inflateable.pleasure/6.6.6;
when(target.platform == platforms.win32) native.thing/windowsInstaller/12.23.r1234;
}
provides when(target.platform == platforms.win32) native.thing/windowsInstaller/12.23.r1234;

/* REQUIRES
** Requires clause is used to declare that the BuildUnit requires certain capabilities.
** The differences between required and provided capabilities are that:
** - the version is always a range (althoug a single version means >= version
*/
requires osgi.bundle/air/1.0;
requires when (!target.platform != "sparc" && target.platform < "hpUx") osgi.bundle/pillow/3.0 ;
requires {
osgi.bundle/pillow/1.0;
when (a == b) osgi.bundle/blanket/1.0;
}

/* META REQUIRES
** With a leading meta keyword, the requiremens are requirements on the environment (i.e. on b3 itself)
** As an example, a meta requirement may be that a certain meta data provider is installed or it will be impossible to
** use this definition.
*/
meta requires osgi.bundle/air/1.0;
meta requires when (42 >= 32) osgi.bundle/pillow/"3.0";
meta requires {
osgi.bundle/pillow/1.0;
when (myorg.foo ~= "[a-z].*") osgi.bundle/blanket/1.0;
}

/* ARTIFACTS
** Artifact is a vector of path groups.
** A group of paths may have a base path - the rest of the paths in the group are relative to the
** base path.
** File names that include reserved words or reserved characters are entered within " "
** File names containing spaces must always be quoted, as the compiler removes whitespace from non strings.
** Standard XText implementation allows a unary ^ before a keyword as an escape (Remove?)
** Inclusion of a vector can be controlled with a leading when(BooleanExpression).
**
** VISIBILITY
** Visibility is either private or public (the default). Private means that the part is only accesable
** from within the b3 unit whene the part is declared.
**
** PROPERTIES
** It is possible to set (and unset) properties in the list using basic or compound property statements.
** These properties are set on the resulting path group vector and are available to the user of the
** set of files.
** Since file group vectors are merged, so will the properties. Use of immutable properties will guarantee
** that the property values set will surface (or an error will be generated if merging causes the value
** to change), but is ok if multiple vectors are tagged the same way.
**
** Note that individual property settings per file is not supported. To flag an individual file it is
** recommended to use dottiefied properties - example - mark the path /a/b as being little endian
** property org.myorg.fileinfo.endian.a.b=little.
**
** DISCUSS - is it of value to have properties/annotations per file?
**
*/
private artifacts test.a1 provides myorg.food/fruit.sallad/2.0, myorg.projectiles/fruit.salad
{
a; // a vector with one entry
a, b; // a vector with two entries
a [ b, c]; // a base path (a), with two relative paths in a vector
/a/b;
/ a / b ; // is equivalent to /a/b - not /" a"/" b"


// names that must be quoted
"unit"; // a keyword
"1a"; // does not look like a qualified name
"a b"; // has space in name
"aŒŠš"; // has NLS characters
"//f"; // looks like a comment
"123"; // is an integer

"my.unit", "my.unit"; // unit is a keyword
my.^unit; // unit is keyword - standard XText grammar escape of keywords in ID
when(target.platform == "osx") MacApp.app ;
when(true) banana.txt, pineapple.txt, mango.txt;
when (true) exotic [ rambustan.txt, tamarind.txt ];
a1 [apple.txt, "ban ana.txt"];
fee/apa.boo [ a/b/c.d, a.b.c.d, o/b/d ];
property apa="banan";
property defaultsToNull;
properties { a; b; }
}

// An empty artifacts vecor
artifacts empty {
}

/* ARTIFACTS PROVIDING CAPABILITIES
** It is possible to declare that the resulting path group vector is a capability layed out on disk.
** They layout can represent many capabilities at the same time.
*/
artifacts providesMany provides a/b/1.0, c/d/2.0, x/y/3.0 {a;}

/* GROUP
** A group is similar to artifacts in that it creates a path group vector, but it creates this
** by aggregating path group vectors from other parts.
** Just as with artifacts; the resulting path group vector can represent capabilities.
**
** The group consists of a list of required capabilities. The syntax is the same as for
** the units requires { } clause, with the following additions:
** - A trailing '#partname' is used after the requirement to pick a particular part.
** - A reference can be made to parts in the same build unit by using a single identifier
** - A reference to a required capability without a trailing '#partname' is taken as a reference to '#self', meaning the
** aggregation of all its public parts.
** - It is possible to define a closure where properties and advise are declared. They have downstream effect
** (i.e. when evaluating the part). The closure is defined using a trailing with { } statement.
** - A closure can be defined for several requirements at the same time by enclosing the requirements in curly
** brackets {r r r} with { }
** - A leading void keyword indicates that the resulting path group vector from the evaluation of the part should
** not be included in the resulting path group vector.
** - The result of individual part evaluation, or evaluation of a group of requirements can be assigned to an alias.
** The alias is a property that is included in the resulting path group vector. This makes it possible for a user
** of the vector to reference a particular part of the set.
** - void and alias can be used at the same time, but for a group that represents a part (as in this case), neither the
** property nor its value survive the group's context. For other types of grouping (in actions), this is very
** valuable, but in a group part, this construct simply has no effect.
**
** WITH CLOSURE
** In the with closure, properties can be set using the single or compound properties statements.
** Advice can be set using advice syntax.
**
*/
private synchronized group "foo/bar" provides myorg.food/fruit.coctail/2.0, a / b / "2.3"
{
a; // referense to part in self
foo/bar; // reference to #self in interface foo, name bar
a/a#b; // reference to #b in interface a, name a
fubbla= osgi.bundle/foo.bar/1.0; // sets the property fubbla to to the pathGroup reference in runtime - typically not
used in groups
osgi.bundle/fee.fum/1.0#jars;
osgi.bundle/zeBundle/1.0#jars;
void a/a#b; // only performed for side effect
void alias.nbr1 = b; // only performed for side effect, but sets a property to the result (that is then ignored)
a/a#b with { property nice = "yes"; }; // sets and passes the property nice downsteam
a/a#b with { // passes several properties downstream.
properties {
a="2"; b="2"; c="3";
}
};
// includes result of three references, all with the same set of downstream properties
{ a/a#b; a/b#c; a/c#d; } with { property target.platform="sparc"; };
// sets an alias on a non included result, result is a group of items with downstream properties
void aliasedButNotIncluded = { a/a#b; a/b#c; a/c#d; } with { property foo="hpux"; };
// sets an alias on an included item, result is a group of items with downstream properties, a nested alias is set
aliasedAndIncluded = { alias.nbr3=a/a#b; a/b#c; a/c#d; } with { property foo="hpux"; };

// inclusion can be filtered with a boolean expression - here "true" makes it always included
when (true) { a/a#b; a/b#c; a/c#d; } with { property foo="z80"; };
// filtering - here, never ever included because boolean value is false
when (false) a/a#b;
// a non included and filtered reference to a/a#b
void when (true) a/a#b;
}

// The keyword 'syncronized' declares that parallell execution of any part is dissallowed
private synchronized group foo {}
public synchronized group foo {}
private group foo {}
group foo {}
synchronized group foo {}


/*
** ACTION
** An action has an embedded group declaration that defines the input to an actor. The actor is told to
** produce the result(s) decalred for the input group. Input groups and results can be nested.
** This is used to decalre common input, input for a group of results (such as input to actions for linux),
** and then specific input for building a linx flavor, for different windowing systems etc.
**
** The result can consist be declared with public or private visibility, or follow the visibility of the action.
** Public result are available as first class members of the unit (even if the enclosing action is private).
** Public result must be named. Private result must be named if it should be referenced individually (and not as
** part of the action's result).
**
** The actor is declared in the preamble of the action part and is instantiated once.
** Parameters to the actor instantiation can be passed with parentheses using named parameters
** (order is not important).
** - An action can provide the resulting path group vector as provided capabilities
**
** Aliases
** Aliases for input parts have an additional meaning in actions - these properties are available to the actor.
** This means that the combination of void alias={ } is meaningful (as opposed to when used in a group part).
**
** RESULT
** Result clauses behave like artifact parts, but they typically refer to files that were produce by the actor.
** Properties in these sets may be set by the actor. This means that an actor can pass information back - such as
** a version qualifier, location of certain files on disk etc.
**
*/
private synchronized action foo
actor ZipActor(serviceKey="WooHoo - woot")
provides myorg.food/fruit.coctail/2.0
{
group {
a; // defaults to #self
when (apa > 11) a/a#b;
osgi.bundle/foo.bar/"1.2.3.qualifier#,./"#jars; // defaults to #self


osgi.bundle/fee.fum/1.0#jars;
osgi.bundle/zeBundle#jars;
void a/a#b; // only performed for side effect
void alias.nbr1 = a/a#b; // only performed for side effect
a/a#b with { property nice = "yes"; };
a/a#b with {
properties {
a="2"; b="2"; c="3";
}
};
{ a/a#b; a/b#c; a/c#d; } with { property target.platform="sparc"; };
void { a/a#b; a/b#c; a/c#d; } with { property foo="hpux"; };
void alias.nbr2 = { alias.nbr3=a/a#b; a/b#c; a/c#d; } with { property foo="hpux"; };
when (true) { a/a#b; a/b#c; a/c#d; } with { property foo="z80"; };
when (false) a/a#b;
void when (true) a/a#b;
}{
result a { a; }
}
}
action test1 actor Test(test="test") provides a/b/"1"
{ // no dependencies, no special input, just "do it and produce result"
result b { b.txt; }
}
action test2 actor Test(test="test") provides a/b/"1"
{ // no dependencies, no special input, just "do it and produce result"
// but set a properties
//
result b { b.txt; } with { property target.platform = "win32"; }
}

/* NON WORKING SYNTAX, due to problems in language specification. Help Wanted.

action test3 actor Test(test="test") provides a/b/"1"
{
// NON working example - need help with parser

// group input to one results
group {
a;
}
result b { b.txt; }
}
*/

action test3 actor Test(test="test") provides a/b/"1"
{
// group input to one or several results
group { a; }
{
result b { b.txt; }
}
}
action Test actor Test(test="test") provides a/b/"1"
{
group { a;
} {
result b { b; }
result b { b; }
result b { b; }
}
}
action Test actor Test(test="test") provides a/b/"1"
{
group { a;
} {
group { x; } { result b { b; } }
result b {b;}
group { x; } { result b { b; } }
}
}

action makeWin32Zip
actor ZipActor(serviceKey="tjoho")
provides foodstuff.sallad/fruitsallad/1.0, x/b/"23"
{
group {
{ site = createSite; } with { property target.platform="win32";};
}{
group {
extraInput = a/a/2.0#jarFiles;
}{
public result makeSomeoneHappy {
apa/banan.zip ;
when(true) chimp/banan.zip ;
} with { properties { target.platform = "win32"; prerequisite.flag = "a#b"; }}

group {
special;
}{
when (true) private result a { a;} with { /* for a only */ }
when (true) result b {} with { /* for b only */ }
} with { /* for a and b */ }
}
}
}

/** Synchronize clauses allows syncronization to be specified across units/actions.
** When executing a build in parallell, an engine should serialize the evaluation (build) of the
** specified elements. Serialization of execution may serialize more than what is specified but never less.
** Each synchronized list specifies a group that will be serialized. References are to part names in this unit, or
** to part names in other units.
**
** DISCUSS: although very useful, statements that synchronized on interface/*, and on actors are also useful.
** Syntax should probably be xpath/query like.
*/
synchronize a,b,c;
synchronize a/a#x,b/b#x,c/c;

synchronize { a,b,c; d,e,f; }

/** REPOSITORIES
** The repository clause defines the order in which repositories are searched.
** There are two forms of entries - the most common is expected to be the short form, where
** both the location, and repository type is specified with a URI. The URI scheme is used to select
** a resolver. For cases where this is not possible, the longer form is to declare that a resolver should be
** used, and the location (a general URL) is then set using advice (if indeed the selected resolver needs a location).
**
**
*/
repositories {
"http://bar/fee" { };
"http://bar/foo";
"http://bar/fum";
resolver foo.bar {
// Statements here are advice relative to a resolver. (i.e. '.' is a resolver)
//
location="http:://www.somewhere.com";
apa = 10;
booleanFlag = 10;
options/advanced[featureA ~="[a-z]*"]/?[a>23]/b/?? {
option1 = 10;
option2 = 20;
option3 = "hello";
};
};
}
advice import_Advice {
/requests[name~="org.myorg.*"]/options {
source=true;
mutable=true;
};
/resolutions[name~="org.eclipse.*"]/options {
location = "platform:/plugin/";
};
}
}
Re: b3 build files DSL in XText - annotaded sample b3 file [message #581728 is a reply to message #491333] Wed, 14 October 2009 11:02 Go to previous message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
Hi,
comments in-line...

- henrik

On 10/14/09 9:52 AM, Thomas Hallgren wrote:
> Lots of questions :-)
>
Feedback apreciated :-)

> Properties:
> property foo= "hello";
> // a property can be set to null (but not immutable properties)
> property foo;
>
> Wouldn't it be better to explicitly assign null in this case? It looks
> like an uninitialized variable. So
>
You suggested having uninitialized properties. The rationale was to use
them as part of result path group vectors. You agreed that that they
could be set to null in that case. I agree that it is not very good...
(read on)...
> property foo = null;
>
> or
> property foo = empty; // Since empty apparently is a keyword?
>
I think we should not allow uninitialized properties.
We can use "null" if we want to, "empty" is not a keyword, it is the
name of a property in the sample :-).

However, there is one more option that also increases quality, and that
is to set the property to a special keyword that indicates that it is
expected to be set by an action. Then, on return from the actor, a check
can be made that the property was actually set.

For instance, if there is an expectancy that the actor will assign a
revision number or similar and it doesn't - then sometimes later, things
will appear broken as the property is uninitialized.

One possibility, would be to allow the following in result path group
vector (but only there):

immutable property revision;

Since immutable means it can't be changed - it is clear that this is not
allowed, and hence, that a value must be provided. The above is
different from:

immutable property revision = "r101010";

Since this forbids the actor to change the value. And it is different from:

property revision = "r101010";

which specifies revision with a default value, that the actor may
override. If specifying:

property revision;

Then, this would mean - revision implicetly set to null, actor may or
may not set it. I think this is likely to cause problems (that are much
harder to find), and suggest that we do not support this at all anywhere.

>
> Expressions:
> You have this expression in the file:
>
> when (!target.platform != "sparc" && target.platform < "hpUx")
>
> which I interpret as a not operation on a string which probably would
> result in an
> UnsupportedOperationException?
>
Yes, the expression would throw an exception. I made it like that in the
sample on purpose to trigger the discussion on how to handle such issues :)

> How do we plan to handle expression type priorities? I.e. which one of
> these are true:
>
> "4" + 2 == 6
> "4" + 2 == "42"
> "4" + 2 == Exception, different types of operands.
>
We can:
- Have generality on types and convert to the more general type -
int/string becomes int. Since we don't have float, double and other
types (although we may add collections) it is not that hard.
- Only use string. (Don't like this solution though).

So, I opt for:

"4" + 2 = "42"

It is more an issue of interpreting properties set in properties files,
or from the command line. How is the distinction made between a string
and an int property there?

A related question. Should we support "real" (i.e. double). ?

> What does:
>
> target.platform < "hpUx"
>
> mean? If it's a lexical compare, is it sensitive to Locale? I can see
> use cases for both locale sensitive compare and plain ASCII. Do we need
> additional operators for this?
>
Very good question(s):

a) It would mean lexical compare if we implement it ;)

b) I see two ways of implementing specification of NLS

- having a bunch of operators that say that the compare is NLS, say @<
@> @<= @>= @== @!= (ugly, and makes it hard to specify locale).

- handle NLS strings as a type more general than string.
@ "This is a NLS String in current locale"
@us_EN "This is a NLS String in US English"
@se_SE "En svensk tiger"

The following would then apply:

"x" < @ "y"

"x" is converted to NLS in current locale before compare.

@ca_FR "Je suis une ficelle rouge"
==
@fi_FI "Olen punainen merkkijono"

Would throw an exception since the locale's are different. The fact that
the two strings mean the same thing could possibly be detected by
feeding them to google translator :) - but lets leave this feature
outside the scope of b3 :)

Any Babel people reading this... suggestions?

>
> Artifacts:
>
> ** Standard XText implementation allows a unary ^ before a keyword as an
> escape (Remove?)
>
> I'd vote yes to that. I'd prefer if we quote keywords where needed
> (paths, requirements, etc.) and prohibits the use of keywords as names
> in other places. Like Java.
>
I think so too.

> You have an example:
>
> "my.unit", "my.unit"; // unit is a keyword
> my.^unit; // unit is keyword - standard XText grammar escape of keywords
> in ID
>
> I understand why 'unit' needs to be quoted, but why do I need to quote
> 'my.unit'? Isn't that one single token? Can I write:
>
> my . "unit" // (with spaces surrounding the dot)
>
yes, since there is a bug when letting the parser do the lexing.
The use of hidden() in parser rules prohibits WS globbing in the lexer,
and thus spaces in the QualifiedName will generate syntax errors.
However, since the parser handles this instead of the lexer, it will see
"unit" as a keyword token.

Handling QualifiedName as a lexer token solves this. It however has
other consequences as it will gobble all occurrences of ID('.' ID)*
which makes it mask ID - there are places where a non Qualified ID is
wanted. The check could perhaps be deferred to data type checking, but
may cause problems. Currently there is the need to use ID (instead of
Qualified ID) in two places:

- in version which makes use of:
AlfanumSym : (ID | INT) (Separator|ID|INT)* ;
- in expressions where (Expression '.' ID) is a method call on
a LHS expression.

So, right now - I handle QualifiedName including WS globbing, since if I
turn it on, things are screwed up. If I solve it in the lexer I get
other problems.

Would prefer a solution where keywords in subparts of QualifiedName are
not recognized as keywords, provided we solve parsing of version and
method call (subject to debate if method call should be supported).

> NLS:
> "aŒŠš"; // has NLS characters
>
> What character encoding is used (related to the locale sensitive compare)?
>
Good question. What do you propose?
a) That we support one, and only one encoding of b3 files (like UTF8).
If so, which one?
b) That encoding is declared in the file, but with a default of a
standard encoding?

>
> Artifact paths:
>
> / a / b ; // is equivalent to /a/b - not /" a"/" b"
>
> That looks really odd to me. I haven't seen any language to date that
> does that and I don't think we should either.

Agree - it is a consequence of the hidden() bug in xtext. Should not be
allowed IMO.

> It's an incomprehensible
> syntax to most people. Perhaps you can have PATH recognized by the lexer
> and then specializations of that (REFERENCE and REQUEST for instance,
> allowing a version and version range) also recognized? I.e. that:
>
As stated above, the problem is coming up with lexer rules that makes it
possible to parse:
- versions
- version ranges
- qualified names
- unqualified names
- ints
- file paths
- advice paths

I think this is quite difficult. If hidden() works, then the only
consequence is that user must string quote if a keyword token is found
inside the element.

BTW - if anyone happens to be a lexer guru, feel free to come up with a
sequence of lex rules that handles all of the above. Free Beer offered :)

> Group:
> Regarding parallel or sequential execution. You have
>
> // The keyword 'syncronized' declares that parallell execution of any
> part is dissallowed
>
> this confuses me. synchronized usually mean that two threads cannot
> execute the same piece simultaneously. One must wait for the other. So a
> synchronized group would be a group that you expect multiple threads to
> call on for execution and that the threads must wait in line when that
> happens.
>
That is how I also thought of this.

> I would like to turn things around and say:
>
> private sequential group foo {} // Execute the parts of this group
> sequentially (the default)
> private parallel group foo {} // Allow parallel execution of the parts
> of this group
>
> I.e. executing things in parallel is a conscious decision. We can have
> synchronized too of course, but I think it's unusual that you'd want
> actions or groups that are not synchronized (in my sense of the word).
>
I can replace synchronized with sequential, and have that be the
default. That works for me language wise. BUT - in practice it makes the
mechanism useless as every component would then be specified to be
sequential (if that is the default).

So - I propose the following: It is parallel by default, and the
keywords are sequential and parallel.

And, agree that java synchronized semantics is always on. It is quite
meaningless to have a compiler compile the same thing to the same
location more than once at the same time. The only exception would be
some special actions - but that would be very special, and they can just
as well always be synchronized too.

> Action:
> Your non-working example:
>
> action test3 actor Test(test="test") provides a/b/"1"
> {
> // NON working example - need help with parser
>
> // group input to one results
> group {
> a;
> }
> result b { b.txt; }
> }
> */
>
> How about turning it inside out, like this:
>
> action test3 actor Test(test="test") provides a/b/"1"
> {
> result b { b.txt } with { group { a; } }
> }
>
I like that, and will make the changes. Agree with your reasoning.
The complex structure one has to write to get nested groups is not easy
to read anyway. Prefer the slight overhead for the complex case as it is
much clearer what you are doing. And, it removes the confusion over how
many times the actor should be invoked.

One addition is that it should be possible to specify several results
with a following with clause - i.e.:

{ result{} result{} } with { }
action - group - result syntax [message #581741 is a reply to message #491333] Wed, 14 October 2009 11:42 Go to previous message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
From the b3 DSL discussion... breaking it out...

On 10/14/09 9:52 AM, Thomas Hallgren wrote:

> Action:
> action Test actor Test(test="test") provides a/b/"1"
> {
> result b { b; } with { group { a; x; } property foo="z80" }
> result b { b; } with { group { a } }
> result b { b; } with { group { a; x; } property foo="i8080" }
> }
>
After thinking a bit, I think this syntax is slightly confusing. The
properties set would have no effect on the evaluation of the group.

For example:
result b { b; } with {
property bar="10";
group { a; x; }
property foo="i8080"
}

.... may be interpreted as the property bar being set in the scope of
group evaluation. Are you ok with this potential confusion?

The alternative would be to keep the group outside of the with clause.
In that case it would make most sense to do it as follows:

result {} with {} group {}

Since
result {} group {} with {}

Looks like the with clause sets the properties for the group closure.
Currently, a with clause on the group is not supported - you would have
to use the following

group { {x; y; z;} with {} }

to set a closure on all the stuff in the group. An alternative is

result {} with {} group {} with {}

where the closures are optional.

I think that is a better solution.

Thoughts?
- henrik
Re: b3 build files DSL in XText - annotaded sample b3 file [message #581752 is a reply to message #491365] Wed, 14 October 2009 11:57 Go to previous message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
On 10/14/09 1:02 PM, Henrik Lindberg wrote:

Typo !!

> - in expressions where ((Expression '.' ID) is a method call on
> a LHS expression.
>
Should have been:

- in expressions where ((Expression '.' ID) '(' Parameters* ')') is a
method call on a LHS expression.

- henrik
Re: b3 build files DSL in XText - annotaded sample b3 file [message #581797 is a reply to message #491365] Wed, 14 October 2009 12:58 Go to previous message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
More comments inline...

On 10/14/2009 01:02 PM, Henrik Lindberg wrote:
>> Properties:
>> property foo= "hello";
>> // a property can be set to null (but not immutable properties)
>> property foo;
>>
>> Wouldn't it be better to explicitly assign null in this case? It looks
>> like an uninitialized variable. So
>>
> You suggested having uninitialized properties. The rationale was to use
> them as part of result path group vectors. You agreed that that they
> could be set to null in that case. I agree that it is not very good...
> (read on)...
>
I remember that discussion. There's a subtle difference between declaring an expectation that a property will be part of
a result and actually declaring one (read on)...

> However, there is one more option that also increases quality, and that
> is to set the property to a special keyword that indicates that it is
> expected to be set by an action. Then, on return from the actor, a check
> can be made that the property was actually set.
>
> For instance, if there is an expectancy that the actor will assign a
> revision number or similar and it doesn't - then sometimes later, things
> will appear broken as the property is uninitialized.
>
> One possibility, would be to allow the following in result path group
> vector (but only there):
>
> immutable property revision;
>
> Since immutable means it can't be changed - it is clear that this is not
> allowed, and hence, that a value must be provided. The above is
> different from:
>
> immutable property revision = "r101010";
>
> Since this forbids the actor to change the value. And it is different from:
>
> property revision = "r101010";
>
> which specifies revision with a default value, that the actor may
> override. If specifying:
>
> property revision;
>
> Then, this would mean - revision implicetly set to null, actor may or
> may not set it. I think this is likely to cause problems (that are much
> harder to find), and suggest that we do not support this at all anywhere.
>
That would mean that we have to allow:

immutable property revision;

but not

property revision;

in a result. I think that is hard to understand. In that case it's better to say that the lack of assignment means that
the actor will (and must) provide a value. Even better perhaps using a keyword as you suggest.

property revision = derived;

or similar but then it becomes unclear how to set a default. Perhaps it could look like this:

property revision = derived("r101010");

alternatively, we turn it around:

derived property revision;

and with a default:

derived property revision = "r101010";


>> How do we plan to handle expression type priorities? I.e. which one of
>> these are true:
>>
>> "4" + 2 == 6
>> "4" + 2 == "42"
>> "4" + 2 == Exception, different types of operands.
>>
> We can:
> - Have generality on types and convert to the more general type -
> int/string becomes int. Since we don't have float, double and other
> types (although we may add collections) it is not that hard.
> - Only use string. (Don't like this solution though).
>
> So, I opt for:
>
> "4" + 2 = "42"
>
Agree. That's also what Java does.


> It is more an issue of interpreting properties set in properties files,
> or from the command line. How is the distinction made between a string
> and an int property there?
>
> A related question. Should we support "real" (i.e. double). ?
>
I believe we should. It's simple enough.


>> NLS:
>> "aŒŠš"; // has NLS characters
>>
>> What character encoding is used (related to the locale sensitive
>> compare)?
>>
> Good question. What do you propose?
> a) That we support one, and only one encoding of b3 files (like UTF8).
> If so, which one?
> b) That encoding is declared in the file, but with a default of a
> standard encoding?
>
a) sounds simpler. We can always implement b) later should there be a demand for it.


>>
>> Artifact paths:
>>
>> / a / b ; // is equivalent to /a/b - not /" a"/" b"
>>
>> That looks really odd to me. I haven't seen any language to date that
>> does that and I don't think we should either.
>
> Agree - it is a consequence of the hidden() bug in xtext. Should not be
> allowed IMO.
>
OK, let's revisit all issues related to WS once we have a better understanding on how to deal with this bug.

> I can replace synchronized with sequential, and have that be the
> default. That works for me language wise. BUT - in practice it makes the
> mechanism useless as every component would then be specified to be
> sequential (if that is the default).
>
Why? There's nothing stopping you from running different actions in parallel even though these actions in themselves are
both synchronized and sequential. It works as long as you don't try to run the same group or action simultaneously using
different threads.


> So - I propose the following: It is parallel by default, and the
> keywords are sequential and parallel.
>
Not too fond of having things running in parallel by default. I think most builds are inherently sequential and will
break when running things in parallel. Some specific tasks can execute in parallel but IMO, that's the exception and you
should declare them if needed, not the opposite.

- thomas
Re: action - group - result syntax [message #581824 is a reply to message #491374] Wed, 14 October 2009 13:04 Go to previous message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
On 10/14/2009 01:42 PM, Henrik Lindberg wrote:
> From the b3 DSL discussion... breaking it out...
>
> On 10/14/09 9:52 AM, Thomas Hallgren wrote:
>
>> Action:
>> action Test actor Test(test="test") provides a/b/"1"
>> {
>> result b { b; } with { group { a; x; } property foo="z80" }
>> result b { b; } with { group { a } }
>> result b { b; } with { group { a; x; } property foo="i8080" }
>> }
>>
> After thinking a bit, I think this syntax is slightly confusing. The
> properties set would have no effect on the evaluation of the group.
>
> For example:
> result b { b; } with {
> property bar="10";
> group { a; x; }
> property foo="i8080"
> }
>
> ... may be interpreted as the property bar being set in the scope of
> group evaluation. Are you ok with this potential confusion?
>
Perhaps my proposed 'derived' keyword would make the distinction clearer?


> The alternative would be to keep the group outside of the with clause.
> In that case it would make most sense to do it as follows:
>
> result {} with {} group {}
>
> Since
> result {} group {} with {}
>
> Looks like the with clause sets the properties for the group closure.
> Currently, a with clause on the group is not supported - you would have
> to use the following
>
> group { {x; y; z;} with {} }
>
> to set a closure on all the stuff in the group. An alternative is
>
> result {} with {} group {} with {}
>
> where the closures are optional.
>
> I think that is a better solution.
>
The keyword 'with' suggests that whatever is enclosed is input to the actor. That includes the group IMO. An alternative
to my 'derived' keyword that would solve the input/output property issue would be:

result {} with { group{} property ... } defines { property ... }

- thomas
derived properties... [message #581843 is a reply to message #491404] Wed, 14 October 2009 14:40 Go to previous message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
Splitting this up into smaller subthreads...

On 10/14/09 2:58 PM, Thomas Hallgren wrote:
> derived property revision;
>
> and with a default:
>
> derived property revision = "r101010";
>
I like that - an additional keyword. But I think it is fine.

- henrik
Re: action - group - result syntax [message #581858 is a reply to message #491406] Wed, 14 October 2009 15:45 Go to previous message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
On 10/14/09 3:04 PM, Thomas Hallgren wrote:
> On 10/14/2009 01:42 PM, Henrik Lindberg wrote:
>> From the b3 DSL discussion... breaking it out...
>>
>> On 10/14/09 9:52 AM, Thomas Hallgren wrote:
>>
>>> Action:
>>> action Test actor Test(test="test") provides a/b/"1"
>>> {
>>> result b { b; } with { group { a; x; } property foo="z80" }
>>> result b { b; } with { group { a } }
>>> result b { b; } with { group { a; x; } property foo="i8080" }
>>> }
>>>
>> After thinking a bit, I think this syntax is slightly confusing. The
>> properties set would have no effect on the evaluation of the group.
>>
>> For example:
>> result b { b; } with {
>> property bar="10";
>> group { a; x; }
>> property foo="i8080"
>> }
>>
>> ... may be interpreted as the property bar being set in the scope of
>> group evaluation. Are you ok with this potential confusion?
>>
> Perhaps my proposed 'derived' keyword would make the distinction clearer?
>
Well, it helps with a different issue - the distinction between
properties set inside the result body (that was not shown in this
example). I was pointing out a closure problem.

The mix of group and properties inside the with is what is causing the
trouble. The properties set there are in the closure of the result, and
not in the closure of evaluating the group.


> The keyword 'with' suggests that whatever is enclosed is input to the
> actor. That includes the group IMO. An alternative to my 'derived'
> keyword that would solve the input/output property issue would be:
>
> result {} with { group{} property ... } defines { property ... }

I don't like the with{ group{} } construct, as it mixes properties,
advice and group - it is confusing what exactly the apply to. Also not
fond of the "defines property" at the end as I want to have the same
mechanism everywhere, and it would have an effect on artifacts. I like
it the way it is.

If with{} should apply to both result and group, and always do so, then
I suggest

result{} group{} with{}

Then, it is not possible to have different sets of properties and advice
for the group and the result. (Which could be useful to specify
"agnostic group", "specific result" for instance).

An alternative, if we want to support this - i.e.

result{} with {} group with{}

Then we just need to specify that the group closure surrounds the result
closure.

Example:

result {}
with {target.platform="sparc"}
group { buildSite }
with {target.platform = "*" useBuild="N12345" }

Which works well with a compound result

{ result a {} with { target.platform="sparc" }
result b {} with { target.platform="z80"
} group { buildSite } with {target.platform="*" }


This would present target.platform = "*" and useBuild="N12345" to the
closure when evaluating the group. And present target.platform="sparc"
useBuild="N12345" when calling the actor for a, and with
target.platform="z80" useBuild="N12345" when calling the actor for b.

Most commonly used would be:
result{} group{} with {}

As you most likely would want the same properties in both cases.

Regards
- henrik
Re: action - group - result syntax [message #581879 is a reply to message #491447] Wed, 14 October 2009 15:56 Go to previous message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
Typo - sorry
> { result a {} with { target.platform="sparc" }
> result b {} with { target.platform="z80"
> } group { buildSite } with {target.platform="*" }
>

{ result a {} with { target.platform="sparc" }
result b {} with { target.platform="z80"}
} group { buildSite } with {target.platform="*" }

> Regards
> - henrik
Re: action - group - result syntax [message #581897 is a reply to message #491451] Wed, 14 October 2009 17:17 Go to previous message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
On 10/14/2009 05:56 PM, Henrik Lindberg wrote:
>
> Typo - sorry
>> { result a {} with { target.platform="sparc" }
>> result b {} with { target.platform="z80"
>> } group { buildSite } with {target.platform="*" }
>>
>
> { result a {} with { target.platform="sparc" }
> result b {} with { target.platform="z80"}
> } group { buildSite } with {target.platform="*" }
>
I think one thing that confuses me with this syntax is the fact that a group is also a closure (a property scope). Let's
remove that for a second (I'll come back to that).

I like the idea that the actor produces a 'result' 'with' given input. The input being both groups and properties. So to
me, the 'result' and 'with' are tightly bound.

I think that:

action products ... {
result a{} with { group { buildSite }, property target.platform="sparc" }
result b{} with { group { buildSite }, property target.platform="z80" }
}

is much clearer than:


action products ... {
{ result a {} with { target.platform="sparc" }
result b {} with { target.platform="z80"}
} group { buildSite }
}

even if the latter is more compact. The closure for the 'buildSite' group is lost here however. What happens if we
introduce that as separate specialization? I.e.

closure a {
group { buildSite }
property target.platform="*"
}

or

closure a {
group { buildSite }
properties { target.platform="*"; ... }
}


I think that is more clear than:

group a { buildSite }
with { target.platform="*" }

Using the former syntax, we can also establish one important difference between 'closure' and 'with':

- The 'closure' propagates the properties to the 'group' that it contains.
- The 'with' just defines groups and properties that are input to the actor. The properties are *not* propagated to the
group. This means that we can express:

result a{} with { property target.platform="sparc"; closure { group { buildSite }; property target.platform="*" } };

OR, spelled out:

closure buildSiteEnvelope {
group { buildSite }
property targetPlatform="*"
}

result a{} with { property target.platform="sparc" group { buildSiteEnvelope } }

Another thought that strikes me when I read that syntax is that perhaps 'using' is a better keyword then 'with'. The
full products example could then be written as:

action buildSite ... {
result using { properties { target.platform="*"; ... } group { <whatever artifacts needed> } }
}

action products ... {
result a using { group { buildSite }; properties { target.platform="sparc"; ... }; }
result b using { group { buildSite }; properties { target.platform="z80"; ... }; }
}

OR

action buildSite ... {
result using { group { <whatever groups needed> } } // Look mum, no properties
}

action products ... {
// We overrided the target.platform for the actor invocation only. Not propagated to the buildSite group.
result a using { group { buildSite } properties { target.platform="sparc"; ... } }
result b using { group { buildSite } properties { target.platform="z80"; ... } }
}

closure buildAll {
group { products; }
properties { target.platform="*"; ... } // Here we set the default TP
}


Thoughs?

- thomas
Re: b3 build files DSL in XText - annotaded sample b3 file [message #581916 is a reply to message #491365] Wed, 14 October 2009 20:03 Go to previous message
Sven Efftinge is currently offline Sven EfftingeFriend
Messages: 1823
Registered: July 2009
Senior Member
Hi all,

some comments inlined.

Henrik Lindberg wrote:
>> Artifacts:
>>
>> ** Standard XText implementation allows a unary ^ before a keyword as an
>> escape (Remove?)
>>
>> I'd vote yes to that. I'd prefer if we quote keywords where needed
>> (paths, requirements, etc.) and prohibits the use of keywords as names
>> in other places. Like Java.
>>
> I think so too.

Why do you want to constrain that?
It would just make your language more complicated because you need two
different versions of an identifier (an escapeable an a non-escapeable).
What kind of harm could one do with the escape character?

>
>> You have an example:
>>
>> "my.unit", "my.unit"; // unit is a keyword
>> my.^unit; // unit is keyword - standard XText grammar escape of keywords
>> in ID
>>
>> I understand why 'unit' needs to be quoted, but why do I need to quote
>> 'my.unit'? Isn't that one single token? Can I write:
>>
>> my . "unit" // (with spaces surrounding the dot)
>>
> yes, since there is a bug when letting the parser do the lexing.
> The use of hidden() in parser rules prohibits WS globbing in the lexer,
> and thus spaces in the QualifiedName will generate syntax errors.
> However, since the parser handles this instead of the lexer, it will see
> "unit" as a keyword token.
>
> Handling QualifiedName as a lexer token solves this. It however has
> other consequences as it will gobble all occurrences of ID('.' ID)*
> which makes it mask ID - there are places where a non Qualified ID is
> wanted. The check could perhaps be deferred to data type checking, but
> may cause problems. Currently there is the need to use ID (instead of
> Qualified ID) in two places:
>
> - in version which makes use of:
> AlfanumSym : (ID | INT) (Separator|ID|INT)* ;
> - in expressions where (Expression '.' ID) is a method call on
> a LHS expression.
>
> So, right now - I handle QualifiedName including WS globbing, since if I
> turn it on, things are screwed up. If I solve it in the lexer I get
> other problems.
>
> Would prefer a solution where keywords in subparts of QualifiedName are
> not recognized as keywords, provided we solve parsing of version and
> method call (subject to debate if method call should be supported).

I highly recommend to stick with parser rules here.
Are you aware of the fact that in most programming languages (Java
incl.) qualified names are parsed exactly like that?
I.e. you can write

package foo . /* fddfdf */ stuff;

but can't

package foo.bar.class;

But is this really a problem?

That said, we'll of course fix the hidden()-bug ASAP.

>
>> It's an incomprehensible
>> syntax to most people. Perhaps you can have PATH recognized by the lexer
>> and then specializations of that (REFERENCE and REQUEST for instance,
>> allowing a version and version range) also recognized? I.e. that:
>>
> As stated above, the problem is coming up with lexer rules that makes it
> possible to parse:
> - versions
> - version ranges
> - qualified names
> - unqualified names
> - ints
> - file paths
> - advice paths
>
> I think this is quite difficult. If hidden() works, then the only
> consequence is that user must string quote if a keyword token is found
> inside the element.
>
> BTW - if anyone happens to be a lexer guru, feel free to come up with a
> sequence of lex rules that handles all of the above. Free Beer offered :)

The problem with implementing all these as lexer rules is not defining
the rule, but that the lexing is completely context free. Having lots of
lexer rules, which don't shadow each other is often just impossible and
can't be solved.
For no beer in the world, unfortunately ;-)

So my advice here is again, to use parser rules and I'ld even allow
whitespace and comments inbetween if it is not ambigous.
People are usually smart enough to layout their scripts in a readable way.

If you want to guide the user you can add warnings or even errors in te
validation phase. That also allows for nicer error messages.

if you have any technical questions regarding Xtext, just use our
newsgroup.
We're looking forward to b3 :-)

Cheers,
Sven

--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
Re: action - group - result syntax [message #581940 is a reply to message #491463] Wed, 14 October 2009 22:54 Go to previous message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
On 10/14/09 7:17 PM, Thomas Hallgren wrote:
> On 10/14/2009 05:56 PM, Henrik Lindberg wrote:

>> { result a {} with { target.platform="sparc" }
>> result b {} with { target.platform="z80"}
>> } group { buildSite } with {target.platform="*" }
>>
> I think one thing that confuses me with this syntax is the fact that a
> group is also a closure (a property scope). Let's remove that for a
> second (I'll come back to that).
>
> I like the idea that the actor produces a 'result' 'with' given input.
> The input being both groups and properties. So to me, the 'result' and
> 'with' are tightly bound.
>
> I think that:
>
> action products ... {
> result a{} with { group { buildSite }, property target.platform="sparc" }
> result b{} with { group { buildSite }, property target.platform="z80" }
> }
>
I don't like that because the group is out of band wrt. the order in the
with clause. The rest of the statements, when executed, are done in the
order they are presented.

with { property a = 10; property b = a + 10; }

Makes property b have the value 20.

If you mix this with a group, which may have when() filters that
references properties, you may think that properties have the values as
computed in the sequence.

result a with {
property a = 10;
group {
derived property a = 10;
when(a == 10) x;
when(a == 20) y;
when(a == 30) z;
derived property a = a + 20;
}
property a = 20;
}

This will result in a == 20 to the actor.
What is the content of the group? x or y?
I can argue all three cases depending on the order the engine performs
the evaluations.

I also think it is wrong to place "derived properties" in the group -
they should not be derived. Derived properties should only be used in
the result. There is confusion there as well with the mixture of
statement sequence and declarative "requirements". I think we need to
revisit the decision to place properties directly in the group and
artifacts lists.

> is much clearer than:
>
> action products ... {
> { result a {} with { target.platform="sparc" }
> result b {} with { target.platform="z80"}
> } group { buildSite }
> }
>
Not really, I think it replaces one problem with another,

> even if the latter is more compact. The closure for the 'buildSite'
> group is lost here however. What happens if we introduce that as
> separate specialization? I.e.
>
> closure a {
> group { buildSite }
> property target.platform="*"
> }
>
I don't like the mix of statement sequence with group.

> closure a {
> group { buildSite }
> properties { target.platform="*"; ... }
> }
>
That is already possible by doing as follows:
group { {buildSite} with { property target.platform="*"; }}

As it is possible to set closures around selected parts in the group,
instead of just around an individual part. Wrapping all of the parts in
the group like eliminates the need for a with outside of the group. The
following two syntax examples are equivalent:

group { {} with{} ) === group { } with {}.


> Using the former syntax, we can also establish one important difference
> between 'closure' and 'with':
>
> - The 'closure' propagates the properties to the 'group' that it contains.
> - The 'with' just defines groups and properties that are input to the
> actor. The properties are *not* propagated to the group. This means that
> we can express:
>
The same concept is used throughout the syntax. Where it is possible
"with" allows setting properties, and advice that takes effect in the
closure the with clause is advising. It is always "around" something.
Why an additional concept - this just makes it more difficult to understand.

> result a{} with{ property target.platform="sparc"; closure { group {
> buildSite }; property target.platform="*" } };
>
> OR, spelled out:
>
> closure buildSiteEnvelope {
> group { buildSite }
> property targetPlatform="*"
> }
>
> result a{} with { property target.platform="sparc" group {
> buildSiteEnvelope } }
>
> Another thought that strikes me when I read that syntax is that perhaps
> 'using' is a better keyword then 'with'. The full products example could
> then be written as:
>
You are only looking at actions. The word "using" works less well
elsewhere. Maybe we should pick a different word - but lets keep the
ones we have been using until we know in what order we are going to have
the darned clauses :)

I will see if I can come up with an improvement that solves all of the
above issues:
- properties in the path group vectors
- understandable nesting of result, group and closures
- understandable order of evaluation of properties.

- henrik
Re: b3 build files DSL in XText - annotaded sample b3 file [message #581954 is a reply to message #491507] Thu, 15 October 2009 00:05 Go to previous message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
Hi Sven,
Thanks for helping out. Much appreciated. Comments inline.

On 10/14/09 10:03 PM, Sven Efftinge wrote:
> Henrik Lindberg wrote:
>>> ** Standard XText implementation allows a unary ^ before a keyword as an
>>> escape (Remove?)
>> I think so too.
>
> Why do you want to constrain that?
> It would just make your language more complicated because you need two
> different versions of an identifier (an escapeable an a non-escapeable).
> What kind of harm could one do with the escape character?
>
We need to handle strange names anyway - names with NLS, spaces, and all
sorts of delimiters, or names that starts with digits. We opted for
quoting all non 'ID (. ID)*' names. So ^ adds a second escape mechanism
- just one more concept to explain. We are not in full control over the
naming standard as we map from other domains, hence the construct. And
to keep it simple - "if names include funny or reserved characters/words
- escape the name as a string". These names are not used as typical
variables in the language (so does not clash with expressions), but user
deals with them in many places, so it is nice to be able to write
typical names without having to handle them as strings at all times.

I also have an issue with ^keyword as I keep reading it as "raised to
the power of keyword" :)

> I highly recommend to stick with parser rules here.
> Are you aware of the fact that in most programming languages (Java
> incl.) qualified names are parsed exactly like that?
> I.e. you can write
>
> package foo . /* fddfdf */ stuff;
>
> but can't
>
> package foo.bar.class;
>
> But is this really a problem?
>
I have only found esoteric issues - I doubt anyone will ever have an
issue with those.

> That said, we'll of course fix the hidden()-bug ASAP.
>
Ah - great. That makes things so much easier since the parser rules
makes it possible to deal with "lexing in context" - I prefer that.

What I want to avoid is that someone thinks they entered a name with a
space in it. I.e entering "Program Files" as Program Files (only to get
white space sucked out of it). Better to spank them with a syntax error
- to allow them to enter either Program%20Files, "Program Files", (or
"Program%20Files"). (We will need to use the %nn notation in URLs, and
some names will be derived from URLs).

>> As stated above, the problem is coming up with lexer rules that makes
>> it possible to parse:
>> - versions
>> - version ranges
>> - qualified names
>> - unqualified names
>> - ints
>> - file paths
>> - advice paths
>>
>> I think this is quite difficult. If hidden() works, then the only
>> consequence is that user must string quote if a keyword token is found
>> inside the element.
>>
>> BTW - if anyone happens to be a lexer guru, feel free to come up with
>> a sequence of lex rules that handles all of the above. Free Beer
>> offered :)
>
> The problem with implementing all these as lexer rules is not defining
> the rule, but that the lexing is completely context free. Having lots of
> lexer rules, which don't shadow each other is often just impossible and
> can't be solved.
> For no beer in the world, unfortunately ;-)
>
If you have all the beer in the world, you won't care :)

> So my advice here is again, to use parser rules and I'ld even allow
> whitespace and comments inbetween if it is not ambigous.
> People are usually smart enough to layout their scripts in a readable way.
>
I will not even attempt to write the lexer rules, and instead use the
parser. I don't mind the embedded comments - if someone was smart enough
to figure out that it is possible and use it for some reason, they
probably know what they are doing.

> If you want to guide the user you can add warnings or even errors in te
> validation phase. That also allows for nicer error messages.
>
Yep - I got that. There are many things we need to handle there that can
not be solved by parsing alone.

> if you have any technical questions regarding Xtext, just use our
> newsgroup.

Thanks.

> We're looking forward to b3 :-)
>
I am very excited about b3 - have been able to make a lot of progress on
a very short time thanks to EMF, and XText.

Starting to ues XText was a very pleasant experience! Kudos. I wrote a
java like language 20 years ago using lex, yacc, and C++ - and I
probably produced as much in 1 week with Xtext (and got an editor with
syntax coloring at no extra effort) as I did in several months with the
lex, yacc, C++ combo. Kudos for a fantastic tool!

The only thing that causes me headache is when my grammar introduces
indirect left recursion. Precedence and associativity was easier to deal
with in yacc. Read that it is possible to make a packrat parser support
left recursion - http://www.vpri.org/pdf/tr2007002_packrat.pdf any
chance anything like that will make it into the XText packrat parser ?

Regards
- henrik
Re: action - group - result syntax [message #581967 is a reply to message #491542] Thu, 15 October 2009 02:38 Go to previous message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
I wrote :)
> I will see if I can come up with an improvement that solves all of the
> above issues:
> - properties in the path group vectors
> - understandable nesting of result, group and closures
> - understandable order of evaluation of properties.

I started hacking at syntax... but realized that we probably are talking
past each other.

So, to reset the thinking I came up with an alternative way to describe
what it is we are trying to cover with the b3 syntax.

I think it is as follows:

DEFINE ARTIFACTS =
PATHS (p0, ... pn)
WHEN(EFFECTIVE CLOSURE EXPR == TRUE) PATHS (p0, ... pn)
WITH 'NEW' ANNOTATIONS (a0 = v0 ... an = vn) ;

DEFINE GROUP =
DEFINE PROPERTIES (p0, .. pn) IN GROUP'S CLOSURE
APPLY ADVICE (a0 .. an) IN GROUP'S CLOSURE
COLLECT 'PARTS AND ANNOTATIONS' (p0, p1, .. pa)
WITH DEFAULT ANNOTATIONS (a0 = v0 ... an = vn)
ADD 'NEW NON COLLECTED' ANNOTATIONS (a0 = v0 ... an = vn)
ASSERT THESE ANNOTATIONS HAVE VALUE (a0 .. an)
POP THE GROUP'S CLOSURE
RETURN 'COLLECTED PARTS AND RESULTING ANNOTATIONS'
;

DEFINE ACTION =

DEFINE PROPERTIES (p0, .. pn) IN ACTION'S CLOSURE
APPLY ADVICE (a0 .. an) IN ACTION'S CLOSURE

CALL ACTOR (A) // initialized earlier
WITH THE FOLLOWING INPUT:
COLLECTED 'PARTS AND ANNOTATIONS' (p0, .. pn)
WITH DEFAULT ANNOTATIONS (a0 = v0 ... an = vn)
ADD 'NEW NON COLLECTED' ANNOTATIONS (a0 = v0 ... an = vn)
ASSERT ANNOTATIONS HAVE A VALUE (a0 .. an)
'CONVERT ANNOTATIONS TO PROPERTIES' IN ACTION'S CLOSURE

DEFINE PART x =
PATHS(xp0, ... xpn)
WHEN(EFFECTIVE CLOSURE EXPR == TRUE) PATHS (p0, ... pn)
"COLLECT" ANNOTATIONS FROM THE ACTOR
WITH DEFAULT ANNOTATIONS (a0 = v0 ... an = vn)
ADD 'NEW NON COLLECTED' ANNOTATIONS (a0 = v0 ... an = vn)
ASSERT ANNOTATIONS HAVE VALUE (a0 .. an)


COLLECT ALL PARTS AND ANNOTATIONS DEFINED IN THE ACTION
POP THE ACTION'S CLOSURE
RETURN 'COLLECTED PARTS AND ANNOTATIONS DEFINED IN THE ACTION'
;

I left out compound variants to make sure we have the basic steps
described first. (I deliberately left out when() in the description of
collecting parts and annotations, but that should be possible).

I hope my pseudo syntax is understandable, and that it is clear how I
think the various concepts interact.

- henrik
Re: action - group - result syntax [message #581991 is a reply to message #491559] Thu, 15 October 2009 07:59 Go to previous message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
Hi Henrik,
Yes this makes sense to me. One thing that I've been thinking about is if we don't need defaults for parts as well, i.e.

WITH DEFAULT ANNOTATIONS (a0 = v0 ... an = vn)

becomes

WITH DEFAULT 'PARTS AND ANNOTATIONS' (a0 = v0 ... an = vn)

to cover cases like "This actor might optionally produce a configuration file. If it doesn't, this is the default".

Another thing I've been thinking about is asserts. I think that we need them on the artifacts as well. Perhaps a bit
esoteric but it could be used in cases where you want to make sure that at least 1 of 2 files is present in a folder.

I see that you place the assert before you pop the closure. Why is that? Shouldn't the assert execute as the absolute
last thing to avoid side-effects from the closure?

- thomas


On 10/15/2009 04:38 AM, Henrik Lindberg wrote:
> I wrote :)
>> I will see if I can come up with an improvement that solves all of the
>> above issues:
>> - properties in the path group vectors
>> - understandable nesting of result, group and closures
>> - understandable order of evaluation of properties.
>
> I started hacking at syntax... but realized that we probably are talking
> past each other.
>
> So, to reset the thinking I came up with an alternative way to describe
> what it is we are trying to cover with the b3 syntax.
>
> I think it is as follows:
>
> DEFINE ARTIFACTS =
> PATHS (p0, ... pn)
> WHEN(EFFECTIVE CLOSURE EXPR == TRUE) PATHS (p0, ... pn)
> WITH 'NEW' ANNOTATIONS (a0 = v0 ... an = vn) ;
>
> DEFINE GROUP =
> DEFINE PROPERTIES (p0, .. pn) IN GROUP'S CLOSURE
> APPLY ADVICE (a0 .. an) IN GROUP'S CLOSURE
> COLLECT 'PARTS AND ANNOTATIONS' (p0, p1, .. pa)
> WITH DEFAULT ANNOTATIONS (a0 = v0 ... an = vn)
> ADD 'NEW NON COLLECTED' ANNOTATIONS (a0 = v0 ... an = vn)
> ASSERT THESE ANNOTATIONS HAVE VALUE (a0 .. an)
> POP THE GROUP'S CLOSURE
> RETURN 'COLLECTED PARTS AND RESULTING ANNOTATIONS'
> ;
>
> DEFINE ACTION =
>
> DEFINE PROPERTIES (p0, .. pn) IN ACTION'S CLOSURE
> APPLY ADVICE (a0 .. an) IN ACTION'S CLOSURE
>
> CALL ACTOR (A) // initialized earlier
> WITH THE FOLLOWING INPUT:
> COLLECTED 'PARTS AND ANNOTATIONS' (p0, .. pn)
> WITH DEFAULT ANNOTATIONS (a0 = v0 ... an = vn)
> ADD 'NEW NON COLLECTED' ANNOTATIONS (a0 = v0 ... an = vn)
> ASSERT ANNOTATIONS HAVE A VALUE (a0 .. an)
> 'CONVERT ANNOTATIONS TO PROPERTIES' IN ACTION'S CLOSURE
>
> DEFINE PART x =
> PATHS(xp0, ... xpn)
> WHEN(EFFECTIVE CLOSURE EXPR == TRUE) PATHS (p0, ... pn)
> "COLLECT" ANNOTATIONS FROM THE ACTOR
> WITH DEFAULT ANNOTATIONS (a0 = v0 ... an = vn)
> ADD 'NEW NON COLLECTED' ANNOTATIONS (a0 = v0 ... an = vn)
> ASSERT ANNOTATIONS HAVE VALUE (a0 .. an)
>
>
> COLLECT ALL PARTS AND ANNOTATIONS DEFINED IN THE ACTION
> POP THE ACTION'S CLOSURE
> RETURN 'COLLECTED PARTS AND ANNOTATIONS DEFINED IN THE ACTION'
> ;
>
> I left out compound variants to make sure we have the basic steps
> described first. (I deliberately left out when() in the description of
> collecting parts and annotations, but that should be possible).
>
> I hope my pseudo syntax is understandable, and that it is clear how I
> think the various concepts interact.
>
> - henrik
Re: b3 build files DSL in XText - annotaded sample b3 file [message #582013 is a reply to message #491550] Thu, 15 October 2009 08:27 Go to previous message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
On 10/15/2009 02:05 AM, Henrik Lindberg wrote:
> I also have an issue with ^keyword as I keep reading it as "raised to
> the power of keyword" :)
>
x=a^b; // Binary op: x equals a XOR b


>> I highly recommend to stick with parser rules here.
>> Are you aware of the fact that in most programming languages (Java
>> incl.) qualified names are parsed exactly like that?
>> I.e. you can write
>>
>> package foo . /* fddfdf */ stuff;
>>
>> but can't
>>
>> package foo.bar.class;
>>
>> But is this really a problem?
>>
> I have only found esoteric issues - I doubt anyone will ever have an
> issue with those.
>
One less esoteric issue is that the path:

/ a/ b/

silently becomes:

/a/b/

The desired behavior is a syntax error, making the user aware that he must write:

/%20a/%20b/

Regards,
Thomas Hallgren
Re: b3 build files DSL in XText - annotaded sample b3 file [message #582034 is a reply to message #491290] Thu, 15 October 2009 17:31 Go to previous message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
On 10/14/09 3:15 AM, Henrik Lindberg wrote:
> Hi,
> I have been working with a XText based DSL for the proposed b3 build
> language for a week or so. I got fed up trying to describe the syntax on
> the wiki - it felt like I should use a proper tool.
>
>
And there was much feedback and discussion, and I am working a new
revision where there will be simplifications made.

So stay tuned...

- henrik
Re: b3 build files DSL in XText - annotaded sample b3 file [message #582052 is a reply to message #491550] Fri, 16 October 2009 09:04 Go to previous message
Sven Efftinge is currently offline Sven EfftingeFriend
Messages: 1823
Registered: July 2009
Senior Member
Hi

Henrik Lindberg wrote:
>
> I also have an issue with ^keyword as I keep reading it as "raised to
> the power of keyword" :)


The '^' is just a default.
See the ID rule in TerminalRules. Just override it and remove or change
the escape character.

>> I have only found esoteric issues - I doubt anyone will ever have an
>> issue with those.
>>
> One less esoteric issue is that the path:
>
> / a/ b/
>
> silently becomes:
>
> /a/b/
>
> The desired behavior is a syntax error, making the user aware that he
> must write:
>

Agreed.

>
> What I want to avoid is that someone thinks they entered a name with a
> space in it. I.e entering "Program Files" as Program Files (only to get
> white space sucked out of it). Better to spank them with a syntax error
> - to allow them to enter either Program%20Files, "Program Files", (or
> "Program%20Files"). (We will need to use the %nn notation in URLs, and
> some names will be derived from URLs).

For the time beeing (as long as the hidden() bug exists) you could
raise an error using the validation hook, when there's whitespace.

You get access to the underlying text of an EMF model by obtaining the
attached node model.

org.eclipse.xtext.parsetree.NodeUtil.getNodeAdapter(EObject)


> I will not even attempt to write the lexer rules, and instead use the
> parser. I don't mind the embedded comments - if someone was smart enough
> to figure out that it is possible and use it for some reason, they
> probably know what they are doing.

Exactly. Frameworks and languages shouldn't constrain users but guide them.
If they want to shoot their own foot, let them do it.
But we need to avoid any suggestions in that direction :-)

>
>> We're looking forward to b3 :-)
>>
> I am very excited about b3 - have been able to make a lot of progress on
> a very short time thanks to EMF, and XText.
>
> Starting to ues XText was a very pleasant experience! Kudos. I wrote a
> java like language 20 years ago using lex, yacc, and C++ - and I
> probably produced as much in 1 week with Xtext (and got an editor with
> syntax coloring at no extra effort) as I did in several months with the
> lex, yacc, C++ combo. Kudos for a fantastic tool!

Very nice words. Thank you very much.

>
> The only thing that causes me headache is when my grammar introduces
> indirect left recursion. Precedence and associativity was easier to deal
> with in yacc. Read that it is possible to make a packrat parser support
> left recursion - http://www.vpri.org/pdf/tr2007002_packrat.pdf any
> chance anything like that will make it into the XText packrat parser ?

Actually, Antlr is a very nice and sophisticated parser generator. We
don't want to reinvent the wheel here. The packrat parser was mainly
developed in order to solve some IP-problems. And we don't have plans to
improve it much in future.

Cheers,
Sven


--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
Previous Topic:Supporting Parallel Builds
Next Topic:better term than "void" wanted
Goto Forum:
  


Current Time: Fri Apr 19 20:10:24 GMT 2024

Powered by FUDForum. Page generated in 0.07509 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top