Comma separated variable list in Xtext - dsl

I have a grammar for a specific DSL. Here is a snippet (written in Xtext):
Vars: 'var' (vars += Var)
Var: ID (',' ID) * ':' Type ';'
And here is an example input:
var
a,b,c : int;
d,e: bool;
I'm really interested in Xtend automatic code generation option and want to have a single object for every Variable, storing it's id and it's type. Using Xtex grammar synatx all I can do is :
Var: ids+=ID (',' ids+=ID)* ':' type =[Type] ';'
Meaning that I may have more than one ID in a single object. How can I store each 'a','b','c' in a single object?

It's not possible to store each variable together with it's type. You'd have to implement some logic that traverses your model to find the type. You could do this with derived properties on the Var itself.

Related

ANTLR4 different precedence in two seemingly equivalent grammars

The following test grammars differ only in that the first alternative of the rule 'expr' is either specified inline or refers to another rule 'notExpression' with just the same definition. But this grammars produce different trees parsing this: '! a & b'. Why?
I really want the grammar to produce the first result (with NOT associated with identifier, not with AND expression) but still need to have 'expr' to reference 'notExpression' in my real grammar. What do I have to change?
grammar test;
s: expr ';' <EOF>;
expr:
NOT expr
| left=expr AND right=expr
| identifier
;
identifier: LETTER (LETTER)*;
WS : ' '+ ->skip;
NOT: '!';
AND: '&';
LETTER: 'A'..'z';
Tree one
grammar test;
s: expr ';' <EOF>;
expr:
notExpression
| left=expr AND right=expr
| identifier
;
notExpression: NOT expr;
identifier: LETTER (LETTER)*;
WS : ' '+ ->skip;
NOT: '!';
AND: '&';
LETTER: 'A'..'z';
Tree two
I kind of got an answer to the second part of my question, which still do not quite give me a satisfaction because using this approach in real elaborate grammar is going to be ugly. As to the first part (WHY) I still have no idea, so more answers are welcome.
Anyway, to fix precedence in presence of referenced rule the 'notExpression' rule can be modified as follows:
notExpression: NOT (identifier|expr);
Which produces the tree different from both shown in original question, but at least the NOT does acquire higher precedence.
Parse tree

Meaning for = in antlr4

I have a grammar like
rule1 : GO (count=DECIMAL)? ;
rule2 : name '=' expression
I dont understand the difference between '=' sign in rule1 and rule2
The assignment is a variable assignment. ANTLR4 will generate a member variable named count for you, which gets the DECIMAL token when matched (since it is optional, count might be empty/null).
You can use count for instance in your listener code to directly get that value, however you could also just use DECIMAL instead. So it's mostly useful for action code or predicates in your grammar. You can refer to such variables by using e.g. $count:
rule1: GO (count = DECIMAL)? { $count.toString().toInteger() < 4}?;
which matches only if GO is followed by a value less than 4.
Side note: toInteger() is just pseudo code here. Use your target's string-to-int conversion API.

puppet, what is the difference between '=' and '=>'

Seriously, what's the difference between '=' and '=>'?
They both look and feel like variable binding operators.
Also, why does one require a comma after each declaration,
and the other generates a syntax error when it finds a comma?
= is used to assign a value to a variable, e.g.
$foo = 'bar'
There are some advanced ways to assign variables in Puppet 4, but generally speaking whenever it's a $variable on the left hand side of the expression, add no comma and always use =. Further variable assignments are simply separated by new lines.
=> is a key-value separator in hashes or lists of attributes in resources:
{
'foo' => 'bar',
'bar' => 'baz',
}
or
file { '/etc/foo.conf':
ensure => present,
content => 'bar',
}
Note that foo, bar, ensure and content are not variables themselves - they're keys in a hash or attributes.
You'll find a similar design in many languages, e.g. Perl.

Make a type be either one type or another

I'm a beginner in Haskell playing around with parsing and building an AST. I wonder how one would go about defining types like the following:
A Value can either be an Identifier or a Literal. Right now, I simply have a type Value with two constructors (taking the name of the identifier and the value of the string literal respectively):
data Value = Id String
| Lit String
However, then I wanted to create a type representing an assignment in an AST, so I need something like
data Assignment = Asgn Value Value
But clearly, I always want the first part of an Assignment to always be an Identifier! So I guess I should make Identifier and Literal separate types to better distinguish things:
data Identifier = Id String
data Literal = Lit String
But how do I define Value now? I thaught of something like this:
-- this doesn't actually work...
data Value = (Id String) -- How to make Value be either an Identifier
| (Lit String) -- or a Literal?
I know I can simply do
data Value = ValueId Identifier
| ValueLit Literal
but this struck me as sort of unelegant and got me wondering if there was a better solution?
I first tried to restructure my types so that I would be able to do it with GADTs, but in the end the simpler solution was to go leftroundabout's suggestion. I guess it's not that "unelegant" anyways.

how to get the raw version of a template string in iojs

Is it possible to get the raw version of a template string in iojs ?
var s = `foo${1+1}bar`
console.log(s); // foo2bar
In the previous example I would like to get the string: foo${1+1}bar
edit1:
My need is to detect whether a template string depends on its context of if is is just a 'constant' string that may contain CR and LF
Is it possible to get the raw version of a template string in iojs ?
No it is not. It's not possible to get the raw representation of the literal, just like there is no way to get the "raw" literal in these cases:
var foo = {[1+1]: 42};
var bar = 1e10;
var baz = "\"42\"";
Note that the term "template string" is misleading (as it may indicate that you could somehow get the raw value of the string (which is also not the case as shown above)). The correct term is "template literal".
My need is to detect whether a template string depends on its context of if is is just a 'constant' string that may contain CR and LF
Seems like a job for a static analysis tool. E.g. you can use recast to parse the source code and traverse all template literals.
For example, the AST representation of `foo${1+1}bar` is:
If such an AST node as an empty expression property, then you know that the value is constant.
There is a way to determine whether a template literal is "static" or "dynamic" at runtime, but that involves changing the behavior of the code.
You can use tagged templates. Tagged templates are functions that get passed the static and dynamic portions of a template literal.
Example:
function foo(template, ...expressions) {
console.log(template, expressions);
}
foo`foo${1+1}bar` // logs (["foo", "bar"], [2]) but returns `undefined`
I.e. if foo gets passed only a single argument, the template literal does not contain expressions. However, foo would also have to interpolate the static parts with the dynamic parts and return the result (not shown in the above example).

Resources