Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ returnStat : 'return' expr {System.out.println("first token "+$start.getText());
|start|Token|The first token to be potentially matched by the rule that is on the main token channel; in other words, this attribute is never a hidden token. For rules that end up matching no tokens, this attribute points at the first token that could have been matched by this rule. When referring to the current rule, this attribute is available to any action within the rule.|
|stop|Token|The last nonhidden channel token to be matched by the rule. When referring to the current rule, this attribute is available only to the after and finally actions.|
|ctx|ParserRuleContext|The rule context object associated with a rule invocation. All of the other attributes are available through this attribute. For example, `$ctx.start` accesses the start field within the current rules context object. It’s the same as `$start`.|
|parser|Parser|The parser itself. This attribute can be used, for example, to invoke a method defined in the parser's `@members` section from a semantic predicate.|

## Dynamically-Scoped Attributes

Expand Down
33 changes: 29 additions & 4 deletions doc/python-target.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,39 @@ If your grammar is targeted to Python only, you may ignore the following. But if
ID {$text.equals("test")}?
```

Unfortunately, this is not portable, but you can work around it. The trick involves:
Unfortunately, this is not portable, as Java and Python (and other target languages) have different syntaxes for all but the simplest language elements. But you can work around it. The trick involves:

* deriving your parser from a parser you provide, such as BaseParser
* implementing utility methods in this BaseParser, such as "isEqualText"
* adding a "self" field to the Java/C# BaseParser, and initialize it with "this"
* implementing utility methods, such as "isEqualText", in this BaseParser, in different files for each target language
* invoking your utility methods in the semantic predicate from the `$parser` object

Thanks to the above, you should be able to rewrite the above semantic predicate as follows:

File `MyGrammarParser.g4`:
```
ID {$self.isEqualText($text,"test")}?
options { superClass = MyGrammarBaseParser; }
...
ID {$parser.isEqualText($text,"test")}?
```

File `MyGrammarBaseParser.py`:
```python
from antlr4 import *

class MyGrammarBaseParser(Parser):

def isEqualText(a, b):
return a is b
```

File `MyGrammarBaseParser.java`:
```java
import org.antlr.v4.runtime.*;

public abstract class MyGrammarBaseParser extends Parser {

public static boolean isEqualText(a, b) {
return a.equals(b);
}
}
```