forked from jasder/antlr
Updated TestPerformance (features, grammar fixes)
This commit is contained in:
parent
19afb4a8bc
commit
707311996d
|
@ -169,7 +169,6 @@
|
||||||
* Character.isJavaIdentifierPart(int) returns true."
|
* Character.isJavaIdentifierPart(int) returns true."
|
||||||
*/
|
*/
|
||||||
grammar Java;
|
grammar Java;
|
||||||
options {backtrack=true; memoize=true;}
|
|
||||||
|
|
||||||
@lexer::members {
|
@lexer::members {
|
||||||
protected boolean enumIsKeyword = true;
|
protected boolean enumIsKeyword = true;
|
||||||
|
@ -184,7 +183,9 @@ compilationUnit
|
||||||
( packageDeclaration importDeclaration* typeDeclaration*
|
( packageDeclaration importDeclaration* typeDeclaration*
|
||||||
| classOrInterfaceDeclaration typeDeclaration*
|
| classOrInterfaceDeclaration typeDeclaration*
|
||||||
)
|
)
|
||||||
|
EOF
|
||||||
| packageDeclaration? importDeclaration* typeDeclaration*
|
| packageDeclaration? importDeclaration* typeDeclaration*
|
||||||
|
EOF
|
||||||
;
|
;
|
||||||
|
|
||||||
packageDeclaration
|
packageDeclaration
|
||||||
|
@ -499,7 +500,7 @@ constructorBody
|
||||||
|
|
||||||
explicitConstructorInvocation
|
explicitConstructorInvocation
|
||||||
: nonWildcardTypeArguments? ('this' | 'super') arguments ';'
|
: nonWildcardTypeArguments? ('this' | 'super') arguments ';'
|
||||||
| expression '.' nonWildcardTypeArguments? 'super' arguments ';'
|
| primary '.' nonWildcardTypeArguments? 'super' arguments ';'
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -711,17 +712,12 @@ constantExpression
|
||||||
;
|
;
|
||||||
|
|
||||||
expression
|
expression
|
||||||
: parExpression
|
: primary
|
||||||
| 'this'
|
|
||||||
| 'super'
|
|
||||||
| literal
|
|
||||||
| Identifier
|
|
||||||
| expression '.' Identifier
|
| expression '.' Identifier
|
||||||
| expression '.' 'class' // should be type.class but causes backtracking
|
|
||||||
| expression '.' 'this'
|
| expression '.' 'this'
|
||||||
| expression '.' 'super' '(' expressionList? ')'
|
| expression '.' 'super' '(' expressionList? ')'
|
||||||
| expression '.' 'super' '.' Identifier arguments?
|
|
||||||
| expression '.' 'new' Identifier '(' expressionList? ')'
|
| expression '.' 'new' Identifier '(' expressionList? ')'
|
||||||
|
| expression '.' 'super' '.' Identifier arguments?
|
||||||
| expression '.' explicitGenericInvocation
|
| expression '.' explicitGenericInvocation
|
||||||
| 'new' creator
|
| 'new' creator
|
||||||
| expression '[' expression ']'
|
| expression '[' expression ']'
|
||||||
|
@ -754,8 +750,20 @@ expression
|
||||||
| '>' '>' '='<assoc=right>
|
| '>' '>' '='<assoc=right>
|
||||||
| '>' '>' '>' '='<assoc=right>
|
| '>' '>' '>' '='<assoc=right>
|
||||||
| '<' '<' '='<assoc=right>
|
| '<' '<' '='<assoc=right>
|
||||||
| '%='<assoc=right>) expression
|
| '%='<assoc=right>
|
||||||
;
|
)
|
||||||
|
expression
|
||||||
|
;
|
||||||
|
|
||||||
|
primary
|
||||||
|
: '(' expression ')'
|
||||||
|
| 'this'
|
||||||
|
| 'super'
|
||||||
|
| literal
|
||||||
|
| Identifier
|
||||||
|
| type '.' 'class'
|
||||||
|
| 'void' '.' 'class'
|
||||||
|
;
|
||||||
|
|
||||||
creator
|
creator
|
||||||
: nonWildcardTypeArguments createdName classCreatorRest
|
: nonWildcardTypeArguments createdName classCreatorRest
|
||||||
|
@ -827,15 +835,16 @@ FloatingPointLiteral
|
||||||
| ('0'..'9')+ Exponent FloatTypeSuffix?
|
| ('0'..'9')+ Exponent FloatTypeSuffix?
|
||||||
| ('0'..'9')+ FloatTypeSuffix
|
| ('0'..'9')+ FloatTypeSuffix
|
||||||
| '0' ('x'|'X')
|
| '0' ('x'|'X')
|
||||||
( HexDigit+ '.' HexDigit* Exponent? FloatTypeSuffix?
|
( HexDigit+ ('.' HexDigit*)? HexExponent FloatTypeSuffix?
|
||||||
| '.' HexDigit+ Exponent? FloatTypeSuffix?
|
| '.' HexDigit+ HexExponent FloatTypeSuffix?
|
||||||
| HexDigit+ Exponent FloatTypeSuffix?
|
|
||||||
| HexDigit+ FloatTypeSuffix
|
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
|
|
||||||
fragment
|
fragment
|
||||||
Exponent : ('e'|'E'|'p'|'P') ('+'|'-')? ('0'..'9')+ ;
|
Exponent : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
|
||||||
|
|
||||||
|
fragment
|
||||||
|
HexExponent : ('p'|'P') ('+'|'-')? ('0'..'9')+ ;
|
||||||
|
|
||||||
fragment
|
fragment
|
||||||
FloatTypeSuffix : ('f'|'F'|'d'|'D') ;
|
FloatTypeSuffix : ('f'|'F'|'d'|'D') ;
|
||||||
|
@ -917,13 +926,13 @@ JavaIDDigit
|
||||||
'\u1040'..'\u1049'
|
'\u1040'..'\u1049'
|
||||||
;
|
;
|
||||||
|
|
||||||
WS : (' '|'\r'|'\t'|'\u000C'|'\n')+ {$channel=HIDDEN;}
|
WS : (' '|'\r'|'\t'|'\u000C'|'\n')+ -> channel(HIDDEN)
|
||||||
;
|
;
|
||||||
|
|
||||||
COMMENT
|
COMMENT
|
||||||
: '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
|
: '/*' .* '*/' -> channel(HIDDEN)
|
||||||
;
|
;
|
||||||
|
|
||||||
LINE_COMMENT
|
LINE_COMMENT
|
||||||
: '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
|
: '//' ~('\n'|'\r')* '\r'? '\n' -> channel(HIDDEN)
|
||||||
;
|
;
|
||||||
|
|
|
@ -1021,7 +1021,7 @@ WS : (' '|'\r'|'\t'|'\u000C'|'\n')+ {$channel=HIDDEN;}
|
||||||
;
|
;
|
||||||
|
|
||||||
COMMENT
|
COMMENT
|
||||||
: '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
|
: '/*' .* '*/' {$channel=HIDDEN;}
|
||||||
;
|
;
|
||||||
|
|
||||||
LINE_COMMENT
|
LINE_COMMENT
|
||||||
|
|
|
@ -1,3 +1,31 @@
|
||||||
|
/*
|
||||||
|
* [The "BSD license"]
|
||||||
|
* Copyright (c) 2012 Sam Harwell
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test;
|
package org.antlr.v4.test;
|
||||||
|
|
||||||
import org.antlr.v4.runtime.*;
|
import org.antlr.v4.runtime.*;
|
||||||
|
@ -14,11 +42,19 @@ import java.lang.reflect.Method;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import org.antlr.v4.runtime.atn.ATNConfig;
|
||||||
|
import org.antlr.v4.runtime.atn.ParserATNSimulator;
|
||||||
|
import org.antlr.v4.runtime.dfa.DFA;
|
||||||
|
import org.antlr.v4.runtime.dfa.DFAState;
|
||||||
|
|
||||||
public class TestPerformance extends BaseTest {
|
public class TestPerformance extends BaseTest {
|
||||||
/** Parse all java files under this package within the JDK_SOURCE_ROOT. */
|
/** Parse all java files under this package within the JDK_SOURCE_ROOT. */
|
||||||
private static final String TOP_PACKAGE = "java";
|
private static final String TOP_PACKAGE = "java.lang";
|
||||||
/** True to load java files from sub-packages of {@link #TOP_PACKAGE}. */
|
/** True to load java files from sub-packages of {@link #TOP_PACKAGE}. */
|
||||||
private static final boolean RECURSIVE = true;
|
private static final boolean RECURSIVE = true;
|
||||||
|
|
||||||
|
@ -27,26 +63,41 @@ public class TestPerformance extends BaseTest {
|
||||||
* the standard grammar (Java.g). In either case, the grammar is renamed in the temporary directory to Java.g
|
* the standard grammar (Java.g). In either case, the grammar is renamed in the temporary directory to Java.g
|
||||||
* before compiling.
|
* before compiling.
|
||||||
*/
|
*/
|
||||||
private static final boolean USE_LR_GRAMMAR = false;
|
private static final boolean USE_LR_GRAMMAR = true;
|
||||||
/**
|
/**
|
||||||
* True to specify the -Xforceatn option when generating the grammar, forcing all decisions in JavaParser to
|
* True to specify the -Xforce-atn option when generating the grammar, forcing all decisions in JavaParser to
|
||||||
* be handled by {@link v2ParserATNSimulator#adaptivePredict}.
|
* be handled by {@link ParserATNSimulator#adaptivePredict}.
|
||||||
*/
|
*/
|
||||||
private static final boolean FORCE_ATN = false;
|
private static final boolean FORCE_ATN = false;
|
||||||
|
/**
|
||||||
|
* True to specify the -atn option when generating the grammar. This will cause ANTLR
|
||||||
|
* to export the ATN for each decision as a DOT (GraphViz) file.
|
||||||
|
*/
|
||||||
|
private static final boolean EXPORT_ATN_GRAPHS = true;
|
||||||
|
/**
|
||||||
|
* True to delete temporary (generated and compiled) files when the test completes.
|
||||||
|
*/
|
||||||
|
private static final boolean DELETE_TEMP_FILES = true;
|
||||||
|
|
||||||
|
private static final boolean PAUSE_FOR_HEAP_DUMP = false;
|
||||||
|
|
||||||
/** Parse each file with JavaParser.compilationUnit */
|
/** Parse each file with JavaParser.compilationUnit */
|
||||||
private static final boolean RUN_PARSER = true;
|
private static final boolean RUN_PARSER = true;
|
||||||
/** True to use {@link BailErrorStrategy}, False to use {@link DefaultErrorStrategy} */
|
/** True to use {@link BailErrorStrategy}, False to use {@link DefaultErrorStrategy} */
|
||||||
private static final boolean BAIL_ON_ERROR = false;
|
private static final boolean BAIL_ON_ERROR = true;
|
||||||
/** This value is passed to {@link org.antlr.v4.runtime.Parser#setBuildParseTree}. */
|
/** This value is passed to {@link Parser#setBuildParseTree}. */
|
||||||
private static final boolean BUILD_PARSE_TREES = false;
|
private static final boolean BUILD_PARSE_TREES = false;
|
||||||
/**
|
/**
|
||||||
* Use ParseTreeWalker.DEFAULT.walk with the BlankJavaParserListener to show parse tree walking overhead.
|
* Use ParseTreeWalker.DEFAULT.walk with the BlankJavaParserListener to show parse tree walking overhead.
|
||||||
* If {@link #BUILD_PARSE_TREES} is false, the listener will instead be called during the parsing process via
|
* If {@link #BUILD_PARSE_TREES} is false, the listener will instead be called during the parsing process via
|
||||||
* {@link org.antlr.v4.runtime.Parser#addParseListener}.
|
* {@link Parser#addParseListener}.
|
||||||
*/
|
*/
|
||||||
private static final boolean BLANK_LISTENER = false;
|
private static final boolean BLANK_LISTENER = false;
|
||||||
|
|
||||||
|
private static final boolean SHOW_DFA_STATE_STATS = true;
|
||||||
|
|
||||||
|
private static final boolean SHOW_CONFIG_STATS = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true, a single JavaLexer will be used, and {@link Lexer#setInputStream} will be called to initialize it
|
* If true, a single JavaLexer will be used, and {@link Lexer#setInputStream} will be called to initialize it
|
||||||
* for each source file. In this mode, the cached DFA will be persisted throughout the lexing process.
|
* for each source file. In this mode, the cached DFA will be persisted throughout the lexing process.
|
||||||
|
@ -67,25 +118,30 @@ public class TestPerformance extends BaseTest {
|
||||||
/** Total number of passes to make over the source */
|
/** Total number of passes to make over the source */
|
||||||
private static final int PASSES = 4;
|
private static final int PASSES = 4;
|
||||||
|
|
||||||
private Lexer sharedLexer;
|
private static Lexer sharedLexer;
|
||||||
private Parser sharedParser;
|
private static Parser sharedParser;
|
||||||
@SuppressWarnings({"FieldCanBeLocal"})
|
@SuppressWarnings({"FieldCanBeLocal"})
|
||||||
private ParseTreeListener<Token> sharedListener;
|
private static ParseTreeListener<Token> sharedListener;
|
||||||
|
|
||||||
private int tokenCount;
|
private int tokenCount;
|
||||||
|
private int currentPass;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
// @Ignore
|
//@Ignore
|
||||||
public void compileJdk() throws IOException {
|
public void compileJdk() throws IOException {
|
||||||
compileParser(USE_LR_GRAMMAR);
|
|
||||||
JavaParserFactory factory = getParserFactory();
|
|
||||||
String jdkSourceRoot = System.getenv("JDK_SOURCE_ROOT");
|
String jdkSourceRoot = System.getenv("JDK_SOURCE_ROOT");
|
||||||
|
if (jdkSourceRoot == null) {
|
||||||
|
jdkSourceRoot = System.getProperty("JDK_SOURCE_ROOT");
|
||||||
|
}
|
||||||
if (jdkSourceRoot == null) {
|
if (jdkSourceRoot == null) {
|
||||||
System.err.println("The JDK_SOURCE_ROOT environment variable must be set for performance testing.");
|
System.err.println("The JDK_SOURCE_ROOT environment variable must be set for performance testing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TOP_PACKAGE.isEmpty()) {
|
compileParser(USE_LR_GRAMMAR);
|
||||||
|
JavaParserFactory factory = getParserFactory();
|
||||||
|
|
||||||
|
if (!TOP_PACKAGE.isEmpty()) {
|
||||||
jdkSourceRoot = jdkSourceRoot + '/' + TOP_PACKAGE.replace('.', '/');
|
jdkSourceRoot = jdkSourceRoot + '/' + TOP_PACKAGE.replace('.', '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,10 +149,13 @@ public class TestPerformance extends BaseTest {
|
||||||
assertTrue(directory.isDirectory());
|
assertTrue(directory.isDirectory());
|
||||||
|
|
||||||
Collection<CharStream> sources = loadSources(directory, RECURSIVE);
|
Collection<CharStream> sources = loadSources(directory, RECURSIVE);
|
||||||
System.out.format("Lex=true, Parse=%s, ForceAtn=%s, Bail=%s, BuildParseTree=%s, BlankListener=%s\n",
|
|
||||||
RUN_PARSER, FORCE_ATN, BAIL_ON_ERROR, BUILD_PARSE_TREES, BLANK_LISTENER);
|
System.out.print(getOptionsDescription());
|
||||||
|
|
||||||
|
currentPass = 0;
|
||||||
parse1(factory, sources);
|
parse1(factory, sources);
|
||||||
for (int i = 0; i < PASSES - 1; i++) {
|
for (int i = 0; i < PASSES - 1; i++) {
|
||||||
|
currentPass = i + 1;
|
||||||
if (CLEAR_DFA) {
|
if (CLEAR_DFA) {
|
||||||
sharedLexer = null;
|
sharedLexer = null;
|
||||||
sharedParser = null;
|
sharedParser = null;
|
||||||
|
@ -104,6 +163,55 @@ public class TestPerformance extends BaseTest {
|
||||||
|
|
||||||
parse2(factory, sources);
|
parse2(factory, sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sources.clear();
|
||||||
|
if (PAUSE_FOR_HEAP_DUMP) {
|
||||||
|
System.gc();
|
||||||
|
System.out.println("Pausing before application exit.");
|
||||||
|
try {
|
||||||
|
Thread.sleep(4000);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
Logger.getLogger(TestPerformance.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void eraseTempDir() {
|
||||||
|
if (DELETE_TEMP_FILES) {
|
||||||
|
super.eraseTempDir();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getOptionsDescription() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("Input=");
|
||||||
|
if (TestPerformance.TOP_PACKAGE.isEmpty()) {
|
||||||
|
builder.append("*");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
builder.append(TOP_PACKAGE).append(".*");
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append(", Grammar=").append(USE_LR_GRAMMAR ? "LR" : "Standard");
|
||||||
|
builder.append(", ForceAtn=").append(FORCE_ATN);
|
||||||
|
|
||||||
|
builder.append('\n');
|
||||||
|
|
||||||
|
builder.append("Op=Lex").append(RUN_PARSER ? "+Parse" : " only");
|
||||||
|
builder.append(", Strategy=").append(BAIL_ON_ERROR ? BailErrorStrategy.class.getSimpleName() : DefaultErrorStrategy.class.getSimpleName());
|
||||||
|
builder.append(", BuildParseTree=").append(BUILD_PARSE_TREES);
|
||||||
|
builder.append(", WalkBlankListener=").append(BLANK_LISTENER);
|
||||||
|
|
||||||
|
builder.append('\n');
|
||||||
|
|
||||||
|
builder.append("Lexer=").append(REUSE_LEXER ? "setInputStream" : "newInstance");
|
||||||
|
builder.append(", Parser=").append(REUSE_PARSER ? "setInputStream" : "newInstance");
|
||||||
|
builder.append(", AfterPass=").append(CLEAR_DFA ? "newInstance" : "setInputStream");
|
||||||
|
|
||||||
|
builder.append('\n');
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -158,6 +266,8 @@ public class TestPerformance extends BaseTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int configOutputSize = 0;
|
||||||
|
|
||||||
protected void parseSources(JavaParserFactory factory, Collection<CharStream> sources) {
|
protected void parseSources(JavaParserFactory factory, Collection<CharStream> sources) {
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
tokenCount = 0;
|
tokenCount = 0;
|
||||||
|
@ -167,7 +277,7 @@ public class TestPerformance extends BaseTest {
|
||||||
input.seek(0);
|
input.seek(0);
|
||||||
inputSize += input.size();
|
inputSize += input.size();
|
||||||
// this incurred a great deal of overhead and was causing significant variations in performance results.
|
// this incurred a great deal of overhead and was causing significant variations in performance results.
|
||||||
//System.out.format("Parsing file %s\n", file.getAbsolutePath());
|
//System.out.format("Parsing file %s\n", input.getSourceName());
|
||||||
try {
|
try {
|
||||||
factory.parseFile(input);
|
factory.parseFile(input);
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
|
@ -180,6 +290,80 @@ public class TestPerformance extends BaseTest {
|
||||||
inputSize / 1024,
|
inputSize / 1024,
|
||||||
tokenCount,
|
tokenCount,
|
||||||
System.currentTimeMillis() - startTime);
|
System.currentTimeMillis() - startTime);
|
||||||
|
|
||||||
|
if (RUN_PARSER) {
|
||||||
|
// make sure the individual DFAState objects actually have unique ATNConfig arrays
|
||||||
|
final ParserATNSimulator<?> interpreter = sharedParser.getInterpreter();
|
||||||
|
final DFA[] decisionToDFA = interpreter.decisionToDFA;
|
||||||
|
|
||||||
|
if (SHOW_DFA_STATE_STATS) {
|
||||||
|
int states = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < decisionToDFA.length; i++) {
|
||||||
|
DFA dfa = decisionToDFA[i];
|
||||||
|
if (dfa == null || dfa.states == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
states += dfa.states.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.format("There are %d DFAState instances.\n", states);
|
||||||
|
}
|
||||||
|
|
||||||
|
int localDfaCount = 0;
|
||||||
|
int globalDfaCount = 0;
|
||||||
|
int localConfigCount = 0;
|
||||||
|
int globalConfigCount = 0;
|
||||||
|
int[] contextsInDFAState = new int[0];
|
||||||
|
|
||||||
|
for (int i = 0; i < decisionToDFA.length; i++) {
|
||||||
|
DFA dfa = decisionToDFA[i];
|
||||||
|
if (dfa == null || dfa.states == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SHOW_CONFIG_STATS) {
|
||||||
|
for (DFAState state : dfa.states.keySet()) {
|
||||||
|
if (state.configset.size() >= contextsInDFAState.length) {
|
||||||
|
contextsInDFAState = Arrays.copyOf(contextsInDFAState, state.configset.size() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.isAcceptState) {
|
||||||
|
boolean hasGlobal = false;
|
||||||
|
for (ATNConfig config : state.configset) {
|
||||||
|
if (config.reachesIntoOuterContext > 0) {
|
||||||
|
globalConfigCount++;
|
||||||
|
hasGlobal = true;
|
||||||
|
} else {
|
||||||
|
localConfigCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasGlobal) {
|
||||||
|
globalDfaCount++;
|
||||||
|
} else {
|
||||||
|
localDfaCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contextsInDFAState[state.configset.size()]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SHOW_CONFIG_STATS && currentPass == 0) {
|
||||||
|
System.out.format(" DFA accept states: %d total, %d with only local context, %d with a global context\n", localDfaCount + globalDfaCount, localDfaCount, globalDfaCount);
|
||||||
|
System.out.format(" Config stats: %d total, %d local, %d global\n", localConfigCount + globalConfigCount, localConfigCount, globalConfigCount);
|
||||||
|
if (SHOW_DFA_STATE_STATS) {
|
||||||
|
for (int i = 0; i < contextsInDFAState.length; i++) {
|
||||||
|
if (contextsInDFAState[i] != 0) {
|
||||||
|
System.out.format(" %d configs = %d\n", i, contextsInDFAState[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void compileParser(boolean leftRecursive) throws IOException {
|
protected void compileParser(boolean leftRecursive) throws IOException {
|
||||||
|
@ -187,8 +371,15 @@ public class TestPerformance extends BaseTest {
|
||||||
String sourceName = leftRecursive ? "Java-LR.g" : "Java.g";
|
String sourceName = leftRecursive ? "Java-LR.g" : "Java.g";
|
||||||
String body = load(sourceName, null);
|
String body = load(sourceName, null);
|
||||||
@SuppressWarnings({"ConstantConditions"})
|
@SuppressWarnings({"ConstantConditions"})
|
||||||
String[] extraOptions = FORCE_ATN ? new String[] {"-Xforceatn"} : new String[0];
|
List<String> extraOptions = new ArrayList<String>();
|
||||||
boolean success = rawGenerateAndBuildRecognizer(grammarFileName, body, "JavaParser", "JavaLexer", extraOptions);
|
if (FORCE_ATN) {
|
||||||
|
extraOptions.add("-Xforce-atn");
|
||||||
|
}
|
||||||
|
if (EXPORT_ATN_GRAPHS) {
|
||||||
|
extraOptions.add("-atn");
|
||||||
|
}
|
||||||
|
String[] extraOptionsArray = extraOptions.toArray(new String[extraOptions.size()]);
|
||||||
|
boolean success = rawGenerateAndBuildRecognizer(grammarFileName, body, "JavaParser", "JavaLexer", extraOptionsArray);
|
||||||
assertTrue(success);
|
assertTrue(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +419,7 @@ public class TestPerformance extends BaseTest {
|
||||||
final Class<? extends Parser> parserClass = (Class<? extends Parser>)loader.loadClass("JavaParser");
|
final Class<? extends Parser> parserClass = (Class<? extends Parser>)loader.loadClass("JavaParser");
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
final Class<? extends ParseTreeListener<Token>> listenerClass = (Class<? extends ParseTreeListener<Token>>)loader.loadClass("BlankJavaListener");
|
final Class<? extends ParseTreeListener<Token>> listenerClass = (Class<? extends ParseTreeListener<Token>>)loader.loadClass("BlankJavaListener");
|
||||||
this.sharedListener = listenerClass.newInstance();
|
TestPerformance.sharedListener = listenerClass.newInstance();
|
||||||
|
|
||||||
final Constructor<? extends Lexer> lexerCtor = lexerClass.getConstructor(CharStream.class);
|
final Constructor<? extends Lexer> lexerCtor = lexerClass.getConstructor(CharStream.class);
|
||||||
final Constructor<? extends Parser> parserCtor = parserClass.getConstructor(TokenStream.class);
|
final Constructor<? extends Parser> parserCtor = parserClass.getConstructor(TokenStream.class);
|
||||||
|
@ -271,7 +462,7 @@ public class TestPerformance extends BaseTest {
|
||||||
|
|
||||||
Method parseMethod = parserClass.getMethod("compilationUnit");
|
Method parseMethod = parserClass.getMethod("compilationUnit");
|
||||||
Object parseResult = parseMethod.invoke(sharedParser);
|
Object parseResult = parseMethod.invoke(sharedParser);
|
||||||
assert parseResult instanceof ParseTree;
|
Assert.assertTrue(parseResult instanceof ParseTree);
|
||||||
|
|
||||||
if (BUILD_PARSE_TREES && BLANK_LISTENER) {
|
if (BUILD_PARSE_TREES && BLANK_LISTENER) {
|
||||||
ParseTreeWalker.DEFAULT.walk(sharedListener, (ParseTree)parseResult);
|
ParseTreeWalker.DEFAULT.walk(sharedListener, (ParseTree)parseResult);
|
||||||
|
|
Loading…
Reference in New Issue