ANTLR4 - цели без вложенных классов
Я пытаюсь расширить ANTLR4 новой целью PHP и возникла проблема с файлом StringTemplate (.stg):
В файле StringTemplate парсер определяется шаблоном Parser_. Parser_ содержит следующее правило:
<funcs; separator="\n">
Это правило генерирует определения классов и функции. Правило находится внутри класса анализатора, но PHP не поддерживает вложенные классы.
Есть ли возможность разделить определения классов и функции в файле StringTemplate? Я хочу установить определения классов шаблона funcs перед классом синтаксического анализатора и функции шаблона funcs внутри класса синтаксического анализатора.
Весь парсер-шаблон:
Parser_(parser, funcs, atn, sempredFuncs, ctor, superClass) ::= <<
// funcs beinhaltet die Klasse und dann die Funktion
class <parser.name> extends <if(superClass)><superClass><else>\antlr4\php7_runtime\Parser<endif> {
public $grammarFileName = "<parser.grammarFileName>";
public $atn = null;
public $decisionsToDFA = array( );
public $sharedContextCache = null;
public $literalNames = [ <parser.literalNames:{t | <t>}; null="'\<INVALID>'", separator=", ", wrap, anchor> ];
public $symbolicNames = [ <parser.symbolicNames:{t | <t>}; null="'\<INVALID>'", separator=", ", wrap, anchor> ];
<parser.rules:{r | const RULE_<r.name> = <r.index>;}; separator="\n", wrap, anchor>
public $ruleNames = [ <parser.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor> ];
public $EOF = <PathRuntime()><TokenLabelType()>::EOF;
<if(parser.tokens)>
<parser.tokens:{k | const <k>=<parser.tokens.(k)>;}; separator="\n", wrap, anchor>
<endif>
<atn>
<parser:(ctor)()>
<namedActions.members>
// funcs -- Start
<funcs; separator="\n">
// funcs -- Ende
} // class <parser.name>
<if(sempredFuncs)>
function sempred( $localctx, int $ruleIndex, int $predIndex){
if ($this->_predicates == null) {
$this->_predicates = py_dict();
}
<parser.sempredFuncs.values:{ f |
$this->predicates[<f.ruleIndex>] = $this-><f.name>_sempred}; separator="\n">
$pred = $this->_predicates->get($ruleIndex, null);
if ( $pred == null) {
throw Exception("No predicate with index:" . (string) $ruleIndex );
} else {
return pred( $localctx, $predIndex)
}
<sempredFuncs.values; separator="\n">
}
<endif>
>>
Спасибо за ваше время!
1 ответ
Решением было пройтись по parser.funcs.ruleCtx и исключить из шаблона RuleFunction:-)
Parser_(parser, funcs, atn, sempredFuncs, ctor, superClass ) ::= <<
<funcs :{ func | <func.ruleCtx> }; separator="\n"> // here the Comtext classes
class <parser.name> extends <if(superClass)><superClass><else>\antlr4\php7_runtime\Parser<endif> {
public $grammarFileName = "<parser.grammarFileName>";
public $atn = null;
public $decisionsToDFA = array( );
public $sharedContextCache = null;
public $literalNames = [ <parser.literalNames:{t | <t>}; null="'\<INVALID>'", separator=", ", wrap, anchor> ];
public $symbolicNames = [ <parser.symbolicNames:{t | <t>}; null="'\<INVALID>'", separator=", ", wrap, anchor> ];
<parser.rules:{r | const RULE_<r.name> = <r.index>;}; separator="\n", wrap, anchor>
public $ruleNames = [ <parser.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor> ];
public $EOF = <PathRuntime()><TokenLabelType()>::EOF;
<if(parser.tokens)>
<parser.tokens:{k | const <k>=<parser.tokens.(k)>;}; separator="\n", wrap, anchor>
<endif>
<atn>
<parser:(ctor)()>
<funcs; separator="\n"> // here RuleFunction is emitted
} // class <parser.name>
<namedActions.members>
<if(sempredFuncs)>
function sempred( $localctx, int $ruleIndex, int $predIndex){
if ($this->_predicates == null) {
$this->_predicates = py_dict();
}
<parser.sempredFuncs.values:{ f |
$this->predicates[<f.ruleIndex>] = $this-><f.name>_sempred}; separator="\n">
$pred = $this->_predicates->get($ruleIndex, null);
if ( $pred == null) {
throw Exception("No predicate with index:" . (string) $ruleIndex );
} else {
return pred( $localctx, $predIndex)
}
<sempredFuncs.values; separator="\n">
}
<endif>
>>