add
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9056]
This commit is contained in:
parent
c16782c848
commit
0e7911f99c
|
@ -0,0 +1,46 @@
|
|||
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
|
||||
;
|
|
@ -0,0 +1,36 @@
|
|||
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);}
|
||||
;
|
|
@ -0,0 +1,155 @@
|
|||
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'
|
||||
;
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
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
|
||||
;
|
Loading…
Reference in New Issue