[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9056]
This commit is contained in:
parrt 2011-09-07 20:47:39 -08:00
parent c16782c848
commit 0e7911f99c
4 changed files with 290 additions and 0 deletions

View File

@ -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
;

View File

@ -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);}
;

View File

@ -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'
;

View File

@ -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
;