|
I have this tree output which contains an unexpected "Unnamed0" node. The unwanted node shows when the optional node (named Metric) following it is used:
Program
Row
Action
pressure (Keyword)
50 (Action.Value)
% (Key symbol)
Telemetry
velocity (Keyword)
>= (Key symbol)
50 (Telemetry.Value)
Row
Action
velocity (Keyword)
40.2 (Action.Value)
Telemetry
distance (Keyword)
>= (Key symbol)
Unnamed0
50 (Telemetry.Value)
m (Keyword)
Here is some of my code for creating the rules. In this code (I believe) it's the NumberLiteral that doesn't work correctly:
private BnfExpression CreateTerminal(IEnumerable<TelemetryDefinitionModel> telemetryDefinitions, bool isAction = false)
{
var um = ServiceRegistry.Get<UnitsManager>();
BnfExpression combined = null;
var actionOp = ToTerm("at");
var prefix = isAction ? "Action" : "Telemetry";
var smallOp = new NonTerminal(prefix + ".Operator");
smallOp.Rule = ToTerm("==") | "!=";
var bigOp = new NonTerminal(prefix + ".Operator");
bigOp.Rule = smallOp | "<" | "<=" | ">" | ">=";
MarkTransient(smallOp, bigOp);
foreach (var definition in telemetryDefinitions)
{
NonTerminal metricOp = null;
if(definition.Metric != PhysicalType.Unitless && um != null)
{
metricOp = new NonTerminal(prefix + ".Metric");
var pt = um.GetCurrentUnit(definition.Metric);
metricOp.Rule = ToTerm(pt.Abbreviations.First());
foreach(var a in pt.Abbreviations.Skip(1))
metricOp.Rule |= ToTerm(a);
MarkTransient(metricOp);
}
var t = new NonTerminal(prefix);
var action = ToTerm("[") + definition.Name + ToTerm("]");
if(definition.Type == TelemetryType.String)
{
var op = isAction ? actionOp : (BnfTerm)smallOp;
var tail = new StringLiteral(prefix + ".Value", "\"", StringOptions.AllowsDoubledQuote);
t.Rule = action + op + tail;
}
else if(definition.Type == TelemetryType.Real)
{
var op = isAction ? actionOp : (BnfTerm)bigOp;
var tail = new NumberLiteral(prefix + ".Value", NumberOptions.AllowStartEndDot);
t.Rule = action + op + tail;
}
else throw new NotImplementedException("definition.Type is out of range");
if (metricOp != null)
{
var optionalMetric = new NonTerminal("OptionalMetric");
optionalMetric.Rule = metricOp | Empty;
t.Rule += optionalMetric;
MarkTransient(optionalMetric);
}
if (combined == null) combined = t;
else combined |= t;
}
return combined;
}
Any help would be appreciated.
|