In some programming languages there are special identifiers that are recognized as keywords only in a specific context. In other contexts they behave the same as ordinary identifiers. For example in C# the identifiers get and set are are recognized as keywords only inside a property implementation and they can be used as normal identifiers in other contexts.
SoulNG has limited support for context-sensitive keywords. The way it works in SoulNG is that the lexer does not convert identifiers to keywords in the identifier rule of the lexer as it is normally done but instead the conversion is done as late as in the parser.
In an XPATH query expression the identifiers child, ancestor, namespace, etc. can be used both as ordinary names of XML elements in a name test and axis specifier keywords in a step of a location path expression.
Thus the names are not converted to keywords in the name rule of the XPATH lexer, but the conversion is done in the AxisName rule of the XPATH parser.
A similar mechanism is used for keywords and and or in the AndExpr and OrExpr rules.