Perplexing Verilog Operator Grammar: Replication Operator [message #1857989] |
Thu, 09 March 2023 18:02 |
Brandon Lewis Messages: 268 Registered: May 2012 |
Senior Member |
|
|
Hi.. me again. :-)
I'm messing with a DSL that has some Verilog language constructs. Most notably, I'm messing with expressions.
I'm come onto trouble with a Verilog operation called Replication (also known as "multi-concatenation")
My code here is strongly influenced by Lorenzo Bettini's book because he dedicates and entire chapter to expressions. The basis of my expression grammar looks exactly like this:
https://github.com/LorenzoBettini/packtpub-xtext-book-2nd-examples/blob/master/org.example.expressions.parent/org.example.expressions/src/org/example/expressions/Expressions.xtext
Verilog has a Concatenation operator using braces. For example a String Concatenation is made with {"foo", "bar"} which equals "foobar".
Since Concatenation starts and ends with braces, I've taken it to look a lot like the Precedence operation, thus I've modified my grammar to be:
Primary returns Expression:
'(' Expression ')' | Concat |
{Not} "!" expression=Primary |
Atomic;
Concat returns ipx::Concat:
'{' expressions+=Expression (',' expressions+=Expression)* '}'
;
So far, so good, I can cleanly generate Xtext artifacts without left recursion, without warnings, and I can pass a number of unit test cases with this. (note: {"zoo"} is a legal concatenation that doesn't do anything interesting.)
The Verilog Replication operation uses syntax like {3{"zoo"}} which equals "zoozoozoo". Like the repeat method in a string. But I've never seen another language with this operation syntax like this. So very hard to find any examples.
I've tried at least 12-15 ways to write a grammar for Replication, but I either hit left recursion, or I start breaking tests case, or I don't break my Concatenation operations but I can't get Replication to work?
I got close once, but a testcase of {3{"foo", "bar"}} failed. Here I have a replication of some concatenation.
The dumbest of my attempts have been like the following:
MultiConcat returns ipx:MultiConcat:
'{' left=Expression '{' right=Expression '}' '}'
I strongly suspect Xtext/Antlr is confused about these braces and confused between Concat and MultiConcat. Because the ',' symbol is optional in Concatenation the first '{' Expression gets matched to Concatenation and the very next '{' which should indicate Replication gets seen as the beginning of another Concat.
Seems a syntatic predicate is needed?
I've seen one ANTLR3 example coded like this, but I can't get it to work:
concatenation :
(LCURLY expression LCURLY) =>
LCURLY expression
LCURLY expression ( COMMA expression )* RCURLY RCURLY |
LCURLY expression ( COMMA expression )* RCURLY
;
[Updated on: Sat, 11 March 2023 14:31] Report message to a moderator
|
|
|
Re: Perplexing Verilog Operator Grammar: Replication Operator [message #1858054 is a reply to message #1857989] |
Mon, 13 March 2023 13:38 |
Brandon Lewis Messages: 268 Registered: May 2012 |
Senior Member |
|
|
This seems to work. Firstly, I dropped the concept of "multi-concat" and just considered the replication operator a different, subtle version of concatenation.
I have used grammar assignments to left, right, and expressions to help me track when the parser has distinguished between {exp{exp}} and { exp, exp }
It doesn't appear that the syntactic predicate is necessary, but I've left it in thinking it matches with the canonical dangling else syntactic predicate example.
The trick seemed to be showing that the inner braces can optionally only occur once. However, putting an "|" between
(',' expressions+=Expression)* and (=>'{' right=Expression....)?
resulted in left recursion.
Concat returns ipx::Concat:
'{' left=Expression
(',' expressions+=Expression)* (=>'{' right=Expression (',' expressions+=Expression)* '}')?
'}'
;
[Updated on: Mon, 13 March 2023 16:43] Report message to a moderator
|
|
|
Powered by
FUDForum. Page generated in 0.03311 seconds