forked from jasder/antlr
merge from master,In preparation for continuing on this experiment branch.
This commit is contained in:
commit
0141bc058a
|
@ -1,80 +0,0 @@
|
|||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-gunit</artifactId>
|
||||
<version>4.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>antlr4-gunit</name>
|
||||
<url>http://www.antlr.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-runtime</artifactId>
|
||||
<version>4.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr-runtime</artifactId>
|
||||
<version>3.4.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>ST4</artifactId>
|
||||
<version>4.0.4</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr3-maven-plugin</artifactId>
|
||||
<version>3.4</version>
|
||||
<configuration>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<verbose>true</verbose>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>antlr</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.3.2</version>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -1,43 +0,0 @@
|
|||
group jUnit;
|
||||
|
||||
jUnitClass(className, header, options, suites) ::= <<
|
||||
<header>
|
||||
|
||||
import org.antlr.runtime.*;
|
||||
import org.antlr.runtime.tree.*;
|
||||
import org.junit.Test;
|
||||
import org.junit.Before;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class <className> extends org.antlr.v4.gunit.gUnitBase {
|
||||
@Before public void setup() {
|
||||
lexerClassName = "<options.lexer>";
|
||||
parserClassName = "<options.parser>";
|
||||
<if(options.adaptor)>
|
||||
adaptorClassName = "<options.adaptor>";
|
||||
<endif>
|
||||
}
|
||||
<suites>
|
||||
}
|
||||
>>
|
||||
|
||||
header(action) ::= "<action>"
|
||||
|
||||
testSuite(name,cases) ::= <<
|
||||
<cases:{c | <c>}; separator="\n\n"> <! use {...} iterator to get <i> !>
|
||||
>>
|
||||
|
||||
parserRuleTestSuccess(input,expecting) ::= <<
|
||||
>>
|
||||
|
||||
parserRuleTestAST(ruleName,scriptLine,input,expecting) ::= <<
|
||||
@Test public void test_<name><i>() throws Exception {
|
||||
// gunit test on line <scriptLine>
|
||||
RuleReturnScope rstruct = (RuleReturnScope)execParser("<ruleName>", "<input>", <scriptLine>);
|
||||
Object actual = ((Tree)rstruct.getTree()).toStringTree();
|
||||
Object expecting = "<expecting>";
|
||||
assertEquals("testing rule <ruleName>", expecting, actual);
|
||||
}
|
||||
>>
|
||||
|
||||
string(s) ::= "<s>"
|
|
@ -1,46 +0,0 @@
|
|||
tree grammar ASTVerifier;
|
||||
|
||||
options {
|
||||
ASTLabelType=CommonTree;
|
||||
tokenVocab = gUnit;
|
||||
}
|
||||
|
||||
@header {
|
||||
package org.antlr.v4.gunit;
|
||||
}
|
||||
|
||||
gUnitDef
|
||||
: ^('gunit' ID DOC_COMMENT? (optionsSpec|header)* testsuite+)
|
||||
;
|
||||
|
||||
optionsSpec
|
||||
: ^(OPTIONS option+)
|
||||
;
|
||||
|
||||
option
|
||||
: ^('=' ID ID)
|
||||
| ^('=' ID STRING)
|
||||
;
|
||||
|
||||
header : ^('@header' ACTION);
|
||||
|
||||
testsuite
|
||||
: ^(SUITE ID ID DOC_COMMENT? testcase+)
|
||||
| ^(SUITE ID DOC_COMMENT? testcase+)
|
||||
;
|
||||
|
||||
testcase
|
||||
: ^(TEST_OK DOC_COMMENT? input)
|
||||
| ^(TEST_FAIL DOC_COMMENT? input)
|
||||
| ^(TEST_RETVAL DOC_COMMENT? input RETVAL)
|
||||
| ^(TEST_STDOUT DOC_COMMENT? input STRING)
|
||||
| ^(TEST_STDOUT DOC_COMMENT? input ML_STRING)
|
||||
| ^(TEST_TREE DOC_COMMENT? input TREE)
|
||||
| ^(TEST_ACTION DOC_COMMENT? input ACTION)
|
||||
;
|
||||
|
||||
input
|
||||
: STRING
|
||||
| ML_STRING
|
||||
| FILENAME
|
||||
;
|
|
@ -1,155 +0,0 @@
|
|||
package org.antlr.v4.gunit;
|
||||
|
||||
import org.antlr.runtime.ANTLRFileStream;
|
||||
import org.antlr.runtime.CommonTokenStream;
|
||||
import org.antlr.runtime.RuleReturnScope;
|
||||
import org.antlr.runtime.tree.BufferedTreeNodeStream;
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
import org.antlr.runtime.tree.CommonTreeNodeStream;
|
||||
import org.antlr.stringtemplate.AutoIndentWriter;
|
||||
import org.antlr.stringtemplate.StringTemplate;
|
||||
import org.antlr.stringtemplate.StringTemplateGroup;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Gen {
|
||||
// TODO: don't hardcode
|
||||
public static final String TEMPLATE_FILE =
|
||||
"/Users/parrt/antlr/code/antlr4/gunit/resources/org/antlr/v4/gunit/jUnit.stg";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if ( args.length==0 ) {help(); System.exit(0);}
|
||||
String outputDirName = ".";
|
||||
String fileName = args[0];
|
||||
if ( args[0].equals("-o") ) {
|
||||
if ( args.length<3 ) {
|
||||
help();
|
||||
System.exit(0);
|
||||
}
|
||||
outputDirName = args[1];
|
||||
fileName = args[2];
|
||||
}
|
||||
|
||||
new Gen().process(fileName, outputDirName);
|
||||
}
|
||||
|
||||
public void process(String fileName, String outputDirName) throws Exception {
|
||||
// PARSE SCRIPT
|
||||
ANTLRFileStream fs = new ANTLRFileStream(fileName);
|
||||
gUnitLexer lexer = new gUnitLexer(fs);
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
gUnitParser parser = new gUnitParser(tokens);
|
||||
RuleReturnScope r = parser.gUnitDef();
|
||||
|
||||
CommonTree scriptAST = (CommonTree)r.getTree();
|
||||
System.out.println(scriptAST.toStringTree());
|
||||
|
||||
// ANALYZE
|
||||
CommonTreeNodeStream nodes = new CommonTreeNodeStream(r.getTree());
|
||||
Semantics sem = new Semantics(nodes);
|
||||
sem.downup(scriptAST);
|
||||
|
||||
System.out.println("options="+sem.options);
|
||||
|
||||
// GENERATE CODE
|
||||
FileReader fr = new FileReader(TEMPLATE_FILE);
|
||||
StringTemplateGroup templates =
|
||||
new StringTemplateGroup(fr);
|
||||
fr.close();
|
||||
|
||||
BufferedTreeNodeStream bnodes = new BufferedTreeNodeStream(scriptAST);
|
||||
jUnitGen gen = new jUnitGen(bnodes);
|
||||
gen.setTemplateLib(templates);
|
||||
RuleReturnScope r2 = gen.gUnitDef();
|
||||
StringTemplate st = (StringTemplate)r2.getTemplate();
|
||||
st.setAttribute("options", sem.options);
|
||||
|
||||
FileWriter fw = new FileWriter(outputDirName+"/"+sem.name+".java");
|
||||
BufferedWriter bw = new BufferedWriter(fw);
|
||||
st.write(new AutoIndentWriter(bw));
|
||||
bw.close();
|
||||
}
|
||||
|
||||
/** Borrowed from Leon Su in gunit v3 */
|
||||
public static String escapeForJava(String inputString) {
|
||||
// Gotta escape literal backslash before putting in specials that use escape.
|
||||
inputString = inputString.replace("\\", "\\\\");
|
||||
// Then double quotes need escaping (singles are OK of course).
|
||||
inputString = inputString.replace("\"", "\\\"");
|
||||
// note: replace newline to String ".\n", replace tab to String ".\t"
|
||||
inputString = inputString.replace("\n", "\\n").replace("\t", "\\t").replace("\r", "\\r").replace("\b", "\\b").replace("\f", "\\f");
|
||||
|
||||
return inputString;
|
||||
}
|
||||
|
||||
public static String normalizeTreeSpec(String t) {
|
||||
List<String> words = new ArrayList<String>();
|
||||
int i = 0;
|
||||
StringBuilder word = new StringBuilder();
|
||||
while ( i<t.length() ) {
|
||||
if ( t.charAt(i)=='(' || t.charAt(i)==')' ) {
|
||||
if ( word.length()>0 ) {
|
||||
words.add(word.toString());
|
||||
word.setLength(0);
|
||||
}
|
||||
words.add(String.valueOf(t.charAt(i)));
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( Character.isWhitespace(t.charAt(i)) ) {
|
||||
// upon WS, save word
|
||||
if ( word.length()>0 ) {
|
||||
words.add(word.toString());
|
||||
word.setLength(0);
|
||||
}
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// ... "x" or ...("x"
|
||||
if ( t.charAt(i)=='"' && (i-1)>=0 &&
|
||||
(t.charAt(i-1)=='(' || Character.isWhitespace(t.charAt(i-1))) )
|
||||
{
|
||||
i++;
|
||||
while ( i<t.length() && t.charAt(i)!='"' ) {
|
||||
if ( t.charAt(i)=='\\' &&
|
||||
(i+1)<t.length() && t.charAt(i+1)=='"' ) // handle \"
|
||||
{
|
||||
word.append('"');
|
||||
i+=2;
|
||||
continue;
|
||||
}
|
||||
word.append(t.charAt(i));
|
||||
i++;
|
||||
}
|
||||
i++; // skip final "
|
||||
words.add(word.toString());
|
||||
word.setLength(0);
|
||||
continue;
|
||||
}
|
||||
word.append(t.charAt(i));
|
||||
i++;
|
||||
}
|
||||
if ( word.length()>0 ) {
|
||||
words.add(word.toString());
|
||||
}
|
||||
//System.out.println("words="+words);
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (int j=0; j<words.size(); j++) {
|
||||
if ( j>0 && !words.get(j).equals(")") &&
|
||||
!words.get(j-1).equals("(") ) {
|
||||
buf.append(' ');
|
||||
}
|
||||
buf.append(words.get(j));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static void help() {
|
||||
System.err.println("org.antlr.v4.gunit.Gen [-o output-dir] gunit-file");
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package org.antlr.v4.gunit;
|
||||
|
||||
import org.antlr.runtime.*;
|
||||
import org.antlr.runtime.tree.BufferedTreeNodeStream;
|
||||
import org.antlr.runtime.tree.Tree;
|
||||
|
||||
public class Interp {
|
||||
public static void main(String[] args) throws Exception {
|
||||
String fileName = args[0];
|
||||
ANTLRFileStream fs = new ANTLRFileStream(fileName);
|
||||
gUnitLexer lexer = new gUnitLexer(fs);
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
gUnitParser parser = new gUnitParser(tokens);
|
||||
RuleReturnScope r = parser.gUnitDef();
|
||||
System.out.println(((Tree)r.getTree()).toStringTree());
|
||||
|
||||
BufferedTreeNodeStream nodes = new BufferedTreeNodeStream(r.getTree());
|
||||
ASTVerifier verifier = new ASTVerifier(nodes);
|
||||
verifier.gUnitDef();
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
tree grammar Semantics;
|
||||
|
||||
options {
|
||||
filter=true;
|
||||
ASTLabelType=CommonTree;
|
||||
tokenVocab = gUnit;
|
||||
}
|
||||
|
||||
@header {
|
||||
package org.antlr.v4.gunit;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
}
|
||||
|
||||
@members {
|
||||
public String name;
|
||||
public Map<String,String> options = new HashMap<String,String>();
|
||||
}
|
||||
|
||||
topdown
|
||||
: optionsSpec
|
||||
| gUnitDef
|
||||
;
|
||||
|
||||
gUnitDef
|
||||
: ^('gunit' ID .*) {name = $ID.text;}
|
||||
;
|
||||
|
||||
optionsSpec
|
||||
: ^(OPTIONS option+)
|
||||
;
|
||||
|
||||
option
|
||||
: ^('=' o=ID v=ID) {options.put($o.text, $v.text);}
|
||||
| ^('=' o=ID v=STRING) {options.put($o.text, $v.text);}
|
||||
;
|
|
@ -1,155 +0,0 @@
|
|||
grammar gUnit;
|
||||
options {
|
||||
output=AST;
|
||||
ASTLabelType=CommonTree;
|
||||
}
|
||||
|
||||
tokens { SUITE; TEST_OK; TEST_FAIL; TEST_RETVAL; TEST_STDOUT; TEST_TREE; TEST_ACTION; }
|
||||
|
||||
@header {
|
||||
package org.antlr.v4.gunit;
|
||||
}
|
||||
@lexer::header {
|
||||
package org.antlr.v4.gunit;
|
||||
}
|
||||
|
||||
gUnitDef
|
||||
: DOC_COMMENT? 'gunit' ID ';' (optionsSpec|header)* testsuite+
|
||||
-> ^('gunit' ID DOC_COMMENT? optionsSpec? header? testsuite+)
|
||||
;
|
||||
|
||||
optionsSpec
|
||||
: OPTIONS (option ';')+ '}' -> ^(OPTIONS option+)
|
||||
;
|
||||
|
||||
option
|
||||
: ID '=' optionValue -> ^('=' ID optionValue)
|
||||
;
|
||||
|
||||
optionValue
|
||||
: ID
|
||||
| STRING
|
||||
;
|
||||
|
||||
header : '@header' ACTION -> ^('@header' ACTION);
|
||||
|
||||
testsuite
|
||||
: DOC_COMMENT? treeRule=ID 'walks' parserRule=ID ':' testcase+
|
||||
-> ^(SUITE $treeRule $parserRule DOC_COMMENT? testcase+)
|
||||
| DOC_COMMENT? ID ':' testcase+ -> ^(SUITE ID DOC_COMMENT? testcase+)
|
||||
;
|
||||
|
||||
testcase
|
||||
: DOC_COMMENT? input 'OK' -> ^(TEST_OK DOC_COMMENT? input)
|
||||
| DOC_COMMENT? input 'FAIL' -> ^(TEST_FAIL DOC_COMMENT? input)
|
||||
| DOC_COMMENT? input 'returns' RETVAL -> ^(TEST_RETVAL DOC_COMMENT? input RETVAL)
|
||||
| DOC_COMMENT? input '->' STRING -> ^(TEST_STDOUT DOC_COMMENT? input STRING)
|
||||
| DOC_COMMENT? input '->' ML_STRING -> ^(TEST_STDOUT DOC_COMMENT? input ML_STRING)
|
||||
| DOC_COMMENT? input '->' TREE -> ^(TEST_TREE DOC_COMMENT? input TREE)
|
||||
| DOC_COMMENT? input '->' ACTION -> ^(TEST_ACTION DOC_COMMENT? input ACTION)
|
||||
;
|
||||
|
||||
input
|
||||
: STRING
|
||||
| ML_STRING
|
||||
| FILENAME
|
||||
;
|
||||
|
||||
ACTION
|
||||
: '{' ('\\}'|'\\' ~'}'|~('\\'|'}'))* '}' {setText(getText().substring(1, getText().length()-1));}
|
||||
;
|
||||
|
||||
RETVAL
|
||||
: NESTED_RETVAL {setText(getText().substring(1, getText().length()-1));}
|
||||
;
|
||||
|
||||
fragment
|
||||
NESTED_RETVAL :
|
||||
'['
|
||||
( options {greedy=false;}
|
||||
: NESTED_RETVAL
|
||||
| .
|
||||
)*
|
||||
']'
|
||||
;
|
||||
|
||||
TREE : NESTED_AST (' '? NESTED_AST)*;
|
||||
|
||||
fragment
|
||||
NESTED_AST
|
||||
: '('
|
||||
( NESTED_AST
|
||||
| STRING_
|
||||
| ~('('|')'|'"')
|
||||
)*
|
||||
')'
|
||||
;
|
||||
|
||||
OPTIONS : 'options' WS* '{' ;
|
||||
|
||||
ID : ID_ ('.' ID_)* ;
|
||||
|
||||
fragment
|
||||
ID_ : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
|
||||
;
|
||||
|
||||
WS : ( ' '
|
||||
| '\t'
|
||||
| '\r'
|
||||
| '\n'
|
||||
) {$channel=HIDDEN;}
|
||||
;
|
||||
|
||||
SL_COMMENT
|
||||
: '//' ~('\r'|'\n')* '\r'? '\n' {$channel=HIDDEN;}
|
||||
;
|
||||
|
||||
DOC_COMMENT
|
||||
: '/**' (options {greedy=false;}:.)* '*/'
|
||||
;
|
||||
|
||||
ML_COMMENT
|
||||
: '/*' ~'*' (options {greedy=false;}:.)* '*/' {$channel=HIDDEN;}
|
||||
;
|
||||
|
||||
STRING : STRING_ {setText(getText().substring(1, getText().length()-1));} ;
|
||||
|
||||
fragment
|
||||
STRING_
|
||||
: '"' ('\\"'|'\\' ~'"'|~('\\'|'"'))+ '"'
|
||||
;
|
||||
|
||||
ML_STRING
|
||||
: '<<' .* '>>' {setText(getText().substring(2, getText().length()-2));}
|
||||
;
|
||||
|
||||
FILENAME
|
||||
: '/' ID ('/' ID)*
|
||||
| ID ('/' ID)+
|
||||
;
|
||||
|
||||
/*
|
||||
fragment
|
||||
ESC : '\\'
|
||||
( 'n'
|
||||
| 'r'
|
||||
| 't'
|
||||
| 'b'
|
||||
| 'f'
|
||||
| '"'
|
||||
| '\''
|
||||
| '\\'
|
||||
| '>'
|
||||
| 'u' XDIGIT XDIGIT XDIGIT XDIGIT
|
||||
| . // unknown, leave as it is
|
||||
)
|
||||
;
|
||||
*/
|
||||
|
||||
fragment
|
||||
XDIGIT :
|
||||
'0' .. '9'
|
||||
| 'a' .. 'f'
|
||||
| 'A' .. 'F'
|
||||
;
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
package org.antlr.v4.gunit;
|
||||
|
||||
import org.antlr.runtime.*;
|
||||
import org.antlr.runtime.tree.TreeAdaptor;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class gUnitBase {
|
||||
public String lexerClassName;
|
||||
public String parserClassName;
|
||||
public String adaptorClassName;
|
||||
|
||||
public Object execParser(
|
||||
String ruleName,
|
||||
String input,
|
||||
int scriptLine)
|
||||
throws Exception
|
||||
{
|
||||
ANTLRStringStream is = new ANTLRStringStream(input);
|
||||
Class lexerClass = Class.forName(lexerClassName);
|
||||
Class[] lexArgTypes = new Class[]{CharStream.class};
|
||||
Constructor lexConstructor = lexerClass.getConstructor(lexArgTypes);
|
||||
Object[] lexArgs = new Object[]{is};
|
||||
TokenSource lexer = (TokenSource)lexConstructor.newInstance(lexArgs);
|
||||
is.setLine(scriptLine);
|
||||
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
|
||||
Class parserClass = Class.forName(parserClassName);
|
||||
Class[] parArgTypes = new Class[]{TokenStream.class};
|
||||
Constructor parConstructor = parserClass.getConstructor(parArgTypes);
|
||||
Object[] parArgs = new Object[]{tokens};
|
||||
Parser parser = (Parser)parConstructor.newInstance(parArgs);
|
||||
|
||||
// set up customized tree adaptor if necessary
|
||||
if ( adaptorClassName!=null ) {
|
||||
parArgTypes = new Class[]{TreeAdaptor.class};
|
||||
Method m = parserClass.getMethod("setTreeAdaptor", parArgTypes);
|
||||
Class adaptorClass = Class.forName(adaptorClassName);
|
||||
m.invoke(parser, adaptorClass.newInstance());
|
||||
}
|
||||
|
||||
Method ruleMethod = parserClass.getMethod(ruleName);
|
||||
|
||||
// INVOKE RULE
|
||||
return ruleMethod.invoke(parser);
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
tree grammar jUnitGen;
|
||||
|
||||
options {
|
||||
output=template;
|
||||
ASTLabelType=CommonTree;
|
||||
tokenVocab = gUnit;
|
||||
}
|
||||
|
||||
@header {
|
||||
package org.antlr.v4.gunit;
|
||||
}
|
||||
|
||||
gUnitDef
|
||||
: ^('gunit' ID DOC_COMMENT? (optionsSpec|header)* suites+=testsuite+)
|
||||
-> jUnitClass(className={$ID.text}, header={$header.st}, suites={$suites})
|
||||
;
|
||||
|
||||
optionsSpec
|
||||
: ^(OPTIONS option+)
|
||||
;
|
||||
|
||||
option
|
||||
: ^('=' ID ID)
|
||||
| ^('=' ID STRING)
|
||||
;
|
||||
|
||||
header : ^('@header' ACTION) -> header(action={$ACTION.text});
|
||||
|
||||
testsuite
|
||||
: ^(SUITE rule=ID ID DOC_COMMENT? cases+=testcase[$rule.text]+)
|
||||
| ^(SUITE rule=ID DOC_COMMENT? cases+=testcase[$rule.text]+)
|
||||
-> testSuite(name={$rule.text}, cases={$cases})
|
||||
;
|
||||
|
||||
testcase[String ruleName]
|
||||
: ^(TEST_OK DOC_COMMENT? input)
|
||||
| ^(TEST_FAIL DOC_COMMENT? input)
|
||||
| ^(TEST_RETVAL DOC_COMMENT? input RETVAL)
|
||||
| ^(TEST_STDOUT DOC_COMMENT? input STRING)
|
||||
| ^(TEST_STDOUT DOC_COMMENT? input ML_STRING)
|
||||
| ^(TEST_TREE DOC_COMMENT? input TREE)
|
||||
-> parserRuleTestAST(ruleName={$ruleName},
|
||||
input={$input.st},
|
||||
expecting={Gen.normalizeTreeSpec($TREE.text)},
|
||||
scriptLine={$input.start.getLine()})
|
||||
| ^(TEST_ACTION DOC_COMMENT? input ACTION)
|
||||
;
|
||||
|
||||
input
|
||||
: STRING -> string(s={Gen.escapeForJava($STRING.text)})
|
||||
| ML_STRING -> string(s={Gen.escapeForJava($ML_STRING.text)})
|
||||
| FILENAME
|
||||
;
|
|
@ -36,7 +36,7 @@ import org.antlr.v4.runtime.misc.NotNull;
|
|||
import org.antlr.v4.runtime.misc.Nullable;
|
||||
|
||||
/** How to emit recognition errors */
|
||||
public interface ANTLRErrorListener<Symbol> {
|
||||
public interface ANTLRErrorListener {
|
||||
/** Upon syntax error, notify any interested parties. This is not how to
|
||||
* recover from errors or compute error messages. The parser
|
||||
* ANTLRErrorStrategy specifies how to recover from syntax errors
|
||||
|
@ -70,12 +70,12 @@ public interface ANTLRErrorListener<Symbol> {
|
|||
* the parser was able to recover in line without exiting the
|
||||
* surrounding rule.
|
||||
*/
|
||||
public <T extends Symbol> void error(Recognizer<T, ?> recognizer,
|
||||
@Nullable T offendingSymbol,
|
||||
int line,
|
||||
int charPositionInLine,
|
||||
String msg,
|
||||
@Nullable RecognitionException e);
|
||||
public void syntaxError(Recognizer<?, ?> recognizer,
|
||||
@Nullable Object offendingSymbol,
|
||||
int line,
|
||||
int charPositionInLine,
|
||||
String msg,
|
||||
@Nullable RecognitionException e);
|
||||
|
||||
/** Called when the parser detects a true ambiguity: an input sequence can be matched
|
||||
* literally by two or more pass through the grammar. ANTLR resolves the ambiguity in
|
||||
|
|
|
@ -74,28 +74,28 @@ public class ANTLRInputStream implements CharStream {
|
|||
this(r, INITIAL_BUFFER_SIZE, READ_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
public ANTLRInputStream(Reader r, int size) throws IOException {
|
||||
this(r, size, READ_BUFFER_SIZE);
|
||||
public ANTLRInputStream(Reader r, int initialSize) throws IOException {
|
||||
this(r, initialSize, READ_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
public ANTLRInputStream(Reader r, int size, int readChunkSize) throws IOException {
|
||||
load(r, size, readChunkSize);
|
||||
public ANTLRInputStream(Reader r, int initialSize, int readChunkSize) throws IOException {
|
||||
load(r, initialSize, readChunkSize);
|
||||
}
|
||||
|
||||
public ANTLRInputStream(InputStream input) throws IOException {
|
||||
this(new InputStreamReader(input), INITIAL_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
public ANTLRInputStream(InputStream input, int size) throws IOException {
|
||||
this(new InputStreamReader(input), size);
|
||||
public ANTLRInputStream(InputStream input, int initialSize) throws IOException {
|
||||
this(new InputStreamReader(input), initialSize);
|
||||
}
|
||||
|
||||
public ANTLRInputStream(InputStream input, int size, int readChunkSize) throws IOException {
|
||||
this(new InputStreamReader(input), size, readChunkSize);
|
||||
public ANTLRInputStream(InputStream input, int initialSize, int readChunkSize) throws IOException {
|
||||
this(new InputStreamReader(input), initialSize, readChunkSize);
|
||||
}
|
||||
|
||||
public void load(Reader r, int size, int readChunkSize)
|
||||
throws IOException
|
||||
throws IOException
|
||||
{
|
||||
if ( r==null ) {
|
||||
return;
|
||||
|
|
|
@ -36,15 +36,14 @@ import org.antlr.v4.runtime.misc.IntervalSet;
|
|||
*
|
||||
* @author Sam Harwell
|
||||
*/
|
||||
public class BaseErrorListener<Symbol> implements ANTLRErrorListener<Symbol> {
|
||||
|
||||
public class BaseErrorListener implements ANTLRErrorListener {
|
||||
@Override
|
||||
public <T extends Symbol> void error(Recognizer<T, ?> recognizer,
|
||||
T offendingSymbol,
|
||||
int line,
|
||||
int charPositionInLine,
|
||||
String msg,
|
||||
RecognitionException e)
|
||||
public void syntaxError(Recognizer<?, ?> recognizer,
|
||||
Object offendingSymbol,
|
||||
int line,
|
||||
int charPositionInLine,
|
||||
String msg,
|
||||
RecognitionException e)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -239,13 +239,16 @@ public class BufferedTokenStream<T extends Token> implements TokenStream {
|
|||
return getTokens(start,stop, s);
|
||||
}
|
||||
|
||||
/** Given a starting index, return the index of the next on-channel
|
||||
* token. Return i if tokens[i] is on channel.
|
||||
/** Given a starting index, return the index of the next token on channel.
|
||||
* Return i if tokens[i] is on channel. Return -1 if there are no tokens
|
||||
* on channel between i and EOF.
|
||||
*/
|
||||
protected int nextTokenOnChannel(int i, int channel) {
|
||||
sync(i);
|
||||
Token token = tokens.get(i);
|
||||
while ( token.getType()!=Token.EOF && token.getChannel()!=channel ) {
|
||||
if ( i>=size() ) return -1;
|
||||
while ( token.getChannel()!=channel ) {
|
||||
if ( token.getType()==Token.EOF ) return -1;
|
||||
i++;
|
||||
sync(i);
|
||||
token = tokens.get(i);
|
||||
|
@ -253,8 +256,9 @@ public class BufferedTokenStream<T extends Token> implements TokenStream {
|
|||
return i;
|
||||
}
|
||||
|
||||
/** Given a starting index, return the index of the previous on-channel
|
||||
* token. Return i if tokens[i] is on channel.
|
||||
/** Given a starting index, return the index of the previous token on channel.
|
||||
* Return i if tokens[i] is on channel. Return -1 if there are no tokens
|
||||
* on channel between i and 0.
|
||||
*/
|
||||
protected int previousTokenOnChannel(int i, int channel) {
|
||||
while ( i>=0 && tokens.get(i).getChannel()!=channel ) {
|
||||
|
@ -263,48 +267,75 @@ public class BufferedTokenStream<T extends Token> implements TokenStream {
|
|||
return i;
|
||||
}
|
||||
|
||||
/** Return a list of all tokens on channel to right of tokenIndex
|
||||
* until token not on channel found. Current token not considered.
|
||||
* channel is typically Lexer.DEFAULT_TOKEN_CHANNEL.
|
||||
/** Collect all tokens on specified channel to the right of
|
||||
* the current token up until we see a token on DEFAULT_TOKEN_CHANNEL or
|
||||
* EOF. If channel is -1, find any non default channel token.
|
||||
*/
|
||||
public List<T> getOffChannelTokensToRight(int tokenIndex, int channel) {
|
||||
public List<T> getHiddenTokensToRight(int tokenIndex, int channel) {
|
||||
if ( p == -1 ) setup();
|
||||
if ( tokenIndex<0 || tokenIndex>=tokens.size() ) {
|
||||
throw new IndexOutOfBoundsException(tokenIndex+" not in 0.."+(tokens.size()-1));
|
||||
}
|
||||
|
||||
int nextOnChannel = nextTokenOnChannel(tokenIndex + 1, channel);
|
||||
int nextOnChannel =
|
||||
nextTokenOnChannel(tokenIndex + 1, Lexer.DEFAULT_TOKEN_CHANNEL);
|
||||
int to;
|
||||
int from = tokenIndex+1;
|
||||
// if none onchannel to right, nextOnChannel=-1 so set to = last token
|
||||
if ( nextOnChannel == -1 ) to = size()-1;
|
||||
else to = nextOnChannel;
|
||||
|
||||
if ( nextOnChannel == tokenIndex + 1 ) return null;
|
||||
|
||||
// get tokens to right up to next on channel
|
||||
return tokens.subList(tokenIndex+1, nextOnChannel);
|
||||
return filterForChannel(from, to, channel);
|
||||
}
|
||||
|
||||
/** Return a list of all tokens on channel to left of tokenIndex
|
||||
* until token not on channel found. Current token not considered.
|
||||
* channel is typically Lexer.DEFAULT_TOKEN_CHANNEL.
|
||||
/** Collect all hidden tokens (any off-default channel) to the right of
|
||||
* the current token up until we see a token on DEFAULT_TOKEN_CHANNEL
|
||||
* of EOF.
|
||||
*/
|
||||
public List<T> getOffChannelTokensToLeft(int tokenIndex, int channel) {
|
||||
if ( p == -1 ) setup();
|
||||
if ( tokenIndex<0 || tokenIndex>=tokens.size() ) {
|
||||
throw new IndexOutOfBoundsException(tokenIndex+" not in 0.."+(tokens.size()-1));
|
||||
}
|
||||
|
||||
int prevOnChannel = previousTokenOnChannel(tokenIndex - 1, channel);
|
||||
|
||||
if ( prevOnChannel == tokenIndex - 1 ) return null;
|
||||
|
||||
// get tokens to left up starting at prev on channel + 1 to just before tokenIndex
|
||||
return tokens.subList(prevOnChannel+1, tokenIndex);
|
||||
}
|
||||
|
||||
public List<T> getHiddenTokensToRight(int tokenIndex) {
|
||||
return getOffChannelTokensToRight(tokenIndex, Lexer.DEFAULT_TOKEN_CHANNEL);
|
||||
return getHiddenTokensToRight(tokenIndex, -1);
|
||||
}
|
||||
|
||||
/** Collect all tokens on specified channel to the left of
|
||||
* the current token up until we see a token on DEFAULT_TOKEN_CHANNEL.
|
||||
* If channel is -1, find any non default channel token.
|
||||
*/
|
||||
public List<T> getHiddenTokensToLeft(int tokenIndex, int channel) {
|
||||
if ( p == -1 ) setup();
|
||||
if ( tokenIndex<0 || tokenIndex>=tokens.size() ) {
|
||||
throw new IndexOutOfBoundsException(tokenIndex+" not in 0.."+(tokens.size()-1));
|
||||
}
|
||||
|
||||
int prevOnChannel =
|
||||
previousTokenOnChannel(tokenIndex - 1, Lexer.DEFAULT_TOKEN_CHANNEL);
|
||||
if ( prevOnChannel == tokenIndex - 1 ) return null;
|
||||
// if none onchannel to left, prevOnChannel=-1 then from=0
|
||||
int from = prevOnChannel+1;
|
||||
int to = tokenIndex-1;
|
||||
|
||||
return filterForChannel(from, to, channel);
|
||||
}
|
||||
|
||||
/** Collect all hidden tokens (any off-default channel) to the left of
|
||||
* the current token up until we see a token on DEFAULT_TOKEN_CHANNEL.
|
||||
*/
|
||||
public List<T> getHiddenTokensToLeft(int tokenIndex) {
|
||||
return getOffChannelTokensToLeft(tokenIndex, Lexer.DEFAULT_TOKEN_CHANNEL);
|
||||
return getHiddenTokensToLeft(tokenIndex, -1);
|
||||
}
|
||||
|
||||
protected List<T> filterForChannel(int from, int to, int channel) {
|
||||
List<T> hidden = new ArrayList<T>();
|
||||
for (int i=from; i<=to; i++) {
|
||||
T t = tokens.get(i);
|
||||
if ( channel==-1 ) {
|
||||
if ( t.getChannel()!= Lexer.DEFAULT_TOKEN_CHANNEL ) hidden.add(t);
|
||||
}
|
||||
else {
|
||||
if ( t.getChannel()==channel ) hidden.add(t);
|
||||
}
|
||||
}
|
||||
if ( hidden.size()==0 ) return null;
|
||||
return hidden;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -36,10 +36,11 @@ public interface CharStream extends IntStream {
|
|||
public static final int MIN_CHAR = Character.MIN_VALUE;
|
||||
public static final int MAX_CHAR = Character.MAX_VALUE-1; // FFFE is max
|
||||
|
||||
/** For unbuffered streams, you can't use this; primarily I'm providing
|
||||
* a useful interface for action code. Just make sure actions don't
|
||||
* use this on streams that don't support it.
|
||||
* @param interval
|
||||
/** This is primaril a useful interface for action code.
|
||||
* Just make sure actions don't use this on streams that don't support it.
|
||||
* For unbuffered streams, you can't use this except in case
|
||||
* where interval is in current buffer window. Lexer guarantees
|
||||
* text of current token at emit() time will be available.
|
||||
*/
|
||||
public String getText(Interval interval);
|
||||
}
|
||||
|
|
|
@ -29,9 +29,24 @@
|
|||
|
||||
package org.antlr.v4.runtime;
|
||||
|
||||
import org.antlr.v4.runtime.misc.Interval;
|
||||
|
||||
public class CommonTokenFactory implements TokenFactory<CommonToken> {
|
||||
public static final TokenFactory<CommonToken> DEFAULT = new CommonTokenFactory();
|
||||
|
||||
/** Copy text for token out of input char stream. Useful when input
|
||||
* stream is unbuffered.
|
||||
* @see UnbufferedCharStream
|
||||
*/
|
||||
protected final boolean copyText;
|
||||
|
||||
/** Create factory and indicate whether or not the factory copy
|
||||
* text out of the char stream.
|
||||
*/
|
||||
public CommonTokenFactory(boolean copyText) { this.copyText = copyText; }
|
||||
|
||||
public CommonTokenFactory() { this(false); }
|
||||
|
||||
@Override
|
||||
public CommonToken create(TokenSource source, int type, String text,
|
||||
int channel, int start, int stop,
|
||||
|
@ -43,6 +58,12 @@ public class CommonTokenFactory implements TokenFactory<CommonToken> {
|
|||
if ( text!=null ) {
|
||||
t.setText(text);
|
||||
}
|
||||
else {
|
||||
if ( copyText ) {
|
||||
CharStream input = source.getInputStream();
|
||||
t.setText(input.getText(Interval.of(start,stop)));
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,16 +32,16 @@ package org.antlr.v4.runtime;
|
|||
*
|
||||
* @author Sam Harwell
|
||||
*/
|
||||
public class ConsoleErrorListener extends BaseErrorListener<Object> {
|
||||
public class ConsoleErrorListener extends BaseErrorListener {
|
||||
public static final ConsoleErrorListener INSTANCE = new ConsoleErrorListener();
|
||||
|
||||
@Override
|
||||
public <T extends Object> void error(Recognizer<T, ?> recognizer,
|
||||
T offendingSymbol,
|
||||
int line,
|
||||
int charPositionInLine,
|
||||
String msg,
|
||||
RecognitionException e)
|
||||
public void syntaxError(Recognizer<?, ?> recognizer,
|
||||
Object offendingSymbol,
|
||||
int line,
|
||||
int charPositionInLine,
|
||||
String msg,
|
||||
RecognitionException e)
|
||||
{
|
||||
System.err.println("line " + line + ":" + charPositionInLine + " " + msg);
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public class DefaultErrorStrategy implements ANTLRErrorStrategy {
|
|||
/** The index into the input stream where the last error occurred.
|
||||
* This is used to prevent infinite loops where an error is found
|
||||
* but no token is consumed during recovery...another error is found,
|
||||
* ad naseum. This is a failsafe mechanism to guarantee that at least
|
||||
* ad nauseum. This is a failsafe mechanism to guarantee that at least
|
||||
* one token/tree node is consumed for two errors.
|
||||
*/
|
||||
protected int lastErrorIndex = -1;
|
||||
|
@ -126,7 +126,8 @@ public class DefaultErrorStrategy implements ANTLRErrorStrategy {
|
|||
// lastErrorIndex+
|
||||
// ", states="+lastErrorStates);
|
||||
if ( lastErrorIndex==recognizer.getInputStream().index() &&
|
||||
lastErrorStates.contains(recognizer._ctx.s) ) {
|
||||
lastErrorStates != null &&
|
||||
lastErrorStates.contains(recognizer._ctx.s) ) {
|
||||
// uh oh, another error at same token index and previously-visited
|
||||
// state in ATN; must be a case where LT(1) is in the recovery
|
||||
// token set so nothing got consumed. Consume a single token
|
||||
|
|
|
@ -35,7 +35,7 @@ import org.antlr.v4.runtime.misc.Interval;
|
|||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.runtime.misc.NotNull;
|
||||
|
||||
public class DiagnosticErrorListener extends BaseErrorListener<Token> {
|
||||
public class DiagnosticErrorListener extends BaseErrorListener {
|
||||
@Override
|
||||
public void reportAmbiguity(@NotNull Parser recognizer,
|
||||
DFA dfa, int startIndex, int stopIndex, @NotNull IntervalSet ambigAlts,
|
||||
|
|
|
@ -1,3 +1,31 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.runtime;
|
||||
|
||||
/** This signifies any kind of mismatched input exceptions such as
|
||||
|
|
|
@ -32,7 +32,9 @@ import org.antlr.v4.runtime.atn.LexerATNSimulator;
|
|||
import org.antlr.v4.runtime.misc.Interval;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EmptyStackException;
|
||||
import java.util.List;
|
||||
|
||||
/** A lexer is recognizer that draws input symbols from a character stream.
|
||||
* lexer grammars result in a subclass of this object. A Lexer object
|
||||
|
@ -97,6 +99,8 @@ public abstract class Lexer extends Recognizer<Integer, LexerATNSimulator>
|
|||
*/
|
||||
public String _text;
|
||||
|
||||
public Lexer() { }
|
||||
|
||||
public Lexer(CharStream input) {
|
||||
this._input = input;
|
||||
}
|
||||
|
@ -126,40 +130,57 @@ public abstract class Lexer extends Recognizer<Integer, LexerATNSimulator>
|
|||
*/
|
||||
@Override
|
||||
public Token nextToken() {
|
||||
if (_hitEOF) return anEOF();
|
||||
if (_input == null) {
|
||||
throw new IllegalStateException("nextToken requires a non-null input stream.");
|
||||
}
|
||||
|
||||
outer:
|
||||
while (true) {
|
||||
_token = null;
|
||||
_channel = Token.DEFAULT_CHANNEL;
|
||||
_tokenStartCharIndex = _input.index();
|
||||
_tokenStartCharPositionInLine = getInterpreter().getCharPositionInLine();
|
||||
_tokenStartLine = getInterpreter().getLine();
|
||||
_text = null;
|
||||
do {
|
||||
_type = Token.INVALID_TYPE;
|
||||
if (_hitEOF) {
|
||||
emitEOF();
|
||||
return _token;
|
||||
}
|
||||
|
||||
// Mark start location in char stream so unbuffered streams are
|
||||
// guaranteed at least have text of current token
|
||||
int tokenStartMarker = _input.mark();
|
||||
try{
|
||||
outer:
|
||||
while (true) {
|
||||
_token = null;
|
||||
_channel = Token.DEFAULT_CHANNEL;
|
||||
_tokenStartCharIndex = _input.index();
|
||||
_tokenStartCharPositionInLine = getInterpreter().getCharPositionInLine();
|
||||
_tokenStartLine = getInterpreter().getLine();
|
||||
_text = null;
|
||||
do {
|
||||
_type = Token.INVALID_TYPE;
|
||||
// System.out.println("nextToken line "+tokenStartLine+" at "+((char)input.LA(1))+
|
||||
// " in mode "+mode+
|
||||
// " at index "+input.index());
|
||||
int ttype;
|
||||
try {
|
||||
ttype = getInterpreter().match(_input, _mode);
|
||||
}
|
||||
catch (LexerNoViableAltException e) {
|
||||
notifyListeners(e); // report error
|
||||
recover(e);
|
||||
ttype = SKIP;
|
||||
}
|
||||
if ( _input.LA(1)==CharStream.EOF ) {
|
||||
_hitEOF = true;
|
||||
}
|
||||
if ( _type == Token.INVALID_TYPE ) _type = ttype;
|
||||
if ( _type ==SKIP ) {
|
||||
continue outer;
|
||||
}
|
||||
} while ( _type ==MORE );
|
||||
if ( _token ==null ) emit();
|
||||
return _token;
|
||||
int ttype;
|
||||
try {
|
||||
ttype = getInterpreter().match(_input, _mode);
|
||||
}
|
||||
catch (LexerNoViableAltException e) {
|
||||
notifyListeners(e); // report error
|
||||
recover(e);
|
||||
ttype = SKIP;
|
||||
}
|
||||
if ( _input.LA(1)==CharStream.EOF ) {
|
||||
_hitEOF = true;
|
||||
}
|
||||
if ( _type == Token.INVALID_TYPE ) _type = ttype;
|
||||
if ( _type ==SKIP ) {
|
||||
continue outer;
|
||||
}
|
||||
} while ( _type ==MORE );
|
||||
if ( _token == null ) emit();
|
||||
return _token;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
// make sure we release marker after match or
|
||||
// unbuffered char stream will keep buffering
|
||||
_input.release(tokenStartMarker);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,10 +240,10 @@ public abstract class Lexer extends Recognizer<Integer, LexerATNSimulator>
|
|||
return _input;
|
||||
}
|
||||
|
||||
/** Currently does not support multiple emits per nextToken invocation
|
||||
* for efficiency reasons. Subclass and override this method and
|
||||
* nextToken (to push tokens into a list and pull from that list rather
|
||||
* than a single variable as this implementation does).
|
||||
/** By default does not support multiple emits per nextToken invocation
|
||||
* for efficiency reasons. Subclass and override this method, nextToken,
|
||||
* and getToken (to push tokens into a list and pull from that list
|
||||
* rather than a single variable as this implementation does).
|
||||
*/
|
||||
public void emit(Token token) {
|
||||
getInterpreter().traceEmit(token);
|
||||
|
@ -243,7 +264,7 @@ public abstract class Lexer extends Recognizer<Integer, LexerATNSimulator>
|
|||
return t;
|
||||
}
|
||||
|
||||
public Token anEOF() {
|
||||
public Token emitEOF() {
|
||||
int cpos = getCharPositionInLine();
|
||||
// The character position for EOF is one beyond the position of
|
||||
// the previous token's last character
|
||||
|
@ -253,6 +274,7 @@ public abstract class Lexer extends Recognizer<Integer, LexerATNSimulator>
|
|||
}
|
||||
Token eof = _factory.create(this, Token.EOF, null, Token.DEFAULT_CHANNEL, _input.index(), _input.index()-1,
|
||||
getLine(), cpos);
|
||||
emit(eof);
|
||||
return eof;
|
||||
}
|
||||
|
||||
|
@ -303,6 +325,9 @@ public abstract class Lexer extends Recognizer<Integer, LexerATNSimulator>
|
|||
this._text = text;
|
||||
}
|
||||
|
||||
/** Override if emitting multiple tokens. */
|
||||
public Token getToken() { return _token; }
|
||||
|
||||
public void setToken(Token _token) {
|
||||
this._token = _token;
|
||||
}
|
||||
|
@ -320,6 +345,19 @@ public abstract class Lexer extends Recognizer<Integer, LexerATNSimulator>
|
|||
return null;
|
||||
}
|
||||
|
||||
/** Return a list of all Token objects in input char stream.
|
||||
* Forces load of all tokens. Does not include EOF token.
|
||||
*/
|
||||
public List<? extends Token> getAllTokens() {
|
||||
List<Token> tokens = new ArrayList<Token>();
|
||||
Token t = nextToken();
|
||||
while ( t.getType()!=Token.EOF ) {
|
||||
tokens.add(t);
|
||||
t = nextToken();
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
public void recover(LexerNoViableAltException e) {
|
||||
getInterpreter().consume(_input); // skip a char and try again
|
||||
}
|
||||
|
@ -328,8 +366,8 @@ public abstract class Lexer extends Recognizer<Integer, LexerATNSimulator>
|
|||
String msg = "token recognition error at: '"+
|
||||
_input.getText(Interval.of(_tokenStartCharIndex, _input.index()))+"'";
|
||||
|
||||
ANTLRErrorListener<? super Integer> listener = getErrorListenerDispatch();
|
||||
listener.error(this, null, _tokenStartLine, _tokenStartCharPositionInLine, msg, e);
|
||||
ANTLRErrorListener listener = getErrorListenerDispatch();
|
||||
listener.syntaxError(this, null, _tokenStartLine, _tokenStartCharPositionInLine, msg, e);
|
||||
}
|
||||
|
||||
public String getCharErrorDisplay(int c) {
|
||||
|
|
|
@ -316,8 +316,8 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator<Token>
|
|||
charPositionInLine = ((Token) offendingToken).getCharPositionInLine();
|
||||
}
|
||||
|
||||
ANTLRErrorListener<? super Token> listener = getErrorListenerDispatch();
|
||||
listener.error(this, offendingToken, line, charPositionInLine, msg, e);
|
||||
ANTLRErrorListener listener = getErrorListenerDispatch();
|
||||
listener.syntaxError(this, offendingToken, line, charPositionInLine, msg, e);
|
||||
}
|
||||
|
||||
/** Consume the current symbol and return it. E.g., given the following
|
||||
|
|
|
@ -38,23 +38,23 @@ import java.util.Collection;
|
|||
*
|
||||
* @author Sam Harwell
|
||||
*/
|
||||
public class ProxyErrorListener<Symbol> implements ANTLRErrorListener<Symbol> {
|
||||
private final Collection<? extends ANTLRErrorListener<? super Symbol>> delegates;
|
||||
public class ProxyErrorListener implements ANTLRErrorListener {
|
||||
private final Collection<? extends ANTLRErrorListener> delegates;
|
||||
|
||||
public ProxyErrorListener(Collection<? extends ANTLRErrorListener<? super Symbol>> delegates) {
|
||||
public ProxyErrorListener(Collection<? extends ANTLRErrorListener> delegates) {
|
||||
this.delegates = delegates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Symbol> void error(Recognizer<T, ?> recognizer,
|
||||
T offendingSymbol,
|
||||
int line,
|
||||
int charPositionInLine,
|
||||
String msg,
|
||||
RecognitionException e)
|
||||
public void syntaxError(Recognizer<?, ?> recognizer,
|
||||
Object offendingSymbol,
|
||||
int line,
|
||||
int charPositionInLine,
|
||||
String msg,
|
||||
RecognitionException e)
|
||||
{
|
||||
for (ANTLRErrorListener<? super Symbol> listener : delegates) {
|
||||
listener.error(recognizer, offendingSymbol, line, charPositionInLine, msg, e);
|
||||
for (ANTLRErrorListener listener : delegates) {
|
||||
listener.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ public class ProxyErrorListener<Symbol> implements ANTLRErrorListener<Symbol> {
|
|||
IntervalSet ambigAlts,
|
||||
ATNConfigSet configs)
|
||||
{
|
||||
for (ANTLRErrorListener<? super Symbol> listener : delegates) {
|
||||
for (ANTLRErrorListener listener : delegates) {
|
||||
listener.reportAmbiguity(recognizer, dfa, startIndex, stopIndex, ambigAlts, configs);
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ public class ProxyErrorListener<Symbol> implements ANTLRErrorListener<Symbol> {
|
|||
int stopIndex,
|
||||
ATNConfigSet configs)
|
||||
{
|
||||
for (ANTLRErrorListener<? super Symbol> listener : delegates) {
|
||||
for (ANTLRErrorListener listener : delegates) {
|
||||
listener.reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, configs);
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ public class ProxyErrorListener<Symbol> implements ANTLRErrorListener<Symbol> {
|
|||
int stopIndex,
|
||||
ATNConfigSet configs)
|
||||
{
|
||||
for (ANTLRErrorListener<? super Symbol> listener : delegates) {
|
||||
for (ANTLRErrorListener listener : delegates) {
|
||||
listener.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, configs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,8 +42,10 @@ public abstract class Recognizer<Symbol, ATNInterpreter extends ATNSimulator> {
|
|||
public static final int EOF=-1;
|
||||
|
||||
@NotNull
|
||||
private List<ANTLRErrorListener<? super Symbol>> _listeners =
|
||||
new CopyOnWriteArrayList<ANTLRErrorListener<? super Symbol>>() {{ add(ConsoleErrorListener.INSTANCE); }};
|
||||
private List<ANTLRErrorListener> _listeners =
|
||||
new CopyOnWriteArrayList<ANTLRErrorListener>() {{
|
||||
add(ConsoleErrorListener.INSTANCE);
|
||||
}};
|
||||
|
||||
protected ATNInterpreter _interp;
|
||||
|
||||
|
@ -99,7 +101,7 @@ public abstract class Recognizer<Symbol, ATNInterpreter extends ATNSimulator> {
|
|||
/**
|
||||
* @throws NullPointerException if {@code listener} is {@code null}.
|
||||
*/
|
||||
public void addErrorListener(@NotNull ANTLRErrorListener<? super Symbol> listener) {
|
||||
public void addErrorListener(@NotNull ANTLRErrorListener listener) {
|
||||
if (listener == null) {
|
||||
throw new NullPointerException("listener cannot be null.");
|
||||
}
|
||||
|
@ -107,7 +109,7 @@ public abstract class Recognizer<Symbol, ATNInterpreter extends ATNSimulator> {
|
|||
_listeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeErrorListener(@NotNull ANTLRErrorListener<? super Symbol> listener) {
|
||||
public void removeErrorListener(@NotNull ANTLRErrorListener listener) {
|
||||
_listeners.remove(listener);
|
||||
}
|
||||
|
||||
|
@ -116,12 +118,12 @@ public abstract class Recognizer<Symbol, ATNInterpreter extends ATNSimulator> {
|
|||
}
|
||||
|
||||
@NotNull
|
||||
public List<? extends ANTLRErrorListener<? super Symbol>> getErrorListeners() {
|
||||
return new ArrayList<ANTLRErrorListener<? super Symbol>>(_listeners);
|
||||
public List<? extends ANTLRErrorListener> getErrorListeners() {
|
||||
return new ArrayList<ANTLRErrorListener>(_listeners);
|
||||
}
|
||||
|
||||
public ANTLRErrorListener<? super Symbol> getErrorListenerDispatch() {
|
||||
return new ProxyErrorListener<Symbol>(getErrorListeners());
|
||||
public ANTLRErrorListener getErrorListenerDispatch() {
|
||||
return new ProxyErrorListener(getErrorListeners());
|
||||
}
|
||||
|
||||
// subclass needs to override these if there are sempreds or actions
|
||||
|
|
|
@ -183,8 +183,8 @@ public class RuleContext implements ParseTree.RuleNode {
|
|||
* that they are now going to track perfectly together. Once they
|
||||
* converged on state 21, there is no way they can separate. In other
|
||||
* words, the prior stack state is not consulted when computing where to
|
||||
* go in the closure operation. ?$ and ??$ are considered the same stack.
|
||||
* If ? is popped off then $ and ?$ remain; they are now an empty and
|
||||
* go in the closure operation. x$ and xy$ are considered the same stack.
|
||||
* If x is popped off then $ and y$ remain; they are now an empty and
|
||||
* nonempty context comparison. So, if one stack is a suffix of
|
||||
* another, then it will still degenerate to the simple empty stack
|
||||
* comparison case.
|
||||
|
@ -270,7 +270,9 @@ public class RuleContext implements ParseTree.RuleNode {
|
|||
public void save(Parser parser, String fileName)
|
||||
throws IOException, PrintException
|
||||
{
|
||||
Trees.writePS(this, parser, fileName);
|
||||
// TreeViewer viewer = new TreeViewer(parser, this);
|
||||
// viewer.save(fileName);
|
||||
Trees.writePS(this, parser, fileName); // parrt routine
|
||||
}
|
||||
|
||||
public void save(Parser parser, String fileName,
|
||||
|
|
|
@ -54,7 +54,7 @@ public interface Token {
|
|||
/** Anything on different channel than DEFAULT_CHANNEL is not parsed
|
||||
* by parser.
|
||||
*/
|
||||
public static final int HIDDEN_CHANNEL = 99;
|
||||
public static final int HIDDEN_CHANNEL = 1;
|
||||
|
||||
/** Get the text of the token */
|
||||
String getText();
|
||||
|
|
|
@ -36,24 +36,36 @@ import java.io.InputStream;
|
|||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
|
||||
/** Do not buffer up the entire char stream. It does keep a small buffer
|
||||
* for efficiency and also buffers while a mark exists (set by the
|
||||
* lookahead prediction in parser). "Unbuffered" here refers to fact
|
||||
* that it doesn't buffer all data, not that's it's on demand loading of char.
|
||||
*/
|
||||
public class UnbufferedCharStream implements CharStream {
|
||||
/** A buffer of the data being scanned */
|
||||
/** A moving window buffer of the data being scanned. While there's a
|
||||
* marker, we keep adding to buffer. Otherwise, consume() resets
|
||||
* so we start filling at index 0 again.
|
||||
*/
|
||||
protected char[] data;
|
||||
|
||||
/** How many characters are actually in the buffer */
|
||||
/** How many characters are actually in the buffer; this is not
|
||||
the buffer size, that's data.length.
|
||||
*/
|
||||
protected int n;
|
||||
|
||||
/** 0..n-1 index into string of next char */
|
||||
/** 0..n-1 index into data of next char; data[p] is LA(1). */
|
||||
protected int p=0;
|
||||
|
||||
protected int earliestMarker = -1;
|
||||
|
||||
/** Absolute char index. It's the index of the char about to be
|
||||
* read via LA(1). Goes from 0 to numchar-1.
|
||||
* read via LA(1). Goes from 0 to numchar-1 in entire stream.
|
||||
*/
|
||||
protected int currentCharIndex = 0;
|
||||
|
||||
/** Buf is window into stream. This is absolute index of data[0] */
|
||||
/** Buf is window into stream. This is absolute char index into entire
|
||||
* stream of data[0]
|
||||
*/
|
||||
protected int bufferStartIndex = 0;
|
||||
|
||||
protected Reader input;
|
||||
|
@ -61,30 +73,35 @@ public class UnbufferedCharStream implements CharStream {
|
|||
/** What is name or source of this char stream? */
|
||||
public String name;
|
||||
|
||||
public UnbufferedCharStream(InputStream input) {
|
||||
this(input, 256);
|
||||
}
|
||||
/** Useful for subclasses that pull char from other than this.input. */
|
||||
public UnbufferedCharStream() {
|
||||
this(256);
|
||||
}
|
||||
|
||||
public UnbufferedCharStream(Reader input) {
|
||||
this(input, 256);
|
||||
}
|
||||
|
||||
public UnbufferedCharStream(InputStream input, int bufferSize) {
|
||||
this.input = new InputStreamReader(input);
|
||||
data = new char[bufferSize];
|
||||
}
|
||||
|
||||
public UnbufferedCharStream(Reader input, int bufferSize) {
|
||||
this.input = input;
|
||||
data = new char[bufferSize];
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
p = 0;
|
||||
earliestMarker = -1;
|
||||
currentCharIndex = 0;
|
||||
bufferStartIndex = 0;
|
||||
/** Useful for subclasses that pull char from other than this.input. */
|
||||
public UnbufferedCharStream(int bufferSize) {
|
||||
n = 0;
|
||||
data = new char[bufferSize];
|
||||
}
|
||||
|
||||
public UnbufferedCharStream(InputStream input) {
|
||||
this(input, 256);
|
||||
}
|
||||
|
||||
public UnbufferedCharStream(Reader input) {
|
||||
this(input, 256);
|
||||
}
|
||||
|
||||
public UnbufferedCharStream(InputStream input, int bufferSize) {
|
||||
this(bufferSize);
|
||||
this.input = new InputStreamReader(input);
|
||||
fill(1); // prime
|
||||
}
|
||||
|
||||
public UnbufferedCharStream(Reader input, int bufferSize) {
|
||||
this(bufferSize);
|
||||
this.input = input;
|
||||
fill(1); // prime
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -99,6 +116,7 @@ public class UnbufferedCharStream implements CharStream {
|
|||
n = 0;
|
||||
bufferStartIndex = currentCharIndex;
|
||||
}
|
||||
sync(1);
|
||||
}
|
||||
|
||||
/** Make sure we have 'need' elements from current position p. Last valid
|
||||
|
@ -114,7 +132,7 @@ public class UnbufferedCharStream implements CharStream {
|
|||
public void fill(int n) {
|
||||
for (int i=1; i<=n; i++) {
|
||||
try {
|
||||
int c = input.read();
|
||||
int c = nextChar();
|
||||
add(c);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
|
@ -123,7 +141,12 @@ public class UnbufferedCharStream implements CharStream {
|
|||
}
|
||||
}
|
||||
|
||||
protected void add(int c) {
|
||||
/** Override to provide different source of characters than this.input */
|
||||
protected int nextChar() throws IOException {
|
||||
return input.read();
|
||||
}
|
||||
|
||||
protected void add(int c) {
|
||||
if ( n>=data.length ) {
|
||||
char[] newdata = new char[data.length*2]; // resize
|
||||
System.arraycopy(data, 0, newdata, 0, data.length);
|
||||
|
@ -154,19 +177,24 @@ public class UnbufferedCharStream implements CharStream {
|
|||
throw new IllegalArgumentException("can't set marker earlier than previous existing marker: "+p+"<"+ earliestMarker);
|
||||
}
|
||||
if ( earliestMarker < 0 ) earliestMarker = m; // set first marker
|
||||
// StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
|
||||
// System.out.println(stackTrace[2].getMethodName()+": mark " + m);
|
||||
return m;
|
||||
}
|
||||
|
||||
/** Release can get markers in weird order since we reset p to beginning
|
||||
* of buffer. Might mark at 1 and then at release p = 0 etc... Don't
|
||||
* look for errors. Just reset earliestMarker if needed.
|
||||
* @param marker
|
||||
*/
|
||||
@Override
|
||||
public void release(int marker) {
|
||||
// StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
|
||||
// System.out.println(stackTrace[2].getMethodName()+": release " + marker);
|
||||
// release is noop unless we remove earliest. then we don't need to
|
||||
// keep anything in buffer. We only care about earliest. Releasing
|
||||
// marker other than earliest does nothing as we can just keep in
|
||||
// buffer.
|
||||
if ( marker < earliestMarker || marker >= n ) {
|
||||
throw new IllegalArgumentException("invalid marker: "+
|
||||
marker+" not in "+0+".."+n);
|
||||
}
|
||||
if ( marker == earliestMarker) earliestMarker = -1;
|
||||
}
|
||||
|
||||
|
@ -193,15 +221,30 @@ public class UnbufferedCharStream implements CharStream {
|
|||
|
||||
@Override
|
||||
public String getSourceName() {
|
||||
return name;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Interval interval) {
|
||||
@Override
|
||||
public String getText(Interval interval) {
|
||||
if (interval.a < bufferStartIndex || interval.b >= bufferStartIndex + n) {
|
||||
throw new UnsupportedOperationException();
|
||||
throw new UnsupportedOperationException("interval "+interval+" outside buffer: "+
|
||||
bufferStartIndex+".."+(bufferStartIndex+n));
|
||||
}
|
||||
|
||||
return new String(data, interval.a, interval.length());
|
||||
}
|
||||
}
|
||||
|
||||
/** For testing. What's in moving window into data stream? */
|
||||
public String getBuffer() {
|
||||
if ( n==0 ) return null;
|
||||
return new String(data,0,n);
|
||||
}
|
||||
|
||||
public int getBufferStartIndex() {
|
||||
return bufferStartIndex;
|
||||
}
|
||||
|
||||
public int getCurrentCharIndex() {
|
||||
return currentCharIndex;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,135 +1,212 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2011 Terence Parr
|
||||
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.runtime;
|
||||
|
||||
import org.antlr.v4.runtime.misc.Interval;
|
||||
import org.antlr.v4.runtime.misc.LookaheadStream;
|
||||
|
||||
/** A token stream that pulls tokens from the source on-demand and
|
||||
* without tracking a complete buffer of the tokens. This stream buffers
|
||||
* the minimum number of tokens possible.
|
||||
*
|
||||
* You can't use this stream if you pass whitespace or other off-channel
|
||||
* tokens to the parser. The stream can't ignore off-channel tokens.
|
||||
*
|
||||
* You can only look backwards 1 token: LT(-1).
|
||||
*
|
||||
* Use this when you need to read from a socket or other infinite stream.
|
||||
*
|
||||
* @see BufferedTokenStream
|
||||
* @see CommonTokenStream
|
||||
*/
|
||||
public class UnbufferedTokenStream<T extends Token>
|
||||
extends LookaheadStream<T>
|
||||
implements TokenStream
|
||||
{
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class UnbufferedTokenStream<T extends Token> implements TokenStream {
|
||||
protected TokenSource tokenSource;
|
||||
protected int tokenIndex = 0; // simple counter to set token index in tokens
|
||||
|
||||
/** A moving window buffer of the data being scanned. While there's a
|
||||
* marker, we keep adding to buffer. Otherwise, consume() resets
|
||||
* so we start filling at index 0 again.
|
||||
*/
|
||||
protected Token[] tokens;
|
||||
|
||||
/** How many tokens are actually in the buffer; this is not
|
||||
* the buffer size, that's tokens.length.
|
||||
*/
|
||||
protected int n;
|
||||
|
||||
/** 0..n-1 index into tokens of next token; tokens[p] is LA(1). */
|
||||
protected int p=0;
|
||||
|
||||
protected int earliestMarker = -1;
|
||||
|
||||
/** Absolute token index. It's the index of the token about to be
|
||||
* read via LA(1). Goes from 0 to numtokens-1 in entire stream.
|
||||
*/
|
||||
protected int currentTokenIndex = 0; // simple counter to set token index in tokens
|
||||
|
||||
/** Buf is window into stream. This is absolute token index into entire
|
||||
* stream of tokens[0]
|
||||
*/
|
||||
protected int bufferStartTokenIndex = 0;
|
||||
|
||||
/** Skip tokens on any channel but this one; this is how we skip whitespace... */
|
||||
// TODO: skip off-channel tokens!!!
|
||||
protected int channel = Token.DEFAULT_CHANNEL;
|
||||
|
||||
public UnbufferedTokenStream(TokenSource tokenSource) {
|
||||
this(tokenSource, 256);
|
||||
}
|
||||
|
||||
public UnbufferedTokenStream(TokenSource tokenSource, int bufferSize) {
|
||||
this.tokenSource = tokenSource;
|
||||
tokens = new Token[bufferSize];
|
||||
fill(1); // prime the pump
|
||||
}
|
||||
|
||||
@Override
|
||||
public T nextElement() {
|
||||
T t = (T)tokenSource.nextToken();
|
||||
if ( t instanceof WritableToken ) {
|
||||
((WritableToken)t).setTokenIndex(tokenIndex);
|
||||
}
|
||||
tokenIndex++;
|
||||
return t;
|
||||
@Override
|
||||
public Token get(int i) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEOF(Token o) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public Token LT(int i) {
|
||||
sync(i);
|
||||
int index = p + i - 1;
|
||||
if ( index < 0 || index > n ) throw new IndexOutOfBoundsException();
|
||||
return tokens[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public TokenSource getTokenSource() { return tokenSource; }
|
||||
@Override
|
||||
public int LA(int i) { return LT(i).getType(); }
|
||||
|
||||
@Override
|
||||
public TokenSource getTokenSource() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(RuleContext ctx) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Token start, Token stop) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consume() {
|
||||
p++;
|
||||
currentTokenIndex++;
|
||||
// have we hit end of buffer when no markers?
|
||||
if ( p==n && earliestMarker < 0 ) {
|
||||
// if so, it's an opportunity to start filling at index 0 again
|
||||
// System.out.println("p=="+n+", no marker; reset buf start index="+currentCharIndex);
|
||||
p = 0;
|
||||
n = 0;
|
||||
bufferStartTokenIndex = currentTokenIndex;
|
||||
}
|
||||
sync(1);
|
||||
}
|
||||
|
||||
/** Make sure we have 'need' elements from current position p. Last valid
|
||||
* p index is tokens.size()-1. p+need-1 is the tokens index 'need' elements
|
||||
* ahead. If we need 1 element, (p+1-1)==p must be < tokens.size().
|
||||
*/
|
||||
protected void sync(int want) {
|
||||
int need = (p+want-1) - n + 1; // how many more elements we need?
|
||||
if ( need > 0 ) fill(need); // out of elements?
|
||||
}
|
||||
|
||||
/** add n elements to buffer */
|
||||
public void fill(int n) {
|
||||
for (int i=1; i<=n; i++) {
|
||||
Token t = tokenSource.nextToken();
|
||||
if ( t instanceof WritableToken ) {
|
||||
((WritableToken)t).setTokenIndex(currentTokenIndex);
|
||||
}
|
||||
add(t);
|
||||
}
|
||||
}
|
||||
|
||||
protected void add(Token t) {
|
||||
if ( n>=tokens.length ) {
|
||||
Token[] newtokens = new Token[tokens.length*2]; // resize
|
||||
System.arraycopy(tokens, 0, newtokens, 0, tokens.length);
|
||||
tokens = newtokens;
|
||||
}
|
||||
tokens[n++] = t;
|
||||
}
|
||||
|
||||
|
||||
/** Return a marker that we can release later. Marker happens to be
|
||||
* index into buffer (not index()).
|
||||
*/
|
||||
@Override
|
||||
public int mark() {
|
||||
int m = p;
|
||||
if ( p < earliestMarker) {
|
||||
// they must have done seek to before min marker
|
||||
throw new IllegalArgumentException("can't set marker earlier than previous existing marker: "+p+"<"+ earliestMarker);
|
||||
}
|
||||
if ( earliestMarker < 0 ) earliestMarker = m; // set first marker
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(int marker) {
|
||||
// release is noop unless we remove earliest. then we don't need to
|
||||
// keep anything in buffer. We only care about earliest. Releasing
|
||||
// marker other than earliest does nothing as we can just keep in
|
||||
// buffer.
|
||||
if ( marker < earliestMarker || marker >= n ) {
|
||||
throw new IllegalArgumentException("invalid marker: "+
|
||||
marker+" not in "+0+".."+n);
|
||||
}
|
||||
if ( marker == earliestMarker) earliestMarker = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int index() {
|
||||
return p + bufferStartTokenIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seek(int index) {
|
||||
// index == to bufferStartIndex should set p to 0
|
||||
int i = index - bufferStartTokenIndex;
|
||||
if ( i < 0 || i >= n ) {
|
||||
throw new UnsupportedOperationException("seek to index outside buffer: "+
|
||||
index+" not in "+ bufferStartTokenIndex +".."+(bufferStartTokenIndex +n));
|
||||
}
|
||||
p = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
throw new UnsupportedOperationException("Unbuffered stream cannot know its size");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSourceName() {
|
||||
return tokenSource.getSourceName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Interval interval) {
|
||||
int bufferStartIndex = currentElementIndex - p;
|
||||
int bufferStopIndex = bufferStartIndex + data.size() - 1;
|
||||
int bufferStartIndex = currentTokenIndex - p;
|
||||
int bufferStopIndex = bufferStartIndex + tokens.length - 1;
|
||||
|
||||
int start = interval.a;
|
||||
int stop = interval.b;
|
||||
if (start < bufferStartIndex || stop > bufferStopIndex) {
|
||||
throw new UnsupportedOperationException();
|
||||
throw new UnsupportedOperationException("interval "+interval+" not in token buffer window: "+
|
||||
bufferStartIndex+".."+bufferStopIndex);
|
||||
}
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (int i = start; i <= stop; i++) {
|
||||
T t = data.get(i - bufferStartIndex);
|
||||
Token t = tokens[i - bufferStartIndex];
|
||||
buf.append(t.getText());
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return getText(Interval.of(0,index()));
|
||||
/** For testing. What's in moving window into tokens stream? */
|
||||
public List<T> getBuffer() {
|
||||
if ( n==0 ) return null;
|
||||
return (List<T>)Arrays.asList(Arrays.copyOfRange(tokens, 0, n));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(RuleContext ctx) {
|
||||
return getText(ctx.getSourceInterval());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Token start, Token stop) {
|
||||
if ( start!=null && stop!=null ) {
|
||||
return getText(Interval.of(start.getTokenIndex(), stop.getTokenIndex()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int LA(int i) { return LT(i).getType(); }
|
||||
|
||||
@Override
|
||||
public T get(int i) {
|
||||
int bufferStartIndex = currentElementIndex - p;
|
||||
int bufferStopIndex = bufferStartIndex + data.size() - 1;
|
||||
if (i < bufferStartIndex || i > bufferStopIndex) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
return data.get(i - bufferStartIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSourceName() { return tokenSource.getSourceName(); }
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ public class ATN {
|
|||
}
|
||||
|
||||
public DecisionState getDecisionState(int decision) {
|
||||
if ( decisionToState.size()>0 ) {
|
||||
if ( !decisionToState.isEmpty() ) {
|
||||
return decisionToState.get(decision);
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -41,6 +41,53 @@ import java.util.Set;
|
|||
|
||||
/** Specialized OrderedHashSet that can track info about the set.
|
||||
* Might be able to optimize later w/o affecting code that uses this set.
|
||||
*
|
||||
* Track configs by alt so we can compress those context trees.
|
||||
*
|
||||
* Sam's sharing: 2 configs that have same state, same alt, same sem ctx:
|
||||
* that's one atn config. ATNConfig is node in graph. context graph ptr is
|
||||
* what you share.
|
||||
*
|
||||
* equals: must remember comparing two nodes, save true/false to avoid
|
||||
* recomputing lest even graph is same cost to compare as tree. graph
|
||||
* enum of paths is same cost of tree.
|
||||
*
|
||||
* in full ctx, cannot trim suffixes but we still share.
|
||||
* merge case that looks like suffix:
|
||||
* start at s with [] then can get [10] [10 4]. graph looks like
|
||||
* 10->4, 10 also points to EMPTY.
|
||||
*
|
||||
* example.
|
||||
* a b d
|
||||
* a b c
|
||||
* what if a's are different nodes? must join
|
||||
* what if we want to add e c d?
|
||||
*
|
||||
* might be merging two graphs. crap:
|
||||
* a b d
|
||||
e b d
|
||||
a c d
|
||||
e c d
|
||||
|
||||
another case:
|
||||
a b d
|
||||
e b d
|
||||
a b d d
|
||||
e b d d
|
||||
|
||||
think about a map that is adjacency list
|
||||
|
||||
ours is more complciated due to local ctx. tomita is always doing full ctx
|
||||
so no worries about suffix.
|
||||
|
||||
merge on graph is the key so that we can call rule and have graph as parent:
|
||||
c calls b calls a, etc...
|
||||
|
||||
a->b->c
|
||||
|->b->d
|
||||
|->b->e
|
||||
|
||||
now with this config, we call another, it just points at a.
|
||||
*/
|
||||
public class ATNConfigSet implements Set<ATNConfig> {
|
||||
public static class Key {
|
||||
|
@ -159,10 +206,11 @@ public class ATNConfigSet implements Set<ATNConfig> {
|
|||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(elements().toString());
|
||||
if ( hasSemanticContext ) buf.append(",hasSemanticContext="+hasSemanticContext);
|
||||
if ( uniqueAlt!=ATN.INVALID_ALT_NUMBER ) buf.append(",uniqueAlt="+uniqueAlt);
|
||||
if ( conflictingAlts!=null ) buf.append(",conflictingAlts="+conflictingAlts);
|
||||
// buf.append(elements().toString());
|
||||
buf.append(super.toString());
|
||||
if ( hasSemanticContext ) buf.append(",hasSemanticContext=").append(hasSemanticContext);
|
||||
if ( uniqueAlt!=ATN.INVALID_ALT_NUMBER ) buf.append(",uniqueAlt=").append(uniqueAlt);
|
||||
if ( conflictingAlts!=null ) buf.append(",conflictingAlts=").append(conflictingAlts);
|
||||
if ( dipsIntoOuterContext ) buf.append(",dipsIntoOuterContext");
|
||||
return buf.toString();
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ public class ParserATNPathFinder extends ParserATNSimulator<Token> {
|
|||
|
||||
int n = s.getNumberOfTransitions();
|
||||
boolean aGoodPath = false;
|
||||
TraceTree found = null;
|
||||
TraceTree found;
|
||||
for (int j=0; j<n; j++) {
|
||||
Transition t = s.transition(j);
|
||||
if ( t.getClass() == RuleTransition.class ) {
|
||||
|
@ -165,7 +165,7 @@ public class ParserATNPathFinder extends ParserATNSimulator<Token> {
|
|||
TraceTree root, Transition t)
|
||||
{
|
||||
SemanticContext.Predicate pred = ((PredicateTransition) t).getPredicate();
|
||||
boolean pass = false;
|
||||
boolean pass;
|
||||
if ( pred.isCtxDependent ) {
|
||||
if ( ctx instanceof ParserRuleContext && ctx==initialContext ) {
|
||||
System.out.println("eval pred "+pred+"="+pred.eval(parser, ctx));
|
||||
|
|
|
@ -772,7 +772,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
|||
return st.target;
|
||||
}
|
||||
}
|
||||
else if ( trans instanceof RangeTransition ) {
|
||||
else if ( trans instanceof RangeTransition ) { // TODO: can't happen in parser, right? remove
|
||||
RangeTransition rt = (RangeTransition)trans;
|
||||
if ( ttype>=rt.from && ttype<=rt.to ) return rt.target;
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ public abstract class SemanticContext {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@NotNull Object obj) {
|
||||
public boolean equals(Object obj) {
|
||||
if ( this==obj ) return true;
|
||||
if ( !(obj instanceof AND) ) return false;
|
||||
AND other = (AND)obj;
|
||||
|
@ -162,7 +162,7 @@ public abstract class SemanticContext {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@NotNull Object obj) {
|
||||
public boolean equals(Object obj) {
|
||||
if ( this==obj ) return true;
|
||||
if ( !(obj instanceof OR) ) return false;
|
||||
OR other = (OR)obj;
|
||||
|
|
|
@ -60,7 +60,7 @@ public class DFASerializer {
|
|||
if ( t!=null && t.stateNumber != Integer.MAX_VALUE ) {
|
||||
buf.append(getStateString(s));
|
||||
String label = getEdgeLabel(i);
|
||||
buf.append("-"+label+"->"+ getStateString(t)+'\n');
|
||||
buf.append("-").append(label).append("->").append(getStateString(t)).append('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,6 +186,11 @@ public class DFAState {
|
|||
public boolean equals(Object o) {
|
||||
// compare set of ATN configurations in this set with other
|
||||
if ( this==o ) return true;
|
||||
|
||||
if (!(o instanceof DFAState)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DFAState other = (DFAState)o;
|
||||
// TODO (sam): what to do when configs==null?
|
||||
boolean sameSet = this.configset.equals(other.configset);
|
||||
|
@ -196,7 +201,7 @@ public class DFAState {
|
|||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(stateNumber + ":" + configset);
|
||||
buf.append(stateNumber).append(":").append(configset);
|
||||
if ( isAcceptState ) {
|
||||
buf.append("=>");
|
||||
if ( predicates!=null ) {
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2011 Terence Parr
|
||||
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.runtime.misc;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/** A queue that can dequeue and get(i) in O(1) and grow arbitrarily large.
|
||||
* A linked list is fast at dequeue but slow at get(i). An array is
|
||||
* the reverse. This is O(1) for both operations.
|
||||
*
|
||||
* List grows until you dequeue last element at end of buffer. Then
|
||||
* it resets to start filling at 0 again. If adds/removes are balanced, the
|
||||
* buffer will not grow too large.
|
||||
*
|
||||
* No iterator stuff as that's not how we'll use it.
|
||||
*/
|
||||
public class FastQueue<T> {
|
||||
/** dynamically-sized buffer of elements */
|
||||
protected List<T> data = new ArrayList<T>();
|
||||
/** index of next element to fill */
|
||||
protected int p = 0;
|
||||
protected int range = -1; // how deep have we gone?
|
||||
|
||||
public void reset() { clear(); }
|
||||
public void clear() { p = 0; data.clear(); }
|
||||
|
||||
/** Get and remove first element in queue */
|
||||
public T remove() {
|
||||
T o = elementAt(0);
|
||||
p++;
|
||||
// have we hit end of buffer?
|
||||
if ( p == data.size() ) {
|
||||
// if so, it's an opportunity to start filling at index 0 again
|
||||
clear(); // size goes to 0, but retains memory
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
public void add(T o) { data.add(o); }
|
||||
|
||||
public int size() { return data.size() - p; }
|
||||
|
||||
public int range() { return range; }
|
||||
|
||||
public T head() { return elementAt(0); }
|
||||
|
||||
/** Return element i elements ahead of current element. i==0 gets
|
||||
* current element. This is not an absolute index into the data list
|
||||
* since p defines the start of the real list.
|
||||
*/
|
||||
public T elementAt(int i) {
|
||||
int absIndex = p + i;
|
||||
if ( absIndex >= data.size() ) {
|
||||
throw new NoSuchElementException("queue index "+ absIndex +" > last index "+(data.size()-1));
|
||||
}
|
||||
if ( absIndex < 0 ) {
|
||||
throw new NoSuchElementException("queue index "+ absIndex +" < 0");
|
||||
}
|
||||
if ( absIndex>range ) range = absIndex;
|
||||
return data.get(absIndex);
|
||||
}
|
||||
|
||||
/** Return string of current buffer contents; non-destructive */
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
int n = size();
|
||||
for (int i=0; i<n; i++) {
|
||||
buf.append(elementAt(i));
|
||||
if ( (i+1)<n ) buf.append(" ");
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
|
@ -30,7 +30,12 @@
|
|||
package org.antlr.v4.runtime.misc;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.print.*;
|
||||
import javax.print.DocFlavor;
|
||||
import javax.print.DocPrintJob;
|
||||
import javax.print.PrintException;
|
||||
import javax.print.PrintService;
|
||||
import javax.print.SimpleDoc;
|
||||
import javax.print.StreamPrintServiceFactory;
|
||||
import javax.print.attribute.HashPrintRequestAttributeSet;
|
||||
import javax.print.attribute.PrintRequestAttributeSet;
|
||||
import javax.swing.*;
|
||||
|
@ -41,6 +46,7 @@ import java.awt.print.Printable;
|
|||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class GraphicsSupport {
|
||||
/**
|
||||
|
@ -74,11 +80,12 @@ public class GraphicsSupport {
|
|||
public static void saveImage(final JComponent comp, String fileName)
|
||||
throws IOException, PrintException
|
||||
{
|
||||
if (fileName.endsWith(".ps") || fileName.endsWith(".eps")) {
|
||||
if (fileName.endsWith(".ps") || fileName.endsWith(".eps") ) {
|
||||
DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
|
||||
String mimeType = "application/postscript";
|
||||
StreamPrintServiceFactory[] factories =
|
||||
StreamPrintServiceFactory.lookupStreamPrintServiceFactories(flavor, mimeType);
|
||||
System.out.println(Arrays.toString(factories));
|
||||
FileOutputStream out = new FileOutputStream(fileName);
|
||||
if (factories.length > 0) {
|
||||
PrintService service = factories[0].getPrintService(out);
|
||||
|
@ -87,13 +94,17 @@ public class GraphicsSupport {
|
|||
public int print(Graphics g, PageFormat pf, int page) {
|
||||
if (page >= 1) return Printable.NO_SUCH_PAGE;
|
||||
else {
|
||||
double sf1 = pf.getImageableWidth() / (comp.getWidth() + 1);
|
||||
double sf2 = pf.getImageableHeight() / (comp.getHeight() + 1);
|
||||
double s = Math.min(sf1, sf2);
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
g2.translate((pf.getWidth() - pf.getImageableWidth()) / 2,
|
||||
(pf.getHeight() - pf.getImageableHeight()) / 2);
|
||||
g2.scale(s, s);
|
||||
if ( comp.getWidth() > pf.getImageableWidth() ||
|
||||
comp.getHeight() > pf.getImageableHeight() )
|
||||
{
|
||||
double sf1 = pf.getImageableWidth() / (comp.getWidth() + 1);
|
||||
double sf2 = pf.getImageableHeight() / (comp.getHeight() + 1);
|
||||
double s = Math.min(sf1, sf2);
|
||||
g2.scale(s, s);
|
||||
}
|
||||
|
||||
comp.paint(g);
|
||||
return Printable.PAGE_EXISTS;
|
||||
|
@ -105,16 +116,20 @@ public class GraphicsSupport {
|
|||
job.print(doc, attributes);
|
||||
}
|
||||
} else {
|
||||
// parrt: works with [image/jpeg, image/png, image/x-png, image/vnd.wap.wbmp, image/bmp, image/gif]
|
||||
Rectangle rect = comp.getBounds();
|
||||
BufferedImage image = new BufferedImage(rect.width, rect.height,
|
||||
BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
g.setColor(Color.WHITE);
|
||||
g.fill(rect);
|
||||
g.setColor(Color.BLACK);
|
||||
// g.setColor(Color.BLACK);
|
||||
comp.paint(g);
|
||||
String extension = fileName.substring(fileName.lastIndexOf('.') + 1);
|
||||
ImageIO.write(image, extension, new File(fileName));
|
||||
boolean result = ImageIO.write(image, extension, new File(fileName));
|
||||
if ( !result ) {
|
||||
System.err.println("Now imager for " + extension);
|
||||
}
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,8 +90,8 @@ public class LogManager {
|
|||
}
|
||||
|
||||
public String save() throws IOException {
|
||||
String dir = System.getProperty("java.io.tmpdir");
|
||||
dir = ".";
|
||||
//String dir = System.getProperty("java.io.tmpdir");
|
||||
String dir = ".";
|
||||
String defaultFilename =
|
||||
dir + "/antlr-" +
|
||||
new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss").format(new Date()) + ".log";
|
||||
|
|
|
@ -1,175 +0,0 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2011 Terence Parr
|
||||
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.runtime.misc;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/** A lookahead queue that knows how to mark/release locations
|
||||
* in the buffer for backtracking purposes. Any markers force the FastQueue
|
||||
* superclass to keep all tokens until no more markers; then can reset
|
||||
* to avoid growing a huge buffer.
|
||||
*/
|
||||
public abstract class LookaheadStream<T> extends FastQueue<T> {
|
||||
public static final int UNINITIALIZED_EOF_ELEMENT_INDEX = Integer.MAX_VALUE;
|
||||
|
||||
/** Absolute token index. It's the index of the symbol about to be
|
||||
* read via LT(1). Goes from 0 to numtokens.
|
||||
*/
|
||||
protected int currentElementIndex = 0;
|
||||
|
||||
protected T prevElement;
|
||||
|
||||
/** Track object returned by nextElement upon end of stream;
|
||||
* Return it later when they ask for LT passed end of input.
|
||||
*/
|
||||
public T eof = null;
|
||||
|
||||
/** tracks how deep mark() calls are nested */
|
||||
protected int markDepth = 0;
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
super.reset();
|
||||
currentElementIndex = 0;
|
||||
p = 0;
|
||||
prevElement=null;
|
||||
}
|
||||
|
||||
/** Implement nextElement to supply a stream of elements to this
|
||||
* lookahead buffer. Return eof upon end of the stream we're pulling from.
|
||||
*/
|
||||
public abstract T nextElement();
|
||||
|
||||
public abstract boolean isEOF(T o);
|
||||
|
||||
/** Get and remove first element in queue; override FastQueue.remove();
|
||||
* it's the same, just checks for backtracking.
|
||||
*/
|
||||
@Override
|
||||
public T remove() {
|
||||
T o = elementAt(0);
|
||||
p++;
|
||||
// have we hit end of buffer and not backtracking?
|
||||
if ( p == data.size() && markDepth==0 ) {
|
||||
// if so, it's an opportunity to start filling at index 0 again
|
||||
clear(); // size goes to 0, but retains memory
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/** Make sure we have at least one element to remove, even if EOF */
|
||||
public void consume() {
|
||||
syncAhead(1);
|
||||
T element = remove();
|
||||
if (markDepth == 0) {
|
||||
prevElement = element;
|
||||
}
|
||||
currentElementIndex++;
|
||||
}
|
||||
|
||||
/** Make sure we have 'need' elements from current position p. Last valid
|
||||
* p index is data.size()-1. p+need-1 is the data index 'need' elements
|
||||
* ahead. If we need 1 element, (p+1-1)==p must be < data.size().
|
||||
*/
|
||||
protected void syncAhead(int need) {
|
||||
int n = (p+need-1) - data.size() + 1; // how many more elements we need?
|
||||
if ( n > 0 ) fill(n); // out of elements?
|
||||
}
|
||||
|
||||
/** add n elements to buffer */
|
||||
public void fill(int n) {
|
||||
for (int i=1; i<=n; i++) {
|
||||
T o = nextElement();
|
||||
if ( isEOF(o) ) eof = o;
|
||||
data.add(o);
|
||||
}
|
||||
}
|
||||
|
||||
/** Size of entire stream is unknown; we only know buffer size from FastQueue */
|
||||
@Override
|
||||
public int size() { throw new UnsupportedOperationException("streams are of unknown size"); }
|
||||
|
||||
public T LT(int k) {
|
||||
if ( k==0 ) {
|
||||
return null;
|
||||
}
|
||||
if ( k<0 ) return LB(-k);
|
||||
//System.out.print("LT(p="+p+","+k+")=");
|
||||
syncAhead(k);
|
||||
if ( (p+k-1) > data.size() ) return eof;
|
||||
return elementAt(k-1);
|
||||
}
|
||||
|
||||
public int index() { return currentElementIndex; }
|
||||
|
||||
public int mark() {
|
||||
markDepth++;
|
||||
return markDepth;
|
||||
}
|
||||
|
||||
public void release(int marker) {
|
||||
// no resources to release
|
||||
}
|
||||
|
||||
/** Seek to a 0-indexed position within data buffer. Can't handle
|
||||
* case where you seek beyond end of existing buffer. Normally used
|
||||
* to seek backwards in the buffer. Does not force loading of nodes.
|
||||
* Doesn't seek to absolute position in input stream since this stream
|
||||
* is unbuffered. Seeks only into our moving window of elements.
|
||||
*/
|
||||
public void seek(int index) {
|
||||
int bufferStartIndex = currentElementIndex - p;
|
||||
if (index < bufferStartIndex) {
|
||||
throw new UnsupportedOperationException("Cannot seek to the specified index.");
|
||||
}
|
||||
|
||||
if (index > currentElementIndex) {
|
||||
int startElementIndex = currentElementIndex;
|
||||
for (int i = 0; i < index - startElementIndex; i++) {
|
||||
consume();
|
||||
}
|
||||
}
|
||||
else {
|
||||
currentElementIndex = index;
|
||||
p = index - bufferStartIndex;
|
||||
}
|
||||
}
|
||||
|
||||
protected T LB(int k) {
|
||||
int bufferIndex = p - k;
|
||||
if (bufferIndex == -1) {
|
||||
return prevElement;
|
||||
}
|
||||
else if (bufferIndex >= 0 && bufferIndex < data.size()) {
|
||||
return data.get(bufferIndex);
|
||||
}
|
||||
|
||||
throw new NoSuchElementException("can't look backwards more than one token in this stream");
|
||||
}
|
||||
}
|
|
@ -94,6 +94,10 @@ public class OrderedHashSet<T> extends LinkedHashSet<T> {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof OrderedHashSet<?>)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// System.out.print("equals " + this + ", " + o+" = ");
|
||||
boolean same = elements!=null && elements.equals(((OrderedHashSet<?>)o).elements);
|
||||
// System.out.println(same);
|
||||
|
|
|
@ -50,7 +50,7 @@ import java.lang.reflect.Method;
|
|||
* postscript file. Optionally taking input file.
|
||||
*
|
||||
* $ java org.antlr.v4.runtime.misc.TestRig GrammarName startRuleName
|
||||
* [-print]
|
||||
* [-tree]
|
||||
* [-tokens] [-gui] [-ps file.ps]
|
||||
* [-trace]
|
||||
* [-diagnostics]
|
||||
|
@ -73,7 +73,7 @@ public class TestRig {
|
|||
String encoding = null;
|
||||
if ( args.length < 2 ) {
|
||||
System.err.println("java org.antlr.v4.runtime.misc.TestRig GrammarName startRuleName\n" +
|
||||
" [-tokens] [-print] [-gui] [-ps file.ps] [-encoding encodingname]\n" +
|
||||
" [-tokens] [-tree] [-gui] [-ps file.ps] [-encoding encodingname]\n" +
|
||||
" [-trace] [-diagnostics]\n"+
|
||||
" [input-filename]");
|
||||
System.err.println("Use startRuleName='tokens' if GrammarName is a lexer grammar.");
|
||||
|
@ -92,7 +92,7 @@ public class TestRig {
|
|||
inputFile = arg;
|
||||
continue;
|
||||
}
|
||||
if ( arg.equals("-print") ) {
|
||||
if ( arg.equals("-tree") ) {
|
||||
printTree = true;
|
||||
}
|
||||
if ( arg.equals("-gui") ) {
|
||||
|
@ -127,7 +127,7 @@ public class TestRig {
|
|||
// System.out.println("exec "+grammarName+"."+startRuleName);
|
||||
String lexerName = grammarName+"Lexer";
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
Class lexerClass = null;
|
||||
Class lexerClass;
|
||||
try {
|
||||
lexerClass = cl.loadClass(lexerName);
|
||||
}
|
||||
|
@ -138,6 +138,7 @@ public class TestRig {
|
|||
}
|
||||
if ( lexerClass==null ) {
|
||||
System.err.println("Can't load "+lexerName);
|
||||
return;
|
||||
}
|
||||
|
||||
InputStream is = System.in;
|
||||
|
|
|
@ -87,7 +87,7 @@ public class TraceTree implements Tree {
|
|||
states.add(0, p.state);
|
||||
p = p.parent;
|
||||
}
|
||||
if ( states.size()==0 ) return null;
|
||||
if ( states.isEmpty() ) return null;
|
||||
return states;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ public class PostScriptDocument {
|
|||
protected StringBuilder header() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("%!PS-Adobe-3.0 EPSF-3.0\n");
|
||||
b.append(boundingBox+"\n");
|
||||
b.append(boundingBox).append("\n");
|
||||
b.append("0.3 setlinewidth\n");
|
||||
b.append("%% x y w h highlight\n" +
|
||||
"/highlight {\n" +
|
||||
|
@ -116,7 +116,7 @@ public class PostScriptDocument {
|
|||
|
||||
public void lineWidth(double w) {
|
||||
lineWidth = w;
|
||||
ps.append(w+" setlinewidth\n");
|
||||
ps.append(w).append(" setlinewidth\n");
|
||||
}
|
||||
|
||||
public void move(double x, double y) {
|
||||
|
|
|
@ -34,11 +34,13 @@ import org.abego.treelayout.TreeForTreeLayout;
|
|||
import org.abego.treelayout.TreeLayout;
|
||||
import org.abego.treelayout.util.DefaultConfiguration;
|
||||
import org.antlr.v4.runtime.Parser;
|
||||
import org.antlr.v4.runtime.misc.GraphicsSupport;
|
||||
import org.antlr.v4.runtime.misc.Utils;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.antlr.v4.runtime.tree.Tree;
|
||||
import org.antlr.v4.runtime.tree.Trees;
|
||||
|
||||
import javax.print.PrintException;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
@ -47,6 +49,7 @@ import java.awt.event.ActionEvent;
|
|||
import java.awt.event.ActionListener;
|
||||
import java.awt.geom.CubicCurve2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
|
@ -324,7 +327,6 @@ public class TreeViewer extends JComponent {
|
|||
});
|
||||
}
|
||||
|
||||
/** This does not always seem to render the postscript properly
|
||||
public void save(String fileName) throws IOException, PrintException {
|
||||
JDialog dialog = new JDialog();
|
||||
Container contentPane = dialog.getContentPane();
|
||||
|
@ -335,10 +337,8 @@ public class TreeViewer extends JComponent {
|
|||
dialog.pack();
|
||||
dialog.setLocationRelativeTo(null);
|
||||
dialog.dispose();
|
||||
// dialog.setVisible(true);
|
||||
GraphicsSupport.saveImage(this, fileName);
|
||||
}
|
||||
*/
|
||||
|
||||
// ---------------------------------------------------
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
lexer grammar T;
|
||||
grammar T;
|
||||
|
||||
A : 'a' {false}? ;
|
||||
B : 'a' ;
|
||||
WS : [ \n] ;
|
||||
s : ID b ;
|
||||
b : INT ;
|
||||
|
||||
ID : [a-zA-Z]+ ;
|
||||
INT : [0-9]+ ;
|
||||
WS : [ \t\n\r]+ -> skip ;
|
||||
|
|
|
@ -1,13 +1,30 @@
|
|||
import org.antlr.v4.runtime.ANTLRFileStream;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CommonTokenFactory;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.UnbufferedCharStream;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class TestT {
|
||||
public static void main(String[] args) throws Exception {
|
||||
CharStream input = new ANTLRFileStream(args[0]);
|
||||
T lex = new T(input);
|
||||
String inputFile = null;
|
||||
if ( args.length>0 ) inputFile = args[0];
|
||||
InputStream is = System.in;
|
||||
if ( inputFile!=null ) {
|
||||
is = new FileInputStream(inputFile);
|
||||
}
|
||||
CharStream input = new UnbufferedCharStream(is);
|
||||
|
||||
TLexer lex = new TLexer(input);
|
||||
lex.setTokenFactory(new CommonTokenFactory(true));
|
||||
|
||||
CommonTokenStream tokens = new CommonTokenStream(lex);
|
||||
tokens.fill();
|
||||
System.out.println(tokens.getTokens());
|
||||
TParser parser = new TParser(tokens);
|
||||
|
||||
ParserRuleContext tree = parser.s();
|
||||
tree.save(parser, "/tmp/t.ps");
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,8 +123,7 @@ public <if(parser.abstractRecognizer)>abstract <endif>class <parser.name> extend
|
|||
<parser.tokens:{k | <k>=<parser.tokens.(k)>}; separator=", ", wrap, anchor>;
|
||||
<endif>
|
||||
public static final String[] tokenNames = {
|
||||
"\<INVALID>",
|
||||
<parser.tokenNames:{t | <t>}; separator=", ", wrap, anchor>
|
||||
<parser.tokenNames:{t | <t>}; null="\"\<INVALID>\"", separator=", ", wrap, anchor>
|
||||
};
|
||||
public static final int
|
||||
<parser.rules:{r | RULE_<r.name> = <r.index>}; separator=", ", wrap, anchor>;
|
||||
|
|
|
@ -128,7 +128,7 @@ public class Tool {
|
|||
|
||||
public static Option[] optionDefs = {
|
||||
new Option("outputDirectory", "-o", OptionArgType.STRING, "specify output directory where all output is generated"),
|
||||
new Option("libDirectory", "-lib", OptionArgType.STRING, "specify location of .token files"),
|
||||
new Option("libDirectory", "-lib", OptionArgType.STRING, "specify location of grammars, tokens files"),
|
||||
new Option("report", "-report", "print out a report about the grammar(s) processed"),
|
||||
new Option("printGrammar", "-print", "print out the grammar without actions"),
|
||||
new Option("debug", "-debug", "generate a parser that emits debugging events"),
|
||||
|
@ -306,8 +306,8 @@ public class Tool {
|
|||
GrammarTransformPipeline transform = new GrammarTransformPipeline(g, this);
|
||||
transform.process();
|
||||
|
||||
LexerGrammar lexerg = null;
|
||||
GrammarRootAST lexerAST = null;
|
||||
LexerGrammar lexerg;
|
||||
GrammarRootAST lexerAST;
|
||||
if ( g.ast!=null && g.ast.grammarType== ANTLRParser.COMBINED &&
|
||||
!g.ast.hasErrors )
|
||||
{
|
||||
|
|
|
@ -49,7 +49,7 @@ public class AnalysisPipeline {
|
|||
// LEFT-RECURSION CHECK
|
||||
LeftRecursionDetector lr = new LeftRecursionDetector(g, g.atn);
|
||||
lr.check();
|
||||
if ( lr.listOfRecursiveCycles.size()>0 ) return; // bail out
|
||||
if ( !lr.listOfRecursiveCycles.isEmpty() ) return; // bail out
|
||||
|
||||
// BUILD DFA FOR EACH DECISION
|
||||
if ( !g.isLexer() ) processParser();
|
||||
|
|
|
@ -29,11 +29,20 @@
|
|||
|
||||
package org.antlr.v4.analysis;
|
||||
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.atn.ATN;
|
||||
import org.antlr.v4.runtime.atn.ATNState;
|
||||
import org.antlr.v4.runtime.atn.RuleStartState;
|
||||
import org.antlr.v4.runtime.atn.RuleStopState;
|
||||
import org.antlr.v4.runtime.atn.RuleTransition;
|
||||
import org.antlr.v4.runtime.atn.Transition;
|
||||
import org.antlr.v4.runtime.misc.OrderedHashSet;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class LeftRecursionDetector {
|
||||
Grammar g;
|
||||
|
@ -63,7 +72,7 @@ public class LeftRecursionDetector {
|
|||
check(g.getRule(start.ruleIndex), start, new HashSet<ATNState>());
|
||||
}
|
||||
//System.out.println("cycles="+listOfRecursiveCycles);
|
||||
if ( listOfRecursiveCycles.size()>0 ) {
|
||||
if ( !listOfRecursiveCycles.isEmpty() ) {
|
||||
g.tool.errMgr.leftRecursionCycles(g.fileName, listOfRecursiveCycles);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ public class LeftRecursiveRuleTransformer {
|
|||
String ruleName = prevRuleAST.getChild(0).getText();
|
||||
LeftRecursiveRuleAnalyzer leftRecursiveRuleWalker =
|
||||
new LeftRecursiveRuleAnalyzer(tokens, prevRuleAST, tool, ruleName, language);
|
||||
boolean isLeftRec = false;
|
||||
boolean isLeftRec;
|
||||
try {
|
||||
// System.out.println("TESTING ---------------\n"+
|
||||
// leftRecursiveRuleWalker.text(ruleAST));
|
||||
|
|
|
@ -29,7 +29,23 @@
|
|||
|
||||
package org.antlr.v4.automata;
|
||||
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.atn.ATNState;
|
||||
import org.antlr.v4.runtime.atn.ActionTransition;
|
||||
import org.antlr.v4.runtime.atn.AtomTransition;
|
||||
import org.antlr.v4.runtime.atn.BlockEndState;
|
||||
import org.antlr.v4.runtime.atn.BlockStartState;
|
||||
import org.antlr.v4.runtime.atn.EpsilonTransition;
|
||||
import org.antlr.v4.runtime.atn.NotSetTransition;
|
||||
import org.antlr.v4.runtime.atn.PlusBlockStartState;
|
||||
import org.antlr.v4.runtime.atn.PlusLoopbackState;
|
||||
import org.antlr.v4.runtime.atn.RuleStartState;
|
||||
import org.antlr.v4.runtime.atn.RuleStopState;
|
||||
import org.antlr.v4.runtime.atn.RuleTransition;
|
||||
import org.antlr.v4.runtime.atn.SetTransition;
|
||||
import org.antlr.v4.runtime.atn.StarBlockStartState;
|
||||
import org.antlr.v4.runtime.atn.StarLoopEntryState;
|
||||
import org.antlr.v4.runtime.atn.StarLoopbackState;
|
||||
import org.antlr.v4.runtime.atn.Transition;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -57,9 +73,9 @@ public class ATNPrinter {
|
|||
work.add(start);
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
ATNState s = null;
|
||||
ATNState s;
|
||||
|
||||
while ( work.size()>0 ) {
|
||||
while ( !work.isEmpty() ) {
|
||||
s = work.remove(0);
|
||||
if ( marked.contains(s) ) continue;
|
||||
int n = s.getNumberOfTransitions();
|
||||
|
@ -73,33 +89,33 @@ public class ATNPrinter {
|
|||
}
|
||||
buf.append(getStateString(s));
|
||||
if ( t instanceof EpsilonTransition ) {
|
||||
buf.append("->"+ getStateString(t.target)+'\n');
|
||||
buf.append("->").append(getStateString(t.target)).append('\n');
|
||||
}
|
||||
else if ( t instanceof RuleTransition ) {
|
||||
buf.append("-"+g.getRule(((RuleTransition)t).ruleIndex).name+"->"+ getStateString(t.target)+'\n');
|
||||
buf.append("-").append(g.getRule(((RuleTransition)t).ruleIndex).name).append("->").append(getStateString(t.target)).append('\n');
|
||||
}
|
||||
else if ( t instanceof ActionTransition ) {
|
||||
ActionTransition a = (ActionTransition)t;
|
||||
buf.append("-"+a.toString()+"->"+ getStateString(t.target)+'\n');
|
||||
buf.append("-").append(a.toString()).append("->").append(getStateString(t.target)).append('\n');
|
||||
}
|
||||
else if ( t instanceof SetTransition ) {
|
||||
SetTransition st = (SetTransition)t;
|
||||
boolean not = st instanceof NotSetTransition;
|
||||
if ( g.isLexer() ) {
|
||||
buf.append("-"+(not?"~":"")+st.toString()+"->"+ getStateString(t.target)+'\n');
|
||||
buf.append("-").append(not?"~":"").append(st.toString()).append("->").append(getStateString(t.target)).append('\n');
|
||||
}
|
||||
else {
|
||||
buf.append("-"+(not?"~":"")+st.label().toString(g.getTokenNames())+"->"+ getStateString(t.target)+'\n');
|
||||
buf.append("-").append(not?"~":"").append(st.label().toString(g.getTokenNames())).append("->").append(getStateString(t.target)).append('\n');
|
||||
}
|
||||
}
|
||||
else if ( t instanceof AtomTransition ) {
|
||||
AtomTransition a = (AtomTransition)t;
|
||||
String label = a.toString();
|
||||
if ( g!=null ) label = g.getTokenDisplayName(a.label);
|
||||
buf.append("-"+label+"->"+ getStateString(t.target)+'\n');
|
||||
buf.append("-").append(label).append("->").append(getStateString(t.target)).append('\n');
|
||||
}
|
||||
else {
|
||||
buf.append("-"+t.toString()+"->"+ getStateString(t.target)+'\n');
|
||||
buf.append("-").append(t.toString()).append("->").append(getStateString(t.target)).append('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,18 @@ package org.antlr.v4.automata;
|
|||
|
||||
import org.antlr.v4.misc.Utils;
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.atn.ATN;
|
||||
import org.antlr.v4.runtime.atn.ATNSimulator;
|
||||
import org.antlr.v4.runtime.atn.ATNState;
|
||||
import org.antlr.v4.runtime.atn.ActionTransition;
|
||||
import org.antlr.v4.runtime.atn.AtomTransition;
|
||||
import org.antlr.v4.runtime.atn.DecisionState;
|
||||
import org.antlr.v4.runtime.atn.LoopEndState;
|
||||
import org.antlr.v4.runtime.atn.PredicateTransition;
|
||||
import org.antlr.v4.runtime.atn.RangeTransition;
|
||||
import org.antlr.v4.runtime.atn.RuleTransition;
|
||||
import org.antlr.v4.runtime.atn.SetTransition;
|
||||
import org.antlr.v4.runtime.atn.Transition;
|
||||
import org.antlr.v4.runtime.misc.Interval;
|
||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
|
@ -200,7 +211,7 @@ public class ATNSerializer {
|
|||
int p = 0;
|
||||
int grammarType = ATNSimulator.toInt(data[p++]);
|
||||
int maxType = ATNSimulator.toInt(data[p++]);
|
||||
buf.append("max type "+maxType+"\n");
|
||||
buf.append("max type ").append(maxType).append("\n");
|
||||
int nstates = ATNSimulator.toInt(data[p++]);
|
||||
for (int i=1; i<=nstates; i++) {
|
||||
int stype = ATNSimulator.toInt(data[p++]);
|
||||
|
@ -211,9 +222,9 @@ public class ATNSerializer {
|
|||
int loopBackStateNumber = ATNSimulator.toInt(data[p++]);
|
||||
arg = " "+loopBackStateNumber;
|
||||
}
|
||||
buf.append((i - 1) + ":" +
|
||||
ATNState.serializationNames.get(stype) + " "+
|
||||
ruleIndex + arg + "\n");
|
||||
buf.append(i - 1).append(":")
|
||||
.append(ATNState.serializationNames.get(stype)).append(" ")
|
||||
.append(ruleIndex).append(arg).append("\n");
|
||||
}
|
||||
int nrules = ATNSimulator.toInt(data[p++]);
|
||||
for (int i=0; i<nrules; i++) {
|
||||
|
@ -221,24 +232,24 @@ public class ATNSerializer {
|
|||
if ( g.isLexer() ) {
|
||||
int arg1 = ATNSimulator.toInt(data[p++]);
|
||||
int arg2 = ATNSimulator.toInt(data[p++]);
|
||||
buf.append("rule "+i+":"+s+" "+arg1+","+arg2+'\n');
|
||||
buf.append("rule ").append(i).append(":").append(s).append(" ").append(arg1).append(",").append(arg2).append('\n');
|
||||
}
|
||||
else {
|
||||
buf.append("rule "+i+":"+s+'\n');
|
||||
buf.append("rule ").append(i).append(":").append(s).append('\n');
|
||||
}
|
||||
}
|
||||
int nmodes = ATNSimulator.toInt(data[p++]);
|
||||
for (int i=0; i<nmodes; i++) {
|
||||
int s = ATNSimulator.toInt(data[p++]);
|
||||
buf.append("mode "+i+":"+s+'\n');
|
||||
buf.append("mode ").append(i).append(":").append(s).append('\n');
|
||||
}
|
||||
int nsets = ATNSimulator.toInt(data[p++]);
|
||||
for (int i=1; i<=nsets; i++) {
|
||||
int nintervals = ATNSimulator.toInt(data[p++]);
|
||||
buf.append((i-1)+":");
|
||||
buf.append(i-1).append(":");
|
||||
for (int j=1; j<=nintervals; j++) {
|
||||
if ( j>1 ) buf.append(", ");
|
||||
buf.append(getTokenName(ATNSimulator.toInt(data[p]))+".."+getTokenName(ATNSimulator.toInt(data[p + 1])));
|
||||
buf.append(getTokenName(ATNSimulator.toInt(data[p]))).append("..").append(getTokenName(ATNSimulator.toInt(data[p + 1])));
|
||||
p += 2;
|
||||
}
|
||||
buf.append("\n");
|
||||
|
@ -251,17 +262,17 @@ public class ATNSerializer {
|
|||
int arg1 = ATNSimulator.toInt(data[p + 3]);
|
||||
int arg2 = ATNSimulator.toInt(data[p + 4]);
|
||||
int arg3 = ATNSimulator.toInt(data[p + 5]);
|
||||
buf.append(src+"->"+trg+
|
||||
" "+Transition.serializationNames.get(ttype)+
|
||||
" "+arg1+","+arg2+","+arg3+
|
||||
"\n");
|
||||
buf.append(src).append("->").append(trg)
|
||||
.append(" ").append(Transition.serializationNames.get(ttype))
|
||||
.append(" ").append(arg1).append(",").append(arg2).append(",").append(arg3)
|
||||
.append("\n");
|
||||
p += 6;
|
||||
}
|
||||
int ndecisions = ATNSimulator.toInt(data[p++]);
|
||||
for (int i=1; i<=ndecisions; i++) {
|
||||
int s = ATNSimulator.toInt(data[p++]);
|
||||
int isGreedy = ATNSimulator.toInt(data[p++]);
|
||||
buf.append((i-1)+":"+s+" "+isGreedy+"\n");
|
||||
buf.append(i-1).append(":").append(s).append(" ").append(isGreedy).append("\n");
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
|
|
@ -31,16 +31,47 @@ package org.antlr.v4.codegen;
|
|||
|
||||
import org.antlr.runtime.tree.CommonTreeNodeStream;
|
||||
import org.antlr.v4.analysis.LeftRecursiveRuleAltInfo;
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
import org.antlr.v4.codegen.model.Action;
|
||||
import org.antlr.v4.codegen.model.AltBlock;
|
||||
import org.antlr.v4.codegen.model.BaseListenerFile;
|
||||
import org.antlr.v4.codegen.model.BaseParseListenerFile;
|
||||
import org.antlr.v4.codegen.model.BaseVisitorFile;
|
||||
import org.antlr.v4.codegen.model.Choice;
|
||||
import org.antlr.v4.codegen.model.CodeBlockForAlt;
|
||||
import org.antlr.v4.codegen.model.CodeBlockForOuterMostAlt;
|
||||
import org.antlr.v4.codegen.model.LabeledOp;
|
||||
import org.antlr.v4.codegen.model.LeftRecursiveRuleFunction;
|
||||
import org.antlr.v4.codegen.model.Lexer;
|
||||
import org.antlr.v4.codegen.model.LexerFile;
|
||||
import org.antlr.v4.codegen.model.ListenerFile;
|
||||
import org.antlr.v4.codegen.model.OutputModelObject;
|
||||
import org.antlr.v4.codegen.model.ParseListenerFile;
|
||||
import org.antlr.v4.codegen.model.Parser;
|
||||
import org.antlr.v4.codegen.model.ParserFile;
|
||||
import org.antlr.v4.codegen.model.RuleActionFunction;
|
||||
import org.antlr.v4.codegen.model.RuleFunction;
|
||||
import org.antlr.v4.codegen.model.RuleSempredFunction;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.codegen.model.StarBlock;
|
||||
import org.antlr.v4.codegen.model.VisitorFile;
|
||||
import org.antlr.v4.codegen.model.decl.CodeBlock;
|
||||
import org.antlr.v4.misc.Utils;
|
||||
import org.antlr.v4.parse.*;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.tool.ast.*;
|
||||
import org.stringtemplate.v4.*;
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
import org.antlr.v4.parse.GrammarASTAdaptor;
|
||||
import org.antlr.v4.tool.Alternative;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
import org.antlr.v4.tool.LeftRecursiveRule;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
import org.antlr.v4.tool.ast.BlockAST;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
import org.antlr.v4.tool.ast.PredAST;
|
||||
import org.stringtemplate.v4.ST;
|
||||
import org.stringtemplate.v4.STGroup;
|
||||
|
||||
import java.util.*;
|
||||
import org.antlr.runtime.RecognitionException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
/** This receives events from SourceGenTriggers.g and asks factory to do work.
|
||||
* Then runs extensions in order on resulting SrcOps to get final list.
|
||||
|
@ -426,14 +457,14 @@ public class OutputModelController {
|
|||
public void setRoot(OutputModelObject root) { this.root = root; }
|
||||
|
||||
public RuleFunction getCurrentRuleFunction() {
|
||||
if ( currentRule.size()>0 ) return currentRule.peek();
|
||||
if ( !currentRule.isEmpty() ) return currentRule.peek();
|
||||
return null;
|
||||
}
|
||||
|
||||
public void pushCurrentRule(RuleFunction r) { currentRule.push(r); }
|
||||
|
||||
public RuleFunction popCurrentRule() {
|
||||
if ( currentRule.size()>0 ) return currentRule.pop();
|
||||
if ( !currentRule.isEmpty() ) return currentRule.pop();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,14 +30,21 @@
|
|||
package org.antlr.v4.codegen;
|
||||
|
||||
import org.antlr.v4.Tool;
|
||||
import org.antlr.v4.codegen.model.ModelElement;
|
||||
import org.antlr.v4.codegen.model.OutputModelObject;
|
||||
import org.antlr.v4.tool.ErrorType;
|
||||
import org.stringtemplate.v4.*;
|
||||
import org.stringtemplate.v4.ST;
|
||||
import org.stringtemplate.v4.STGroup;
|
||||
import org.stringtemplate.v4.compiler.FormalArgument;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/** Convert an output model tree to template hierarchy by walking
|
||||
* the output model. Each output model object has a corresponding template
|
||||
|
@ -94,13 +101,24 @@ public class OutputModelWalker {
|
|||
st.add(modelArgName, omo);
|
||||
|
||||
// COMPUTE STs FOR EACH NESTED MODEL OBJECT MARKED WITH @ModelElement AND MAKE ST ATTRIBUTE
|
||||
Set<String> usedFieldNames = new HashSet<String>();
|
||||
Field fields[] = cl.getFields();
|
||||
for (Field fi : fields) {
|
||||
Annotation[] annotations = fi.getAnnotations();
|
||||
if ( annotations.length==0 ) continue;
|
||||
ModelElement annotation = fi.getAnnotation(ModelElement.class);
|
||||
if (annotation == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String fieldName = fi.getName();
|
||||
|
||||
if (!usedFieldNames.add(fieldName)) {
|
||||
tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "Model object " + omo.getClass().getSimpleName() + " has multiple fields named '" + fieldName + "'");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Just don't set @ModelElement fields w/o formal arg in target ST
|
||||
if ( formalArgs.get(fieldName)==null ) continue;
|
||||
|
||||
try {
|
||||
Object o = fi.get(omo);
|
||||
if ( o instanceof OutputModelObject ) { // SINGLE MODEL OBJECT?
|
||||
|
|
|
@ -31,9 +31,10 @@ package org.antlr.v4.codegen;
|
|||
|
||||
import org.antlr.v4.codegen.model.RuleFunction;
|
||||
import org.antlr.v4.misc.Utils;
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.runtime.Lexer;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
import org.stringtemplate.v4.ST;
|
||||
|
||||
|
@ -91,20 +92,12 @@ public class Target {
|
|||
* Literals without associated names are converted to the string equivalent
|
||||
* of their integer values. Used to generate x==ID and x==34 type comparisons
|
||||
* etc... Essentially we are looking for the most obvious way to refer
|
||||
* to a token type in the generated code. If in the lexer, return the
|
||||
* char literal translated to the target language. For example, ttype=10
|
||||
* will yield '\n' from the getTokenDisplayName method. That must
|
||||
* be converted to the target languages literals. For most C-derived
|
||||
* languages no translation is needed.
|
||||
* to a token type in the generated code.
|
||||
*/
|
||||
public String getTokenTypeAsTargetLabel(Grammar g, int ttype) {
|
||||
if ( g.getType() == ANTLRParser.LEXER ) {
|
||||
// String name = g.getTokenDisplayName(ttype);
|
||||
// return getTargetCharLiteralFromANTLRCharLiteral(this,name);
|
||||
}
|
||||
String name = g.getTokenDisplayName(ttype);
|
||||
// If name is a literal, return the token type instead
|
||||
if ( name.charAt(0)=='\'' ) {
|
||||
if ( name==null || name.charAt(0)=='\'' ) {
|
||||
return String.valueOf(ttype);
|
||||
}
|
||||
return name;
|
||||
|
|
|
@ -1,3 +1,31 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
|
|
@ -1,3 +1,31 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
|
|
@ -1,3 +1,31 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
|
|
@ -1,3 +1,31 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
|
||||
package org.antlr.v4.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.*;
|
||||
import org.antlr.v4.codegen.CodeGenerator;
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.runtime.atn.PlusBlockStartState;
|
||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
|
@ -46,7 +47,6 @@ public class LL1PlusBlock extends LL1Loop {
|
|||
public String loopCounterVar;
|
||||
public String[] exitLook;
|
||||
|
||||
@ModelElement public SrcOp loopExpr;
|
||||
@ModelElement public ThrowNoViableAlt error;
|
||||
|
||||
public LL1PlusBlock(OutputModelFactory factory, GrammarAST plusRoot, List<CodeBlockForAlt> alts) {
|
||||
|
|
|
@ -1,3 +1,31 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
|
|
@ -1,3 +1,31 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
|
|
@ -37,7 +37,7 @@ public abstract class OutputModelObject {
|
|||
public OutputModelFactory factory;
|
||||
public GrammarAST ast;
|
||||
|
||||
public OutputModelObject() {;}
|
||||
public OutputModelObject() {}
|
||||
|
||||
public OutputModelObject(OutputModelFactory factory) { this(factory, null); }
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ public class RuleFunction extends OutputModelObject {
|
|||
super(factory);
|
||||
this.name = r.name;
|
||||
this.rule = r;
|
||||
if ( r.modifiers!=null && r.modifiers.size()>0 ) {
|
||||
if ( r.modifiers!=null && !r.modifiers.isEmpty() ) {
|
||||
this.modifiers = new ArrayList<String>();
|
||||
for (GrammarAST t : r.modifiers) modifiers.add(t.getText());
|
||||
}
|
||||
|
|
|
@ -1,3 +1,31 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
|
|
@ -1,3 +1,31 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
|
|
@ -1,3 +1,32 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model.chunk;
|
||||
|
||||
import org.antlr.v4.codegen.model.decl.StructDecl;
|
||||
|
|
|
@ -30,8 +30,12 @@
|
|||
package org.antlr.v4.codegen.model.decl;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.codegen.model.DispatchMethod;
|
||||
import org.antlr.v4.codegen.model.ListenerDispatchMethod;
|
||||
import org.antlr.v4.codegen.model.ParseListenerDispatchMethod;
|
||||
import org.antlr.v4.codegen.model.VisitorDispatchMethod;
|
||||
import org.antlr.v4.tool.LeftRecursiveRule;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
@ -75,10 +79,8 @@ public class AltLabelStructDecl extends StructDecl {
|
|||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if ( obj == this ) return true;
|
||||
if ( obj.hashCode() != this.hashCode() ) return false;
|
||||
if ( obj instanceof AltLabelStructDecl ) {
|
||||
return name.equals(((AltLabelStructDecl)obj).name);
|
||||
}
|
||||
return false;
|
||||
if (!(obj instanceof AltLabelStructDecl)) return false;
|
||||
|
||||
return name.equals(((AltLabelStructDecl)obj).name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,32 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model.decl;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
@ -23,11 +52,9 @@ public abstract class ContextGetterDecl extends Decl {
|
|||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if ( obj==null ) return false;
|
||||
if ( this==obj ) return true;
|
||||
// A() and label A are different
|
||||
if ( !(obj instanceof ContextGetterDecl) ) return false;
|
||||
if ( this==obj ) return true;
|
||||
if ( this.hashCode() != obj.hashCode() ) return false;
|
||||
return
|
||||
name.equals(((Decl) obj).name) &&
|
||||
getArgType().equals(((ContextGetterDecl) obj).getArgType());
|
||||
|
|
|
@ -1,8 +1,37 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model.decl;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
||||
/** public XContext X() { } */
|
||||
/** {@code public XContext X() { }} */
|
||||
public class ContextRuleGetterDecl extends ContextGetterDecl {
|
||||
public String ctxName;
|
||||
public ContextRuleGetterDecl(OutputModelFactory factory, String name, String ctxName) {
|
||||
|
|
|
@ -1,9 +1,38 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model.decl;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
||||
/** public List<XContext> X() { }
|
||||
* public XContext X(int i) { }
|
||||
/** {@code public List<XContext> X() { }
|
||||
* public XContext X(int i) { }}
|
||||
*/
|
||||
public class ContextRuleListGetterDecl extends ContextGetterDecl {
|
||||
public String ctxName;
|
||||
|
|
|
@ -1,3 +1,32 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model.decl;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
|
|
@ -1,8 +1,37 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model.decl;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
||||
/** public Token X() { } */
|
||||
/** {@code public Token X() { }} */
|
||||
public class ContextTokenGetterDecl extends ContextGetterDecl {
|
||||
public ContextTokenGetterDecl(OutputModelFactory factory, String name) {
|
||||
super(factory, name);
|
||||
|
|
|
@ -1,9 +1,38 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model.decl;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
||||
/** public List<Token> X() { }
|
||||
* public Token X(int i) { }
|
||||
/** {@code public List<Token> X() { }
|
||||
* public Token X(int i) { }}
|
||||
*/
|
||||
public class ContextTokenListGetterDecl extends ContextGetterDecl {
|
||||
public ContextTokenListGetterDecl(OutputModelFactory factory, String name) {
|
||||
|
|
|
@ -1,3 +1,32 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.codegen.model.decl;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
|
|
@ -57,11 +57,10 @@ public class Decl extends SrcOp {
|
|||
/** If same name, can't redefine, unless it's a getter */
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if ( obj==null ) return false;
|
||||
if ( this==obj ) return true;
|
||||
if ( !(obj instanceof Decl) ) return false;
|
||||
// A() and label A are different
|
||||
if ( obj instanceof ContextGetterDecl ) return false;
|
||||
if ( this==obj ) return true;
|
||||
if ( this.hashCode() != obj.hashCode() ) return false;
|
||||
return name.equals(((Decl) obj).name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,5 +115,5 @@ public class StructDecl extends Decl {
|
|||
extensionMembers.add(member);
|
||||
}
|
||||
|
||||
public boolean isEmpty() { return attrs.size()==0; }
|
||||
public boolean isEmpty() { return attrs.isEmpty(); }
|
||||
}
|
||||
|
|
|
@ -1,9 +1,38 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.misc;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.HashMap;
|
||||
|
||||
/** Count how many of each key we have; not thread safe */
|
||||
public class FrequencySet<T> extends Hashtable<T, MutableInt> {
|
||||
public class FrequencySet<T> extends HashMap<T, MutableInt> {
|
||||
public int count(T key) {
|
||||
MutableInt value = get(key);
|
||||
if (value == null) return 0;
|
||||
|
|
|
@ -1,3 +1,32 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.misc;
|
||||
|
||||
public class MutableInt extends Number implements Comparable<Number> {
|
||||
|
|
|
@ -106,7 +106,7 @@ alternative returns [ATNFactory.Handle p]
|
|||
|
||||
lexerCommands returns [ATNFactory.Handle p]
|
||||
@init {StringBuilder cmds = new StringBuilder();}
|
||||
: (c=lexerCommand {cmds.append($c.cmd+" ");})+
|
||||
: (c=lexerCommand {cmds.append($c.cmd).append(' ');})+
|
||||
{
|
||||
$p = factory.action(cmds.toString());
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ TEXT
|
|||
@after {delegate.text(buf.toString());}
|
||||
: ( c=~('\\'| '$') {buf.append((char)$c);}
|
||||
| '\\$' {buf.append("$");}
|
||||
| '\\' c=~('$') {buf.append("\\"+(char)$c);}
|
||||
| '\\' c=~('$') {buf.append('\\').append((char)$c);}
|
||||
)+
|
||||
;
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ import org.antlr.v4.tool.ast.TerminalAST;
|
|||
|
||||
public class GrammarASTAdaptor extends CommonTreeAdaptor {
|
||||
org.antlr.runtime.CharStream input; // where we can find chars ref'd by tokens in tree
|
||||
public GrammarASTAdaptor() { ; }
|
||||
public GrammarASTAdaptor() { }
|
||||
public GrammarASTAdaptor(org.antlr.runtime.CharStream input) { this.input = input; }
|
||||
|
||||
@Override
|
||||
|
@ -50,7 +50,7 @@ public class GrammarASTAdaptor extends CommonTreeAdaptor {
|
|||
@Override
|
||||
/** Make sure even imaginary nodes know the input stream */
|
||||
public Object create(int tokenType, String text) {
|
||||
GrammarAST t = null;
|
||||
GrammarAST t;
|
||||
if ( tokenType==ANTLRParser.RULE ) {
|
||||
// needed by TreeWizard to make RULE tree
|
||||
t = new RuleAST(new CommonToken(tokenType, text));
|
||||
|
|
|
@ -30,12 +30,18 @@
|
|||
package org.antlr.v4.parse;
|
||||
|
||||
import org.antlr.v4.Tool;
|
||||
import org.antlr.v4.codegen.CodeGenerator;
|
||||
import org.antlr.v4.tool.ErrorType;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import org.antlr.v4.codegen.CodeGenerator;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** */
|
||||
public class TokenVocabParser {
|
||||
|
@ -53,69 +59,31 @@ public class TokenVocabParser {
|
|||
int maxTokenType = -1;
|
||||
File fullFile = getImportedVocabFile();
|
||||
try {
|
||||
Pattern tokenDefPattern = Pattern.compile("([^\n]+?)[ \\t]*?=[ \\t]*?([0-9]+)");
|
||||
FileReader fr = new FileReader(fullFile);
|
||||
BufferedReader br = new BufferedReader(fr);
|
||||
StreamTokenizer tokenizer = new StreamTokenizer(br);
|
||||
tokenizer.parseNumbers();
|
||||
tokenizer.wordChars('_', '_');
|
||||
tokenizer.eolIsSignificant(true);
|
||||
tokenizer.slashSlashComments(true);
|
||||
tokenizer.slashStarComments(true);
|
||||
tokenizer.ordinaryChar('=');
|
||||
tokenizer.quoteChar('\'');
|
||||
tokenizer.whitespaceChars(' ',' ');
|
||||
tokenizer.whitespaceChars('\t','\t');
|
||||
String tokenDef = br.readLine();
|
||||
int lineNum = 1;
|
||||
int token = tokenizer.nextToken();
|
||||
while (token != StreamTokenizer.TT_EOF) {
|
||||
String tokenID;
|
||||
if ( token == StreamTokenizer.TT_WORD ) {
|
||||
tokenID = tokenizer.sval;
|
||||
}
|
||||
else if ( token == '\'' ) {
|
||||
tokenID = "'"+tokenizer.sval+"'";
|
||||
while ( tokenDef!=null ) {
|
||||
Matcher matcher = tokenDefPattern.matcher(tokenDef);
|
||||
if ( matcher.find() ) {
|
||||
String tokenID = matcher.group(1);
|
||||
String tokenTypeS = matcher.group(2);
|
||||
int tokenType = Integer.valueOf(tokenTypeS);
|
||||
tool.log("grammar", "import "+tokenID+"="+tokenType);
|
||||
tokens.put(tokenID, tokenType);
|
||||
maxTokenType = Math.max(maxTokenType,tokenType);
|
||||
lineNum++;
|
||||
}
|
||||
else {
|
||||
tool.errMgr.toolError(ErrorType.TOKENS_FILE_SYNTAX_ERROR,
|
||||
vocabName + CodeGenerator.VOCAB_FILE_EXTENSION,
|
||||
lineNum);
|
||||
while ( tokenizer.nextToken() != StreamTokenizer.TT_EOL ) {;}
|
||||
token = tokenizer.nextToken();
|
||||
continue;
|
||||
if ( tokenDef.length()>0 ) { // ignore blank lines
|
||||
tool.errMgr.toolError(ErrorType.TOKENS_FILE_SYNTAX_ERROR,
|
||||
vocabName + CodeGenerator.VOCAB_FILE_EXTENSION,
|
||||
" bad token def: "+tokenDef,
|
||||
lineNum);
|
||||
}
|
||||
}
|
||||
token = tokenizer.nextToken();
|
||||
if ( token != '=' ) {
|
||||
tool.errMgr.toolError(ErrorType.TOKENS_FILE_SYNTAX_ERROR,
|
||||
vocabName+CodeGenerator.VOCAB_FILE_EXTENSION,
|
||||
lineNum);
|
||||
while ( tokenizer.nextToken() != StreamTokenizer.TT_EOL ) {;}
|
||||
token = tokenizer.nextToken();
|
||||
continue;
|
||||
}
|
||||
token = tokenizer.nextToken(); // skip '='
|
||||
if ( token != StreamTokenizer.TT_NUMBER ) {
|
||||
tool.errMgr.toolError(ErrorType.TOKENS_FILE_SYNTAX_ERROR,
|
||||
vocabName+CodeGenerator.VOCAB_FILE_EXTENSION,
|
||||
lineNum);
|
||||
while ( tokenizer.nextToken() != StreamTokenizer.TT_EOL ) {;}
|
||||
token = tokenizer.nextToken();
|
||||
continue;
|
||||
}
|
||||
int tokenType = (int)tokenizer.nval;
|
||||
token = tokenizer.nextToken();
|
||||
tool.log("grammar", "import "+tokenID+"="+tokenType);
|
||||
tokens.put(tokenID, tokenType);
|
||||
maxTokenType = Math.max(maxTokenType,tokenType);
|
||||
lineNum++;
|
||||
if ( token != StreamTokenizer.TT_EOL ) {
|
||||
tool.errMgr.toolError(ErrorType.TOKENS_FILE_SYNTAX_ERROR,
|
||||
vocabName+CodeGenerator.VOCAB_FILE_EXTENSION,
|
||||
lineNum);
|
||||
while ( tokenizer.nextToken() != StreamTokenizer.TT_EOL ) {;}
|
||||
token = tokenizer.nextToken();
|
||||
continue;
|
||||
}
|
||||
token = tokenizer.nextToken(); // skip newline
|
||||
tokenDef = br.readLine();
|
||||
}
|
||||
br.close();
|
||||
}
|
||||
|
@ -159,7 +127,6 @@ public class TokenVocabParser {
|
|||
// to look for it in the output directory which is where .tokens
|
||||
// files are generated (in the base, not relative to the input
|
||||
// location.)
|
||||
//
|
||||
f = new File(tool.outputDirectory, vocabName + CodeGenerator.VOCAB_FILE_EXTENSION);
|
||||
return f;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,10 @@
|
|||
|
||||
package org.antlr.v4.parse;
|
||||
|
||||
import org.antlr.runtime.*;
|
||||
import org.antlr.runtime.NoViableAltException;
|
||||
import org.antlr.runtime.Parser;
|
||||
import org.antlr.runtime.RecognitionException;
|
||||
import org.antlr.runtime.TokenStream;
|
||||
import org.antlr.v4.Tool;
|
||||
import org.antlr.v4.tool.ErrorType;
|
||||
|
||||
|
@ -49,7 +52,7 @@ public class ToolANTLRParser extends ANTLRParser {
|
|||
RecognitionException e)
|
||||
{
|
||||
String msg = getParserErrorMessage(this, e);
|
||||
if ( paraphrases.size()>0 ) {
|
||||
if ( !paraphrases.isEmpty() ) {
|
||||
String paraphrase = (String)paraphrases.peek();
|
||||
msg = msg+" while "+paraphrase;
|
||||
}
|
||||
|
@ -59,7 +62,7 @@ public class ToolANTLRParser extends ANTLRParser {
|
|||
}
|
||||
|
||||
public String getParserErrorMessage(Parser parser, RecognitionException e) {
|
||||
String msg = null;
|
||||
String msg;
|
||||
if ( e instanceof NoViableAltException) {
|
||||
String name = parser.getTokenErrorDisplay(e.token);
|
||||
msg = name+" came as a complete surprise to me";
|
||||
|
|
|
@ -29,13 +29,14 @@
|
|||
|
||||
package org.antlr.v4.parse;
|
||||
|
||||
import org.antlr.runtime.*;
|
||||
import org.antlr.runtime.IntStream;
|
||||
import org.antlr.runtime.RecognitionException;
|
||||
|
||||
/** */
|
||||
public class v4ParserException extends RecognitionException {
|
||||
public String msg;
|
||||
/** Used for remote debugger deserialization */
|
||||
public v4ParserException() {;}
|
||||
public v4ParserException() {}
|
||||
|
||||
public v4ParserException(String msg, IntStream input) {
|
||||
super(input);
|
||||
|
|
|
@ -107,11 +107,11 @@ public class ActionSniffer extends BlankActionSplitterListener {
|
|||
|
||||
public void trackRef(Token x) {
|
||||
List<TerminalAST> xRefs = alt.tokenRefs.get(x.getText());
|
||||
if ( alt!=null && xRefs!=null ) {
|
||||
if ( xRefs!=null ) {
|
||||
alt.tokenRefsInActions.map(x.getText(), node);
|
||||
}
|
||||
List<GrammarAST> rRefs = alt.ruleRefs.get(x.getText());
|
||||
if ( alt!=null && rRefs!=null ) {
|
||||
if ( rRefs!=null ) {
|
||||
alt.ruleRefsInActions.map(x.getText(), node);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,13 @@ import org.antlr.runtime.ANTLRStringStream;
|
|||
import org.antlr.runtime.Token;
|
||||
import org.antlr.v4.parse.ActionSplitter;
|
||||
import org.antlr.v4.parse.ActionSplitterListener;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.tool.Alternative;
|
||||
import org.antlr.v4.tool.ErrorManager;
|
||||
import org.antlr.v4.tool.ErrorType;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
import org.antlr.v4.tool.LabelElementPair;
|
||||
import org.antlr.v4.tool.LabelType;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -168,7 +174,7 @@ public class AttributeChecks implements ActionSplitterListener {
|
|||
errMgr.toolError(ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF,
|
||||
x.getText(), y.getText());
|
||||
}
|
||||
if ( r.resolveToAttribute(y.getText(), null)==null ) {
|
||||
else if ( r.resolveToAttribute(y.getText(), null)==null ) {
|
||||
errMgr.grammarError(ErrorType.UNKNOWN_RULE_ATTRIBUTE,
|
||||
g.fileName, y, y.getText(), x.getText(), expr);
|
||||
|
||||
|
@ -182,7 +188,7 @@ public class AttributeChecks implements ActionSplitterListener {
|
|||
errMgr.toolError(ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF,
|
||||
x.getText(), y.getText());
|
||||
}
|
||||
if ( r.resolveToAttribute(y.getText(), null)==null ) {
|
||||
else if ( r.resolveToAttribute(y.getText(), null)==null ) {
|
||||
errMgr.grammarError(ErrorType.UNKNOWN_RULE_ATTRIBUTE,
|
||||
g.fileName, y, y.getText(), x.getText(), expr);
|
||||
|
||||
|
|
|
@ -30,13 +30,23 @@
|
|||
package org.antlr.v4.semantics;
|
||||
|
||||
import org.antlr.v4.analysis.LeftRecursiveRuleAnalyzer;
|
||||
import org.antlr.v4.misc.*;
|
||||
import org.antlr.v4.parse.*;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.tool.ast.*;
|
||||
import org.antlr.v4.misc.OrderedHashMap;
|
||||
import org.antlr.v4.misc.Utils;
|
||||
import org.antlr.v4.parse.GrammarTreeVisitor;
|
||||
import org.antlr.v4.parse.ScopeParser;
|
||||
import org.antlr.v4.tool.AttributeDict;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
import org.antlr.v4.tool.LeftRecursiveRule;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
import org.antlr.v4.tool.ast.AltAST;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
import org.antlr.v4.tool.ast.RuleAST;
|
||||
import org.stringtemplate.v4.misc.MultiMap;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class RuleCollector extends GrammarTreeVisitor {
|
||||
/** which grammar are we checking */
|
||||
|
@ -62,7 +72,7 @@ public class RuleCollector extends GrammarTreeVisitor {
|
|||
GrammarAST block)
|
||||
{
|
||||
int numAlts = block.getChildCount();
|
||||
Rule r = null;
|
||||
Rule r;
|
||||
if ( LeftRecursiveRuleAnalyzer.hasImmediateRecursiveRuleRefs(rule, ID.getText()) ) {
|
||||
r = new LeftRecursiveRule(g, ID.getText(), rule);
|
||||
}
|
||||
|
@ -115,7 +125,7 @@ public class RuleCollector extends GrammarTreeVisitor {
|
|||
int numAlts = block.getChildCount();
|
||||
Rule r = new Rule(g, ID.getText(), rule, numAlts);
|
||||
r.mode = currentModeName;
|
||||
if ( modifiers.size()>0 ) r.modifiers = modifiers;
|
||||
if ( !modifiers.isEmpty() ) r.modifiers = modifiers;
|
||||
rules.put(r.name, r);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ public class SemanticPipeline {
|
|||
basics.process();
|
||||
|
||||
// don't continue if we get errors in this basic check
|
||||
if ( false ) return;
|
||||
//if ( false ) return;
|
||||
|
||||
// TRANSFORM LEFT-RECURSIVE RULES
|
||||
LeftRecursiveRuleTransformer lrtrans =
|
||||
|
|
|
@ -30,10 +30,21 @@
|
|||
package org.antlr.v4.semantics;
|
||||
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.tool.Alternative;
|
||||
import org.antlr.v4.tool.ErrorManager;
|
||||
import org.antlr.v4.tool.ErrorType;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
import org.antlr.v4.tool.LabelElementPair;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/** Check for symbol problems; no side-effects. Inefficient to walk rules
|
||||
* and such multiple times, but I like isolating all error checking outside
|
||||
|
@ -103,8 +114,8 @@ public class SymbolChecks {
|
|||
public void checkActionRedefinitions(List<GrammarAST> actions) {
|
||||
if ( actions==null ) return;
|
||||
String scope = g.getDefaultActionScope();
|
||||
String name = null;
|
||||
GrammarAST nameNode = null;
|
||||
String name;
|
||||
GrammarAST nameNode;
|
||||
for (GrammarAST ampersandAST : actions) {
|
||||
nameNode = (GrammarAST)ampersandAST.getChild(0);
|
||||
if ( ampersandAST.getChildCount()==2 ) {
|
||||
|
@ -280,7 +291,7 @@ public class SymbolChecks {
|
|||
g.fileName, ref.token, ruleName);
|
||||
}
|
||||
GrammarAST arg = (GrammarAST)ref.getChild(0);
|
||||
if ( arg!=null && r.args==null ) {
|
||||
if ( arg!=null && (r==null || r.args==null) ) {
|
||||
errMgr.grammarError(ErrorType.RULE_HAS_NO_ARGS,
|
||||
g.fileName, ref.token, ruleName);
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ public class Attribute {
|
|||
/** Who contains us? */
|
||||
public AttributeDict dict;
|
||||
|
||||
public Attribute() {;}
|
||||
public Attribute() {}
|
||||
|
||||
public Attribute(String name) { this(name,null); }
|
||||
|
||||
|
|
|
@ -30,14 +30,38 @@
|
|||
package org.antlr.v4.tool;
|
||||
|
||||
import org.antlr.v4.misc.Utils;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.atn.ATNConfig;
|
||||
import org.antlr.v4.runtime.atn.ATNState;
|
||||
import org.antlr.v4.runtime.atn.ActionTransition;
|
||||
import org.antlr.v4.runtime.atn.AtomTransition;
|
||||
import org.antlr.v4.runtime.atn.BlockEndState;
|
||||
import org.antlr.v4.runtime.atn.BlockStartState;
|
||||
import org.antlr.v4.runtime.atn.DecisionState;
|
||||
import org.antlr.v4.runtime.atn.NotSetTransition;
|
||||
import org.antlr.v4.runtime.atn.PlusBlockStartState;
|
||||
import org.antlr.v4.runtime.atn.PlusLoopbackState;
|
||||
import org.antlr.v4.runtime.atn.PredicateTransition;
|
||||
import org.antlr.v4.runtime.atn.RangeTransition;
|
||||
import org.antlr.v4.runtime.atn.RuleStopState;
|
||||
import org.antlr.v4.runtime.atn.RuleTransition;
|
||||
import org.antlr.v4.runtime.atn.SetTransition;
|
||||
import org.antlr.v4.runtime.atn.StarBlockStartState;
|
||||
import org.antlr.v4.runtime.atn.StarLoopEntryState;
|
||||
import org.antlr.v4.runtime.atn.StarLoopbackState;
|
||||
import org.antlr.v4.runtime.atn.Transition;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.dfa.DFAState;
|
||||
import org.stringtemplate.v4.ST;
|
||||
import org.stringtemplate.v4.STGroup;
|
||||
import org.stringtemplate.v4.STGroupDir;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/** The DOT (part of graphviz) generation aspect. */
|
||||
public class DOTGenerator {
|
||||
|
@ -187,7 +211,7 @@ public class DOTGenerator {
|
|||
List<ATNState> work = new LinkedList<ATNState>();
|
||||
|
||||
work.add(startState);
|
||||
while ( work.size()>0 ) {
|
||||
while ( !work.isEmpty() ) {
|
||||
ATNState s = work.get(0);
|
||||
if ( markedStates.contains(s) ) { work.remove(0); continue; }
|
||||
markedStates.add(s);
|
||||
|
|
|
@ -274,7 +274,7 @@ public class ErrorManager {
|
|||
format = new STGroupFile(fileName, "UTF-8");
|
||||
format.load();
|
||||
|
||||
if ( initSTListener.errors.size()>0 ) {
|
||||
if ( !initSTListener.errors.isEmpty() ) {
|
||||
rawError("ANTLR installation corrupted; can't load messages format file:\n"+
|
||||
initSTListener.toString());
|
||||
panic();
|
||||
|
|
|
@ -385,7 +385,7 @@ public class Grammar implements AttributeResolver {
|
|||
List<Grammar> grammarsFromRootToMe = getOutermostGrammar().getGrammarAncestors();
|
||||
String qualifiedName = name;
|
||||
if ( grammarsFromRootToMe!=null ) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (Grammar g : grammarsFromRootToMe) {
|
||||
buf.append(g.name);
|
||||
buf.append('_');
|
||||
|
@ -420,7 +420,7 @@ public class Grammar implements AttributeResolver {
|
|||
}
|
||||
|
||||
public int getTokenType(String token) {
|
||||
Integer I = null;
|
||||
Integer I;
|
||||
if ( token.charAt(0)=='\'') {
|
||||
I = stringLiteralToTypeMap.get(token);
|
||||
}
|
||||
|
@ -437,7 +437,7 @@ public class Grammar implements AttributeResolver {
|
|||
* char vocabulary, compute an ANTLR-valid (possibly escaped) char literal.
|
||||
*/
|
||||
public String getTokenDisplayName(int ttype) {
|
||||
String tokenName = null;
|
||||
String tokenName;
|
||||
// inside any target's char range and is lexer grammar?
|
||||
if ( isLexer() &&
|
||||
ttype >= Lexer.MIN_CHAR_VALUE && ttype <= Lexer.MAX_CHAR_VALUE )
|
||||
|
@ -742,51 +742,56 @@ public class Grammar implements AttributeResolver {
|
|||
}
|
||||
|
||||
public static Map<String,String> getStringLiteralAliasesFromLexerRules(GrammarRootAST ast) {
|
||||
String[] patterns = {
|
||||
"(RULE %name:TOKEN_REF (BLOCK (ALT %lit:STRING_LITERAL)))",
|
||||
"(RULE %name:TOKEN_REF (BLOCK (ALT %lit:STRING_LITERAL ACTION)))",
|
||||
"(RULE %name:TOKEN_REF (BLOCK (ALT %lit:STRING_LITERAL SEMPRED)))",
|
||||
"(RULE %name:TOKEN_REF (BLOCK (LEXER_ALT_ACTION (ALT %lit:STRING_LITERAL) .)))",
|
||||
"(RULE %name:TOKEN_REF (BLOCK (LEXER_ALT_ACTION (ALT %lit:STRING_LITERAL) . .)))",
|
||||
"(RULE %name:TOKEN_REF (BLOCK (LEXER_ALT_ACTION (ALT %lit:STRING_LITERAL) (LEXER_ACTION_CALL . .))))",
|
||||
"(RULE %name:TOKEN_REF (BLOCK (LEXER_ALT_ACTION (ALT %lit:STRING_LITERAL) . (LEXER_ACTION_CALL . .))))",
|
||||
"(RULE %name:TOKEN_REF (BLOCK (LEXER_ALT_ACTION (ALT %lit:STRING_LITERAL) (LEXER_ACTION_CALL . .) .)))",
|
||||
// TODO: allow doc comment in there
|
||||
};
|
||||
GrammarASTAdaptor adaptor = new GrammarASTAdaptor(ast.token.getInputStream());
|
||||
TreeWizard wiz = new TreeWizard(adaptor,ANTLRParser.tokenNames);
|
||||
Map<String,String> lexerRuleToStringLiteral = new HashMap<String,String>();
|
||||
|
||||
List<GrammarAST> ruleNodes = ast.getNodesWithType(ANTLRParser.RULE);
|
||||
if ( ruleNodes==null || ruleNodes.size()==0 ) return null;
|
||||
if ( ruleNodes==null || ruleNodes.isEmpty() ) return null;
|
||||
|
||||
for (GrammarAST r : ruleNodes) {
|
||||
for (GrammarAST r : ruleNodes) {
|
||||
//tool.log("grammar", r.toStringTree());
|
||||
// System.out.println("chk: "+r.toStringTree());
|
||||
Tree name = r.getChild(0);
|
||||
if ( name.getType()==ANTLRParser.TOKEN_REF ) {
|
||||
Map nodes = new HashMap();
|
||||
boolean isLitRule =
|
||||
wiz.parse(r, "(RULE %name:TOKEN_REF (BLOCK (ALT %lit:STRING_LITERAL)))", nodes);
|
||||
if ( isLitRule ) {
|
||||
GrammarAST litNode = (GrammarAST)nodes.get("lit");
|
||||
GrammarAST nameNode = (GrammarAST)nodes.get("name");
|
||||
lexerRuleToStringLiteral.put(litNode.getText(), nameNode.getText());
|
||||
continue;
|
||||
if ( name.getType()==ANTLRParser.TOKEN_REF ) {
|
||||
// check rule against patterns
|
||||
boolean isLitRule;
|
||||
for (String pattern : patterns) {
|
||||
isLitRule =
|
||||
defAlias(r, pattern, wiz, lexerRuleToStringLiteral);
|
||||
if ( isLitRule ) break;
|
||||
}
|
||||
// TODO: allow doc comment in there
|
||||
nodes = new HashMap();
|
||||
// try with action in there
|
||||
isLitRule =
|
||||
wiz.parse(r, "(RULE %name:TOKEN_REF (BLOCK (ALT %lit:STRING_LITERAL ACTION)))", nodes);
|
||||
if ( isLitRule ) {
|
||||
GrammarAST litNode = (GrammarAST)nodes.get("lit");
|
||||
GrammarAST nameNode = (GrammarAST)nodes.get("name");
|
||||
lexerRuleToStringLiteral.put(litNode.getText(), nameNode.getText());
|
||||
continue;
|
||||
}
|
||||
nodes = new HashMap();
|
||||
// try with pred in there
|
||||
isLitRule =
|
||||
wiz.parse(r, "(RULE %name:TOKEN_REF (BLOCK (ALT %lit:STRING_LITERAL SEMPRED)))", nodes);
|
||||
if ( isLitRule ) {
|
||||
GrammarAST litNode = (GrammarAST)nodes.get("lit");
|
||||
GrammarAST nameNode = (GrammarAST)nodes.get("name");
|
||||
lexerRuleToStringLiteral.put(litNode.getText(), nameNode.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
// if ( !isLitRule ) System.out.println("no pattern matched");
|
||||
}
|
||||
}
|
||||
return lexerRuleToStringLiteral;
|
||||
}
|
||||
|
||||
protected static boolean defAlias(GrammarAST r, String pattern,
|
||||
TreeWizard wiz,
|
||||
Map<String, String> lexerRuleToStringLiteral)
|
||||
{
|
||||
HashMap<String, Object> nodes = new HashMap<String, Object>();
|
||||
if ( wiz.parse(r, pattern, nodes) ) {
|
||||
GrammarAST litNode = (GrammarAST)nodes.get("lit");
|
||||
GrammarAST nameNode = (GrammarAST)nodes.get("name");
|
||||
lexerRuleToStringLiteral.put(litNode.getText(), nameNode.getText());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Set<String> getStringLiterals() {
|
||||
final Set<String> strings = new HashSet<String>();
|
||||
GrammarTreeVisitor collector = new GrammarTreeVisitor() {
|
||||
|
|
|
@ -78,7 +78,7 @@ public class LeftRecursiveRule extends Rule {
|
|||
LeftRecursiveRuleAltInfo altInfo = recOpAlts.getElement(i);
|
||||
if ( altInfo.altLabel==null ) alts.add(altInfo.originalAltAST);
|
||||
}
|
||||
if ( alts.size()==0 ) return null;
|
||||
if ( alts.isEmpty() ) return null;
|
||||
return alts;
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ public class LeftRecursiveRule extends Rule {
|
|||
altInfo.altLabel));
|
||||
}
|
||||
}
|
||||
if ( labels.size()==0 ) return null;
|
||||
if ( labels.isEmpty() ) return null;
|
||||
return labels;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ public class Rule implements AttributeResolver {
|
|||
for (int i=1; i<=numberOfAlts; i++) {
|
||||
refs.addAll(alt[i].labelDefs.keySet());
|
||||
}
|
||||
if ( refs.size()==0 ) return null;
|
||||
if ( refs.isEmpty() ) return null;
|
||||
return refs;
|
||||
}
|
||||
|
||||
|
@ -219,7 +219,7 @@ public class Rule implements AttributeResolver {
|
|||
labels.add(new Triple<Integer,AltAST,String>(i,alt[i].ast,altLabel.getText()));
|
||||
}
|
||||
}
|
||||
if ( labels.size()==0 ) return null;
|
||||
if ( labels.isEmpty() ) return null;
|
||||
return labels;
|
||||
}
|
||||
|
||||
|
@ -229,7 +229,7 @@ public class Rule implements AttributeResolver {
|
|||
GrammarAST altLabel = alt[i].ast.altLabel;
|
||||
if ( altLabel==null ) alts.add(alt[i].ast);
|
||||
}
|
||||
if ( alts.size()==0 ) return null;
|
||||
if ( alts.isEmpty() ) return null;
|
||||
return alts;
|
||||
}
|
||||
|
||||
|
@ -332,15 +332,23 @@ public class Rule implements AttributeResolver {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return this==obj || name.equals(((Rule)obj).name);
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof Rule)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return name.equals(((Rule)obj).name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("Rule{name="+name);
|
||||
if ( args!=null ) buf.append(", args=" + args);
|
||||
if ( retvals!=null ) buf.append(", retvals=" + retvals);
|
||||
buf.append("Rule{name=").append(name);
|
||||
if ( args!=null ) buf.append(", args=").append(args);
|
||||
if ( retvals!=null ) buf.append(", retvals=").append(retvals);
|
||||
buf.append("}");
|
||||
return buf.toString();
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ public class GrammarAST extends CommonTree {
|
|||
List<GrammarAST> work = new LinkedList<GrammarAST>();
|
||||
work.add(this);
|
||||
GrammarAST t;
|
||||
while ( work.size()>0 ) {
|
||||
while ( !work.isEmpty() ) {
|
||||
t = work.remove(0);
|
||||
if ( types.contains(t.getType()) ) nodes.add(t);
|
||||
if ( t.children!=null ) work.addAll((Collection)t.children);
|
||||
|
|
|
@ -1,3 +1,32 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.tool.ast;
|
||||
|
||||
/** A simple visitor, based upon the classic double dispatch method,
|
||||
|
|
|
@ -1,3 +1,32 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.tool.ast;
|
||||
|
||||
import org.antlr.runtime.Token;
|
||||
|
|
|
@ -1,3 +1,32 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2012 Terence Parr
|
||||
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.tool.ast;
|
||||
|
||||
import org.antlr.runtime.Token;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue