Skip to content

Commit

Permalink
Merge pull request #12 from antlr/add-$parser-support
Browse files Browse the repository at this point in the history
Add $parser support
  • Loading branch information
ericvergnaud committed Dec 2, 2014
2 parents 3230356 + 47d790e commit e3a9236
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class <file.grammarName>Visitor(ParseTreeVisitor):
<file.visitorNames:{lname |
# Visit a parse tree produced by <file.parserName>#<lname>.
def visit<lname; format="cap">(self, ctx):
pass
return self.visitChildren(ctx)

}; separator="\n">

Expand All @@ -132,11 +132,6 @@ from .<superClass> import <superClass>
<endif>
<atn>

EOF = <TokenLabelType()>.EOF
<if(parser.tokens)>
<parser.tokens:{k | <k>=<parser.tokens.(k)>}; separator="\n", wrap, anchor>
<endif>

class <parser.name> ( <if(superClass)><superClass><else>Parser<endif> ):

grammarFileName = "<parser.grammarFileName; format="java-escape">"
Expand All @@ -155,6 +150,11 @@ class <parser.name> ( <if(superClass)><superClass><else>Parser<endif> ):

ruleNames = [ <parser.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor> ]

EOF = <TokenLabelType()>.EOF
<if(parser.tokens)>
<parser.tokens:{k | <k>=<parser.tokens.(k)>}; separator="\n", wrap, anchor>
<endif>

<parser:(ctor)()>

<namedActions.members>
Expand Down Expand Up @@ -355,7 +355,6 @@ else:
<error>
>>


LL1OptionalBlockSingleAlt(choice, expr, alts, preamble, error, followExpr) ::= <<
self.state = <choice.stateNumber>
<!_errHandler.sync(this);!>
Expand All @@ -366,6 +365,7 @@ if <expr>:
<!else if ( !(<followExpr>) ) <error>!>
>>


LL1StarBlockSingleAlt(choice, loopExpr, alts, preamble, iteration) ::= <<
self.state = <choice.stateNumber>
self._errHandler.sync(self)
Expand Down Expand Up @@ -478,16 +478,16 @@ offsetShiftVar(shiftAmount, offset) ::= <%
%>

offsetShiftType(shiftAmount, offset) ::= <%
<if(!isZero.(offset))>(<shiftAmount> - <offset>)<else><shiftAmount><endif>
<if(!isZero.(offset))>(<parser.name>.<shiftAmount> - <offset>)<else><parser.name>.<shiftAmount><endif>
%>

// produces more efficient bytecode when bits.ttypes contains at most two items
bitsetInlineComparison(s, bits) ::= <%
<bits.ttypes:{ttype | <s.varName>==<ttype>}; separator=" or ">
<bits.ttypes:{ttype | <s.varName>==<parser.name>.<ttype>}; separator=" or ">
%>

cases(ttypes) ::= <<
if token in [<ttypes:{t | <t>}; separator=", ">]:
if token in [<ttypes:{t | <parser.name>.<t>}; separator=", ">]:
>>

InvokeRule(r, argExprsChunks) ::= <<
Expand All @@ -497,7 +497,7 @@ self.state = <r.stateNumber>

MatchToken(m) ::= <<
self.state = <m.stateNumber>
<if(m.labels)><m.labels:{l | <labelref(l)> = }><endif>self.match(<m.name>)
<if(m.labels)><m.labels:{l | <labelref(l)> = }><endif>self.match(<parser.name>.<m.name>)
>>

MatchSet(m, expr, capture) ::= "<CommonSetStuff(m, expr, capture, false)>"
Expand Down Expand Up @@ -575,11 +575,13 @@ RulePropertyRef_start(r) ::= "(None if <ctx(r)>.<r.label> is None else <ctx(r)>.
RulePropertyRef_stop(r) ::= "(None if <ctx(r)>.<r.label> is None else <ctx(r)>.<r.label>.stop)"
RulePropertyRef_text(r) ::= "(None if <ctx(r)>.<r.label> is None else self._input.getText((<ctx(r)>.<r.label>.start,<ctx(r)>.<r.label>.stop)))"
RulePropertyRef_ctx(r) ::= "<ctx(r)>.<r.label>"
RulePropertyRef_parser(r) ::= "self"

ThisRulePropertyRef_start(r) ::= "localctx.start"
ThisRulePropertyRef_stop(r) ::= "localctx.stop"
ThisRulePropertyRef_text(r) ::= "self._input.getText((localctx.start, self._input.LT(-1)))"
ThisRulePropertyRef_ctx(r) ::= "localctx"
ThisRulePropertyRef_parser(r) ::= "self"

NonLocalAttrRef(s) ::= "getInvokingContext(<s.ruleIndex>).<s.name>"
SetNonLocalAttr(s, rhsChunks) ::= "getInvokingContext(<s.ruleIndex>).<s.name> = <rhsChunks>"
Expand All @@ -594,7 +596,7 @@ RuleContextListDecl(rdecl) ::= "self.<rdecl.name> = list() # of <rdecl.ctxName>s

ContextTokenGetterDecl(t) ::= <<
def <t.name>(self):
return self.getToken(<t.name>, 0)
return self.getToken(<parser.name>.<t.name>, 0)
>>

// should never be called
Expand All @@ -606,9 +608,9 @@ def <t.name>_list(self):
ContextTokenListIndexedGetterDecl(t) ::= <<
def <t.name>(self, i:int=None):
if i is None:
return self.getTokens(<t.name>)
return self.getTokens(<parser.name>.<t.name>)
else:
return self.getToken(<t.name>, i)
return self.getToken(<parser.name>.<t.name>, i)
>>

ContextRuleGetterDecl(r) ::= <<
Expand Down Expand Up @@ -752,6 +754,7 @@ LexerFile(lexerFile, lexer, namedActions) ::= <<
<fileHeader(lexerFile.grammarFileName, lexerFile.ANTLRVersion)>
from antlr4 import *
from io import StringIO

<namedActions.header>

<lexer>
Expand All @@ -761,8 +764,6 @@ Lexer(lexer, atn, actionFuncs, sempredFuncs, superClass) ::= <<

<atn>

<lexer.tokens:{k | <k> = <lexer.tokens.(k)>}; separator="\n", wrap, anchor>

class <lexer.name>(<if(superClass)><superClass><else>Lexer<endif>):

atn = ATNDeserializer().deserialize(serializedATN())
Expand All @@ -771,7 +772,9 @@ class <lexer.name>(<if(superClass)><superClass><else>Lexer<endif>):

<rest(lexer.modes):{m| <m> = <i>}; separator="\n">

modeNames = [ <lexer.modes:{m| "<m>"}; separator=", ", wrap, anchor> ]
<lexer.tokens:{k | <k> = <lexer.tokens.(k)>}; separator="\n", wrap, anchor>

modeNames = [ <lexer.modes:{m| u"<m>"}; separator=", ", wrap, anchor> ]

literalNames = [ u"\<INVALID>",
<lexer.literalNames:{t | <t>}; separator=", ", wrap, anchor> ]
Expand Down
12 changes: 10 additions & 2 deletions tool/test/org/antlr/v4/test/rt/py3/Python3.test.stg
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ RuleInvocationStack() ::= "str_list(self.getRuleInvocationStack())"

LL_EXACT_AMBIG_DETECTION() ::= <<self._interp.predictionMode = PredictionMode.LL_EXACT_AMBIG_DETECTION>>

ParserPropertyMember() ::= <<
@members {
def Property(self):
return True

}
>>

PositionAdjustingLexer() ::= <<

def resetAcceptPosition(self, index, line, column):
Expand All @@ -193,9 +201,9 @@ def nextToken(self):
return super(type(self),self).nextToken()

def emit(self):
if self._type==TOKENS:
if self._type==PositionAdjustingLexer.TOKENS:
self.handleAcceptPositionForKeyword("tokens")
elif self._type==LABEL:
elif self._type==PositionAdjustingLexer.LABEL:
self.handleAcceptPositionForIdentifier()
return super(type(self),self).emit()

Expand Down
4 changes: 2 additions & 2 deletions tool/test/org/antlr/v4/test/rt/py3/TestLexerExec.java
Original file line number Diff line number Diff line change
Expand Up @@ -608,9 +608,9 @@ public void testPositionAdjustingLexer() throws Exception {
sb.append(" return super(type(self),self).nextToken()\n");
sb.append("\n");
sb.append("def emit(self):\n");
sb.append(" if self._type==TOKENS:\n");
sb.append(" if self._type==PositionAdjustingLexer.TOKENS:\n");
sb.append(" self.handleAcceptPositionForKeyword(\"tokens\")\n");
sb.append(" elif self._type==LABEL:\n");
sb.append(" elif self._type==PositionAdjustingLexer.LABEL:\n");
sb.append(" self.handleAcceptPositionForIdentifier()\n");
sb.append(" return super(type(self),self).emit()\n");
sb.append("\n");
Expand Down
20 changes: 19 additions & 1 deletion tool/test/org/antlr/v4/test/rt/py3/TestParserExec.java
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ public void testPredicatedIfIfElse() throws Exception {
String grammar = "grammar T;\n" +
"s : stmt EOF ;\n" +
"stmt : ifStmt | ID;\n" +
"ifStmt : 'if' ID stmt ('else' stmt | { self._input.LA(1)!=ELSE }?);\n" +
"ifStmt : 'if' ID stmt ('else' stmt | { self._input.LA(1)!=TParser.ELSE }?);\n" +
"ELSE : 'else';\n" +
"ID : [a-zA-Z]+;\n" +
"WS : [ \\n\\t]+ -> skip;";
Expand Down Expand Up @@ -453,5 +453,23 @@ public void testReferenceToATN_2() throws Exception {
assertNull(this.stderrDuringParse);
}

/* this file and method are generated, any edit will be overwritten by the next generation */
@Test
public void testParserProperty() throws Exception {
String grammar = "grammar T;\n" +
"@members {\n" +
"def Property(self):\n" +
" return True\n" +
"\n" +
"}\n" +
"a : {$parser.Property()}? ID {print(\"valid\")}\n" +
" ;\n" +
"ID : 'a'..'z'+ ;\n" +
"WS : (' '|'\\n') -> skip ;";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "TListener", "TVisitor", "a", "abc", false);
assertEquals("valid\n", found);
assertNull(this.stderrDuringParse);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ String testPredFromAltTestedInLoopBack(String input) throws Exception {
"@after {print($ctx.toStringTree(recog=self))}\n" +
" : para para EOF ;\n" +
"para: paraContent NL NL ;\n" +
"paraContent : ('s'|'x'|{self._input.LA(2)!=NL}? NL)+ ;\n" +
"paraContent : ('s'|'x'|{self._input.LA(2)!=TParser.NL}? NL)+ ;\n" +
"NL : '\\n' ;\n" +
"s : 's' ;\n" +
"X : 'x' ;";
Expand Down

0 comments on commit e3a9236

Please sign in to comment.