Whatever we call it, no matter how we do it - we need live data / remote view into rusEFI actual state #3353
config values
This commit is contained in:
parent
0e70760a17
commit
86e18592ce
|
@ -49,10 +49,17 @@ public class Field {
|
|||
this.options = options;
|
||||
}
|
||||
|
||||
public static Field findField(Field[] values, String instancePrefix, String fieldName) {
|
||||
Field field = findFieldOrNull(values, instancePrefix, fieldName);
|
||||
if (field == null)
|
||||
throw new IllegalStateException("No field: " + fieldName);
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds field by name, ignoring case
|
||||
*/
|
||||
public static Field findField(Field[] values, String instancePrefix, String fieldName) {
|
||||
public static Field findFieldOrNull(Field[] values, String instancePrefix, String fieldName) {
|
||||
Objects.requireNonNull(fieldName);
|
||||
for (Field f : values) {
|
||||
if (fieldName.equalsIgnoreCase(f.getName()))
|
||||
|
@ -66,7 +73,7 @@ public class Field {
|
|||
return f;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("No field: " + fieldName);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getStructureSize(Field[] values) {
|
||||
|
@ -159,7 +166,7 @@ public class Field {
|
|||
// todo: rename to getNumberValue?
|
||||
@NotNull
|
||||
public Double getValue(ConfigurationImage ci, double multiplier) {
|
||||
Objects.requireNonNull(ci);
|
||||
Objects.requireNonNull(ci, "ConfigurationImage");
|
||||
Number value;
|
||||
ByteBuffer wrapped = ci.getByteBuffer(getOffset(), type.getStorageSize());
|
||||
if (bitOffset != NO_BIT_OFFSET) {
|
||||
|
|
|
@ -43,7 +43,7 @@ public class LinkManager implements Closeable {
|
|||
public static final String LOG_VIEWER = "log viewer";
|
||||
private final CommandQueue commandQueue;
|
||||
|
||||
private LinkConnector connector;
|
||||
private LinkConnector connector = LinkConnector.VOID;
|
||||
private boolean isStarted;
|
||||
private boolean compositeLogicEnabled = true;
|
||||
private boolean needPullData = true;
|
||||
|
@ -205,6 +205,7 @@ public class LinkManager implements Closeable {
|
|||
connector.connectAndReadConfiguration(stateListener);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public LinkConnector getConnector() {
|
||||
return connector;
|
||||
}
|
||||
|
|
|
@ -1,30 +1,39 @@
|
|||
package com.rusefi.livedata;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.opensr5.ConfigurationImage;
|
||||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||
import com.rusefi.binaryprotocol.BinaryProtocolState;
|
||||
import com.rusefi.config.Field;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.enums.live_data_e;
|
||||
import com.rusefi.io.LinkConnector;
|
||||
import com.rusefi.livedata.generated.CPP14Lexer;
|
||||
import com.rusefi.livedata.generated.CPP14Parser;
|
||||
import com.rusefi.livedata.generated.CPP14ParserBaseListener;
|
||||
import com.rusefi.ui.UIContext;
|
||||
import com.rusefi.ui.livedata.Range;
|
||||
import com.rusefi.ui.livedata.SourceCodePainter;
|
||||
import com.rusefi.ui.livedata.VariableValueSource;
|
||||
import org.antlr.v4.runtime.ANTLRInputStream;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import com.rusefi.ui.livedocs.LiveDocHolder;
|
||||
import com.rusefi.ui.livedocs.LiveDocsRegistry;
|
||||
import com.rusefi.ui.livedocs.RefreshActions;
|
||||
import com.rusefi.ui.livedocs.RefreshActionsMap;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.AttributeSet;
|
||||
import javax.swing.text.StyleConstants;
|
||||
import javax.swing.text.StyleContext;
|
||||
import javax.swing.text.StyledDocument;
|
||||
import javax.swing.text.*;
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static com.devexperts.logging.Logging.getLogging;
|
||||
import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
|
||||
|
@ -37,11 +46,48 @@ public class LiveDataParserPanel {
|
|||
private static final Logging log = getLogging(LiveDataParserPanel.class);
|
||||
|
||||
private final JPanel content = new JPanel(new BorderLayout());
|
||||
private final JTextPane text = new JTextPane();
|
||||
private ParseResult parseResult = ParseResult.VOID;
|
||||
private final UIContext uiContext;
|
||||
private final JTextPane text = new JTextPane() {
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
BinaryProtocol binaryProtocol = uiContext.getLinkManager().getConnector().getBinaryProtocol();
|
||||
if (binaryProtocol == null)
|
||||
return;
|
||||
BinaryProtocolState bps = binaryProtocol.getBinaryProtocolState();
|
||||
if (bps == null)
|
||||
return;
|
||||
ConfigurationImage ci = bps.getControllerConfiguration();
|
||||
if (ci == null)
|
||||
return;
|
||||
|
||||
g.setColor(Color.red);
|
||||
|
||||
for (Token setting : parseResult.getConfigTokens()) {
|
||||
Field field = Field.findFieldOrNull(Fields.VALUES, "", setting.getText());
|
||||
if (field == null)
|
||||
continue;
|
||||
Number value = field.getValue(ci);
|
||||
Rectangle r;
|
||||
try {
|
||||
r = getUI().modelToView(text, setting.getStopIndex());
|
||||
} catch (BadLocationException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
g.drawString(value.toString(), r.x, r.y);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
private final VariableValueSource valueSource;
|
||||
private String sourceCode;
|
||||
|
||||
public LiveDataParserPanel(VariableValueSource valueSource) {
|
||||
public LiveDataParserPanel(UIContext uiContext, VariableValueSource valueSource, String fileName) {
|
||||
this.uiContext = uiContext;
|
||||
this.valueSource = valueSource;
|
||||
|
||||
JScrollPane rightScrollPane = new JScrollPane(text,
|
||||
|
@ -50,7 +96,7 @@ public class LiveDataParserPanel {
|
|||
content.add(rightScrollPane);
|
||||
|
||||
try {
|
||||
sourceCode = getContent(getClass(), "ac_control.cpp");
|
||||
sourceCode = getContent(getClass(), fileName);
|
||||
text.setText(sourceCode);
|
||||
|
||||
refresh();
|
||||
|
@ -84,22 +130,29 @@ public class LiveDataParserPanel {
|
|||
return parser.translationUnit();
|
||||
}
|
||||
|
||||
public static void applyVariables(VariableValueSource valueSource, String s, SourceCodePainter painter, ParseTree tree) {
|
||||
public static ParseResult applyVariables(VariableValueSource valueSource, String s, SourceCodePainter painter, ParseTree tree) {
|
||||
Stack<Boolean> currentState = new Stack<>();
|
||||
currentState.add(Boolean.TRUE);
|
||||
|
||||
java.util.List<TerminalNode> allTerminals = new java.util.ArrayList<>();
|
||||
|
||||
new ParseTreeWalker().walk(new CPP14ParserBaseListener() {
|
||||
@Override
|
||||
public void enterStatement(CPP14Parser.StatementContext ctx) {
|
||||
String origin = getOrigin(ctx, s);
|
||||
System.out.println("enter statement [" + origin + "]");
|
||||
// System.out.println("enter statement [" + origin + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTerminal(TerminalNode node) {
|
||||
allTerminals.add(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterCondition(CPP14Parser.ConditionContext ctx) {
|
||||
String conditionVariable = ctx.getText();
|
||||
System.out.println("REQUESTING VALUE " + conditionVariable);
|
||||
System.out.println("exp " + getOrigin(ctx.expression(), s));
|
||||
// System.out.println("REQUESTING VALUE " + conditionVariable);
|
||||
// System.out.println("exp " + getOrigin(ctx.expression(), s));
|
||||
|
||||
Boolean state = (Boolean) valueSource.getValue(conditionVariable);
|
||||
if (state == null) {
|
||||
|
@ -107,17 +160,16 @@ public class LiveDataParserPanel {
|
|||
return;
|
||||
}
|
||||
if (state) {
|
||||
painter.paint(Color.GREEN, new Range(ctx));
|
||||
painter.paintBackground(Color.GREEN, new Range(ctx));
|
||||
} else {
|
||||
painter.paint(Color.RED, new Range(ctx));
|
||||
painter.paintBackground(Color.RED, new Range(ctx));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterSelectionStatement(CPP14Parser.SelectionStatementContext ctx) {
|
||||
super.enterSelectionStatement(ctx);
|
||||
|
||||
System.out.println("Else terminal " + ctx.Else());
|
||||
// System.out.println("Else terminal " + ctx.Else());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -125,6 +177,21 @@ public class LiveDataParserPanel {
|
|||
|
||||
}
|
||||
}, tree);
|
||||
|
||||
java.util.List<Token> configTokens = new java.util.ArrayList<>();
|
||||
|
||||
for (int i = 0; i < allTerminals.size() - 3; i++) {
|
||||
|
||||
if (allTerminals.get(i).getText().equals("CONFIG") &&
|
||||
allTerminals.get(i + 1).getText().equals("(") &&
|
||||
allTerminals.get(i + 3).getText().equals(")")
|
||||
) {
|
||||
Token token = allTerminals.get(i + 2).getSymbol();
|
||||
painter.paintForeground(Color.BLUE, new Range(token, token));
|
||||
configTokens.add(token);
|
||||
}
|
||||
}
|
||||
return new ParseResult(configTokens);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
@ -146,12 +213,62 @@ public class LiveDataParserPanel {
|
|||
AttributeSet oldSet = styledDocument.getCharacterElement(0).getAttributes();
|
||||
styledDocument.setCharacterAttributes(0, sourceCode.length(), sc.getEmptySet(), true);
|
||||
|
||||
applyVariables(valueSource, sourceCode, new SourceCodePainter() {
|
||||
// todo: technically we do not need to do the complete re-compile on fresh data arrival just repaint!
|
||||
// todo: split compilation and painting/repainting
|
||||
parseResult = applyVariables(valueSource, sourceCode, new SourceCodePainter() {
|
||||
@Override
|
||||
public void paint(Color color, Range range) {
|
||||
public void paintBackground(Color color, Range range) {
|
||||
AttributeSet s = sc.addAttribute(oldSet, StyleConstants.Background, color);
|
||||
styledDocument.setCharacterAttributes(range.getStart(), range.getLength(), s, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintForeground(Color color, Range range) {
|
||||
AttributeSet s = sc.addAttribute(oldSet, StyleConstants.Foreground, color);
|
||||
styledDocument.setCharacterAttributes(range.getStart(), range.getLength(), s, true);
|
||||
}
|
||||
}, tree);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static LiveDataParserPanel getLiveDataParserPanel(UIContext uiContext, final live_data_e live_data_e, final Field[] values, String fileName) {
|
||||
AtomicReference<byte[]> reference = new AtomicReference<>();
|
||||
|
||||
LiveDataParserPanel livePanel = new LiveDataParserPanel(uiContext, new VariableValueSource() {
|
||||
@Override
|
||||
public Object getValue(String name) {
|
||||
byte[] bytes = reference.get();
|
||||
if (bytes == null)
|
||||
return null;
|
||||
Field f = Field.findField(values, "", name);
|
||||
int number = f.getValue(new ConfigurationImage(bytes)).intValue();
|
||||
// System.out.println("getValue " + f);
|
||||
// convert Number to Boolean
|
||||
return number != 0;
|
||||
}
|
||||
}, fileName);
|
||||
RefreshActionsMap refreshActionsMap = new RefreshActionsMap();
|
||||
refreshActionsMap.put(live_data_e, new RefreshActions() {
|
||||
@Override
|
||||
public void refresh(BinaryProtocol bp, byte[] response) {
|
||||
reference.set(response);
|
||||
livePanel.refresh();
|
||||
}
|
||||
});
|
||||
|
||||
LiveDocsRegistry.INSTANCE.register(new LiveDocHolder(live_data_e, refreshActionsMap) {
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
JPanel panel = livePanel.getContent();
|
||||
boolean isVisible = !panel.getVisibleRect().isEmpty();
|
||||
return isVisible && isRecursivelyVisible(panel);
|
||||
}
|
||||
});
|
||||
return livePanel;
|
||||
}
|
||||
|
||||
private static boolean isRecursivelyVisible(Container c) {
|
||||
Container parent = c.getParent();
|
||||
return c.isVisible() && (parent == null || isRecursivelyVisible(parent));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package com.rusefi.livedata;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ParseResult {
|
||||
static ParseResult VOID = new ParseResult(Collections.emptyList());
|
||||
|
||||
private List<Token> configTokens;
|
||||
|
||||
public ParseResult(List<Token> configTokens) {
|
||||
this.configTokens = configTokens;
|
||||
}
|
||||
|
||||
public List<Token> getConfigTokens() {
|
||||
return configTokens;
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ import com.opensr5.ConfigurationImage;
|
|||
import com.opensr5.Logger;
|
||||
import com.rusefi.FileLog;
|
||||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||
import com.rusefi.config.Field;
|
||||
import com.rusefi.config.generated.AcControl;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.core.Sensor;
|
||||
|
@ -12,11 +11,6 @@ import com.rusefi.core.SensorCentral;
|
|||
import com.rusefi.enums.live_data_e;
|
||||
import com.rusefi.livedata.LiveDataParserPanel;
|
||||
import com.rusefi.ui.config.ConfigField;
|
||||
import com.rusefi.ui.livedata.VariableValueSource;
|
||||
import com.rusefi.ui.livedocs.LiveDocHolder;
|
||||
import com.rusefi.ui.livedocs.LiveDocsRegistry;
|
||||
import com.rusefi.ui.livedocs.RefreshActions;
|
||||
import com.rusefi.ui.livedocs.RefreshActionsMap;
|
||||
import com.rusefi.ui.util.UiUtils;
|
||||
import com.rusefi.ui.widgets.IntGaugeLabel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -30,10 +24,12 @@ import java.awt.*;
|
|||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
|
||||
/**
|
||||
* todo: it was a nice prototype of jlatexmath usage but it's time to remove it soon!
|
||||
* Lua nad live_data_e seems much more promising at the moment
|
||||
*
|
||||
* Andrey Belomutskiy, (c) 2013-2020
|
||||
*/
|
||||
public class FormulasPane {
|
||||
|
@ -52,40 +48,9 @@ public class FormulasPane {
|
|||
public FormulasPane(UIContext uiContext) {
|
||||
this.uiContext = uiContext;
|
||||
|
||||
|
||||
AtomicReference<byte[]> reference = new AtomicReference<>();
|
||||
LiveDataParserPanel livePanel = LiveDataParserPanel.getLiveDataParserPanel(uiContext, live_data_e.LDS_AC_CONTROL, AcControl.VALUES, "ac_control.cpp");
|
||||
|
||||
JPanel vertical = new JPanel(new VerticalFlowLayout());
|
||||
LiveDataParserPanel livePanel = new LiveDataParserPanel(new VariableValueSource() {
|
||||
@Override
|
||||
public Object getValue(String name) {
|
||||
byte[] bytes = reference.get();
|
||||
if (bytes == null)
|
||||
return null;
|
||||
Field f = Field.findField(AcControl.VALUES, "", name);
|
||||
int number = f.getValue(new ConfigurationImage(bytes)).intValue();
|
||||
System.out.println("getValue");
|
||||
return number != 0;
|
||||
}
|
||||
});
|
||||
RefreshActionsMap refreshActionsMap = new RefreshActionsMap();
|
||||
refreshActionsMap.put(live_data_e.LDS_AC_CONTROL, new RefreshActions() {
|
||||
@Override
|
||||
public void refresh(BinaryProtocol bp, byte[] response) {
|
||||
reference.set(response);
|
||||
livePanel.refresh();
|
||||
}
|
||||
});
|
||||
|
||||
LiveDocsRegistry.INSTANCE.register(new LiveDocHolder(live_data_e.LDS_AC_CONTROL, refreshActionsMap) {
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
JPanel panel = livePanel.getContent();
|
||||
boolean isVisible = !panel.getVisibleRect().isEmpty();
|
||||
return isVisible && isRecursivelyVisible(panel);
|
||||
}
|
||||
});
|
||||
|
||||
vertical.add(livePanel.getContent());
|
||||
vertical.add(formulaProxy);
|
||||
|
||||
|
@ -318,9 +283,4 @@ public class FormulasPane {
|
|||
public JPanel getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
static boolean isRecursivelyVisible(Container c) {
|
||||
Container parent = c.getParent();
|
||||
return c.isVisible() && (parent == null || isRecursivelyVisible(parent));
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import com.rusefi.SensorSnifferCentral;
|
|||
import com.rusefi.io.CommandQueue;
|
||||
import com.rusefi.io.LinkManager;
|
||||
import com.rusefi.sensor_logs.SensorLogger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class UIContext {
|
||||
private final LinkManager linkManager = new LinkManager();
|
||||
|
@ -13,6 +14,7 @@ public class UIContext {
|
|||
|
||||
public SensorSnifferCentral sensorSnifferCentral = new SensorSnifferCentral(linkManager);
|
||||
|
||||
@NotNull
|
||||
public LinkManager getLinkManager() {
|
||||
return linkManager;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.rusefi.ui.livedata;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
public class Range {
|
||||
private final int start;
|
||||
|
@ -11,8 +12,13 @@ public class Range {
|
|||
this.stop = stop;
|
||||
}
|
||||
|
||||
public Range(Token start, Token stop) {
|
||||
this(start.getStartIndex(), stop.getStopIndex() + 1);
|
||||
}
|
||||
|
||||
|
||||
public Range(ParserRuleContext context) {
|
||||
this(context.start.getStartIndex(), context.stop.getStopIndex() + 1);
|
||||
this(context.start, context.stop);
|
||||
}
|
||||
|
||||
public int getStart() {
|
||||
|
|
|
@ -3,5 +3,7 @@ package com.rusefi.ui.livedata;
|
|||
import java.awt.*;
|
||||
|
||||
public interface SourceCodePainter {
|
||||
void paint(Color color, Range range);
|
||||
void paintBackground(Color color, Range range);
|
||||
|
||||
void paintForeground(Color color, Range range);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.rusefi.livedata;
|
||||
|
||||
import com.rusefi.ui.UIContext;
|
||||
import com.rusefi.ui.livedata.VariableValueSource;
|
||||
import com.rusefi.ui.util.FrameHelper;
|
||||
|
||||
|
@ -19,6 +20,6 @@ public class LiveDataParserSandbox {
|
|||
}
|
||||
};
|
||||
|
||||
new FrameHelper().showFrame(new LiveDataParserPanel(valueSource).getContent());
|
||||
new FrameHelper().showFrame(new LiveDataParserPanel(new UIContext(), valueSource, "ac_control.cpp").getContent());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ public class LiveDataParserTest {
|
|||
}
|
||||
};
|
||||
|
||||
String s = "bool AcState::getAcState(DECLARE_ENGINE_PARAMETER_SIGNATURE) {\n" +
|
||||
String sourceCode = "bool AcState::getAcState(DECLARE_ENGINE_PARAMETER_SIGNATURE) {\n" +
|
||||
"\tauto rpm = Sensor::getOrZero(SensorType::Rpm);\n" +
|
||||
"\n" +
|
||||
"\tengineTooSlow = rpm < 500;\n" +
|
||||
|
@ -34,9 +34,9 @@ public class LiveDataParserTest {
|
|||
"\tif (engineTooSlow) {\n" +
|
||||
"\t\treturn true;\n" +
|
||||
"\t} else {\n " +
|
||||
"auto ff2 = 1;\n" +
|
||||
"auto ff2 = CONFIG(Alternatorcontrolpin);\n" +
|
||||
"\t}\n " +
|
||||
"auto ff = 1;\n" +
|
||||
"auto ff = CONFIG(tpsMax);\n" +
|
||||
"\tif (engineTooFast) {\n" +
|
||||
"\t\treturn false;\n" +
|
||||
"\t} \n " +
|
||||
|
@ -45,15 +45,21 @@ public class LiveDataParserTest {
|
|||
|
||||
SourceCodePainter painter = new SourceCodePainter() {
|
||||
@Override
|
||||
public void paint(Color color, Range range) {
|
||||
public void paintBackground(Color color, Range range) {
|
||||
System.out.println("paint " + color + " " + range);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintForeground(Color color, Range range) {
|
||||
System.out.println("paintForeground");
|
||||
|
||||
}
|
||||
};
|
||||
ParseTree tree = LiveDataParserPanel.getParseTree(s);
|
||||
ParseTree tree = LiveDataParserPanel.getParseTree(sourceCode);
|
||||
new ParseTreeWalker().walk(new PrintCPP14ParserListener(), tree);
|
||||
|
||||
|
||||
LiveDataParserPanel.applyVariables(valueSource, s, painter, tree);
|
||||
LiveDataParserPanel.applyVariables(valueSource, sourceCode, painter, tree);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ public class PrintCPP14ParserListener implements CPP14ParserListener {
|
|||
|
||||
@Override
|
||||
public void enterPrimaryExpression(CPP14Parser.PrimaryExpressionContext ctx) {
|
||||
System.out.println("enterPrimaryExpression");
|
||||
System.out.println("enterPrimaryExpression " + ctx.getText());
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue