aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJack Koenig2017-02-28 10:24:29 -0800
committerJack Koenig2017-03-01 18:01:28 -0600
commit7f280a5b0821c61284e9bf9ed7780cc825f7f3e8 (patch)
tree700d511e93c4058c627bb28ecc507d0c49eb6758 /src
parent51f8f4a5e868a8e655091e3e61445d3cd772d2ba (diff)
Allow nested digit fields in subfield expressions
Workaround for #470. This allows parsing DoubleLits in subfield expressions.
Diffstat (limited to 'src')
-rw-r--r--src/main/antlr4/FIRRTL.g41
-rw-r--r--src/main/scala/firrtl/Visitor.scala20
-rw-r--r--src/test/scala/firrtlTests/ParserSpec.scala13
3 files changed, 33 insertions, 1 deletions
diff --git a/src/main/antlr4/FIRRTL.g4 b/src/main/antlr4/FIRRTL.g4
index 69b7ba5d..cdec7260 100644
--- a/src/main/antlr4/FIRRTL.g4
+++ b/src/main/antlr4/FIRRTL.g4
@@ -164,6 +164,7 @@ exp
| 'SInt' ('<' intLit '>')? '(' intLit ')'
| id // Ref
| exp '.' fieldId
+ | exp '.' DoubleLit // TODO Workaround for #470
| exp '[' intLit ']'
| exp '[' exp ']'
| 'mux(' exp exp exp ')'
diff --git a/src/main/scala/firrtl/Visitor.scala b/src/main/scala/firrtl/Visitor.scala
index 2db46271..73555a37 100644
--- a/src/main/scala/firrtl/Visitor.scala
+++ b/src/main/scala/firrtl/Visitor.scala
@@ -17,6 +17,12 @@ class Visitor(infoMode: InfoMode) extends FIRRTLBaseVisitor[FirrtlNode] {
// Strip file path
private def stripPath(filename: String) = filename.drop(filename.lastIndexOf("/") + 1)
+ // Check if identifier is made of legal characters
+ private def legalId(id: String) = {
+ val legalChars = ('A' to 'Z').toSet ++ ('a' to 'z').toSet ++ ('0' to '9').toSet ++ Set('_', '$')
+ id forall legalChars
+ }
+
def visit[FirrtlNode](ctx: FIRRTLParser.CircuitContext): Circuit = visitCircuit(ctx)
// These regex have to change if grammar changes
@@ -315,7 +321,19 @@ class Visitor(infoMode: InfoMode) extends FIRRTLBaseVisitor[FirrtlNode] {
case "mux(" => Mux(visitExp(ctx.exp(0)), visitExp(ctx.exp(1)), visitExp(ctx.exp(2)), UnknownType)
case _ =>
ctx.getChild(1).getText match {
- case "." => new SubField(visitExp(ctx.exp(0)), ctx.fieldId.getText, UnknownType)
+ case "." =>
+ val expr1 = visitExp(ctx.exp(0))
+ // TODO Workaround for #470
+ if (ctx.fieldId == null) {
+ ctx.DoubleLit.getText.split('.') match {
+ case Array(a, b) if legalId(a) && legalId(b) =>
+ val inner = new SubField(expr1, a, UnknownType)
+ new SubField(inner, b, UnknownType)
+ case Array() => throw new ParserException(s"Illegal Expression at ${ctx.getText}")
+ }
+ } else {
+ new SubField(expr1, ctx.fieldId.getText, UnknownType)
+ }
case "[" => if (ctx.exp(1) == null)
new SubIndex(visitExp(ctx.exp(0)), string2Int(ctx.intLit(0).getText), UnknownType)
else new SubAccess(visitExp(ctx.exp(0)), visitExp(ctx.exp(1)), UnknownType)
diff --git a/src/test/scala/firrtlTests/ParserSpec.scala b/src/test/scala/firrtlTests/ParserSpec.scala
index a1f14c8e..cd9bfb40 100644
--- a/src/test/scala/firrtlTests/ParserSpec.scala
+++ b/src/test/scala/firrtlTests/ParserSpec.scala
@@ -93,6 +93,19 @@ class ParserSpec extends FirrtlFlatSpec {
}
}
+ // ********** Digits as Fields **********
+ "Digits" should "be legal fields in bundles and in subexpressions" in {
+ val input = """
+ |circuit Test :
+ | module Test :
+ | input in : { 0 : { 0 : UInt<32>, flip 1 : UInt<32> } }
+ | input in2 : { 4 : { 23 : { foo : UInt<32>, bar : { flip 123 : UInt<32> } } } }
+ | in.0.1 <= in.0.0
+ | in2.4.23.bar.123 <= in2.4.23.foo
+ """.stripMargin
+ firrtl.Parser.parse(input split "\n")
+ }
+
// ********** Doubles as parameters **********
"Doubles" should "be legal parameters for extmodules" in {
val nums = Seq("1.0", "7.6", "3.00004", "1.0E10", "1.0023E-17")