The TextParserRule holds the basic elment of the syntax description. Each rule has a name and a set of patterns. The parser uses these rules to parse the input files. The first token of a pattern must resolve to a terminal token. The resolution can run transitively over a set of rules. The first tokens of each pattern of a rule must resolve to a terminal symbol and all terminals must be unique in the scope that they appear in. The parser uses this first token to select the next pattern it uses for the syntactical analysis. A rule can be marked as repeatable and/or optional. In this case the syntax element described by the rule may occur 0 or multiple times in the parsed file.
Add a new pattern to the Rule. It should be of type TextParser::Pattern.
# File lib/taskjuggler/TextParser/Rule.rb, line 52 52: def addPattern(pattern) 53: @patterns << pattern 54: end
Return a Hash of all state transitions caused by the 1st token of each pattern of this rule.
# File lib/taskjuggler/TextParser/Rule.rb, line 95 95: def addTransitionsToState(states, rules, stateStack, sourceState, 96: loopBack) 97: @patterns.each do |pattern| 98: pattern.addTransitionsToState(states, rules, stateStack.dup, sourceState, 99: self, 0, loopBack) 100: end 101: end
# File lib/taskjuggler/TextParser/Rule.rb, line 171 171: def dump 172: puts "Rule: #{name} #{@optional ? "[optional]" : ""} " + 173: "#{@repeatable ? "[repeatable]" : ""}" 174: @patterns.length.times do |i| 175: puts " Pattern: \"#{@patterns[i]}\"" 176: unless @transitions[i] 177: puts "No transitions for this pattern!" 178: next 179: end 180: 181: @transitions[i].each do |key, rule| 182: if key[0] == __ 183: token = "\"" + key.slice(1, key.length - 1) + "\"" 184: else 185: token = key.slice(1, key.length - 1) 186: end 187: puts " #{token} -> #{rule.name}" 188: end 189: end 190: puts 191: end
# File lib/taskjuggler/TextParser/Rule.rb, line 43 43: def flushCache 44: # A rule is considered to describe optional tokens in case the @optional 45: # flag is set or all of the patterns reference optional rules again. 46: # This variable caches the transitively determined optional value. 47: @transitiveOptional = nil 48: end
# File lib/taskjuggler/TextParser/Rule.rb, line 81 81: def generateStates 82: # First, add an entry State for this rule. Entry states are never 83: # reached by normal state transitions. They are only used as (re-)start 84: # states. 85: states = [ State.new(self) ] 86: 87: @patterns.each do |pattern| 88: states += pattern.generateStates(self) 89: end 90: states 91: end
Return true if the rule describes optional elements. The evaluation recursively descends into the pattern if necessary and stores the result to be reused for later calls.
# File lib/taskjuggler/TextParser/Rule.rb, line 64 64: def optional?(rules) 65: # If we have a cached result, use this. 66: return @transitiveOptional if @transitiveOptional 67: 68: # If the rule is marked optional, then it is optional. 69: if @optional 70: return @transitiveOptional = true 71: end 72: 73: # If all patterns describe optional content, then this rule is optional 74: # as well. 75: @transitiveOptional = true 76: @patterns.each do |pat| 77: return @transitiveOptional = false unless pat.optional?(rules) 78: end 79: end
Return a reference the pattern of this Rule.
# File lib/taskjuggler/TextParser/Rule.rb, line 145 145: def pattern(idx) 146: @patterns[idx] 147: end
Add a description for a pattern element of the last added pattern.
# File lib/taskjuggler/TextParser/Rule.rb, line 119 119: def setArg(idx, doc) 120: raise 'No pattern defined yet' if @patterns.empty? 121: @patterns[1].setArg(idx, doc) 122: end
Add a description for the syntax elements of this Rule. doc is a RichText and keyword is a unique name of this Rule. To avoid ambiguouties, an optional scope can be appended, separated by a dot (E.g. name.scope).
# File lib/taskjuggler/TextParser/Rule.rb, line 113 113: def setDoc(keyword, doc) 114: raise 'No pattern defined yet' if @patterns.empty? 115: @patterns[1].setDoc(keyword, doc) 116: end
Add a reference to a code example. file is the name of the file. tag is a tag within the file that specifies a part of this file.
# File lib/taskjuggler/TextParser/Rule.rb, line 140 140: def setExample(file, tag) 141: @patterns[1].setExample(file, tag) 142: end
Specify the index idx of the last token to be used for the syntax documentation. All subsequent tokens will be ignored.
# File lib/taskjuggler/TextParser/Rule.rb, line 126 126: def setLastSyntaxToken(idx) 127: raise 'No pattern defined yet' if @patterns.empty? 128: raise 'Token index too large' if idx >= @patterns[1].tokens.length 129: @patterns[1].setLastSyntaxToken(idx) 130: end
Mark the rule as an optional element of the syntax.
# File lib/taskjuggler/TextParser/Rule.rb, line 57 57: def setOptional 58: @optional = true 59: end
Mark the syntax element described by this Rule as a repeatable element that can occur once or more times in sequence.
# File lib/taskjuggler/TextParser/Rule.rb, line 105 105: def setRepeatable 106: @repeatable = true 107: end
Add a reference to another rule for documentation purposes.
# File lib/taskjuggler/TextParser/Rule.rb, line 133 133: def setSeeAlso(also) 134: raise 'No pattern defined yet' if @patterns.empty? 135: @patterns[1].setSeeAlso(also) 136: end
# File lib/taskjuggler/TextParser/Rule.rb, line 149 149: def to_syntax(stack, docs, rules, skip) 150: str = '' 151: str << '[' if @optional || @repeatable 152: str << '(' if @patterns.length > 1 153: first = true 154: pStr = '' 155: @patterns.each do |pat| 156: if first 157: first = false 158: else 159: pStr << ' | ' 160: end 161: pStr << pat.to_syntax_r(stack, docs, rules, skip) 162: end 163: return '' if pStr == '' 164: str << pStr 165: str << '...' if @repeatable 166: str << ')' if @patterns.length > 1 167: str << ']' if @optional || @repeatable 168: str 169: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.