Class: TaskJuggler::TextParser::Rule
- Defined in:
- lib/taskjuggler/TextParser/Rule.rb
Overview
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.
Instance Attribute Summary collapse
-
#doc ⇒ Object
readonly
Returns the value of attribute doc.
-
#keyword ⇒ Object
readonly
Returns the value of attribute keyword.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#optional ⇒ Object
readonly
Returns the value of attribute optional.
-
#patterns ⇒ Object
readonly
Returns the value of attribute patterns.
-
#repeatable ⇒ Object
readonly
Returns the value of attribute repeatable.
Instance Method Summary collapse
-
#addPattern(pattern) ⇒ Object
Add a new
pattern
to the Rule. -
#addTransitionsToState(states, rules, stateStack, sourceState, loopBack) ⇒ Object
Return a Hash of all state transitions caused by the 1st token of each pattern of this rule.
- #dump ⇒ Object
- #flushCache ⇒ Object
- #generateStates(rules) ⇒ Object
- #include?(token) ⇒ Boolean
-
#initialize(name) ⇒ Rule
constructor
Create a new syntax rule called
name
. -
#optional?(rules) ⇒ Boolean
Return true if the rule describes optional elements.
-
#pattern(idx) ⇒ Object
Return a reference the pattern of this Rule.
-
#setArg(idx, doc) ⇒ Object
Add a description for a pattern element of the last added pattern.
-
#setDoc(keyword, doc) ⇒ Object
Add a description for the syntax elements of this Rule.
-
#setExample(file, tag) ⇒ Object
Add a reference to a code example.
-
#setLastSyntaxToken(idx) ⇒ Object
Specify the index
idx
of the last token to be used for the syntax documentation. -
#setOptional ⇒ Object
Mark the rule as an optional element of the syntax.
-
#setRepeatable ⇒ Object
Mark the syntax element described by this Rule as a repeatable element that can occur once or more times in sequence.
-
#setSeeAlso(also) ⇒ Object
Add a reference to another rule for documentation purposes.
-
#setSupportLevel(level) ⇒ Object
Specify the support level of the current pattern.
- #to_syntax(stack, docs, rules, skip) ⇒ Object
Constructor Details
#initialize(name) ⇒ Rule
Create a new syntax rule called name
.
33 34 35 36 37 38 39 40 41 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 33 def initialize(name) @name = name @patterns = [] @repeatable = false @optional = false @keyword = nil flushCache end |
Instance Attribute Details
#doc ⇒ Object (readonly)
Returns the value of attribute doc.
30 31 32 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 30 def doc @doc end |
#keyword ⇒ Object (readonly)
Returns the value of attribute keyword.
30 31 32 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 30 def keyword @keyword end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
30 31 32 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 30 def name @name end |
#optional ⇒ Object (readonly)
Returns the value of attribute optional.
30 31 32 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 30 def optional @optional end |
#patterns ⇒ Object (readonly)
Returns the value of attribute patterns.
30 31 32 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 30 def patterns @patterns end |
#repeatable ⇒ Object (readonly)
Returns the value of attribute repeatable.
30 31 32 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 30 def repeatable @repeatable end |
Instance Method Details
#addPattern(pattern) ⇒ Object
Add a new pattern
to the Rule. It should be of type TextParser::Pattern.
52 53 54 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 52 def addPattern(pattern) @patterns << pattern end |
#addTransitionsToState(states, rules, stateStack, sourceState, loopBack) ⇒ Object
Return a Hash of all state transitions caused by the 1st token of each pattern of this rule.
100 101 102 103 104 105 106 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 100 def addTransitionsToState(states, rules, stateStack, sourceState, loopBack) @patterns.each do |pattern| pattern.addTransitionsToState(states, rules, stateStack.dup, sourceState, self, 0, loopBack) end end |
#dump ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 182 def dump puts "Rule: #{name} #{@optional ? "[optional]" : ""} " + "#{@repeatable ? "[repeatable]" : ""}" @patterns.length.times do |i| puts " Pattern: \"#{@patterns[i]}\"" unless @transitions[i] puts "No transitions for this pattern!" next end @transitions[i].each do |key, rule| if key[0] == ?_ token = "\"" + key.slice(1, key.length - 1) + "\"" else token = key.slice(1, key.length - 1) end puts " #{token} -> #{rule.name}" end end puts end |
#flushCache ⇒ Object
43 44 45 46 47 48 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 43 def flushCache # A rule is considered to describe optional tokens in case the @optional # flag is set or all of the patterns reference optional rules again. # This variable caches the transitively determined optional value. @transitiveOptional = nil end |
#generateStates(rules) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 86 def generateStates(rules) # First, add an entry State for this rule. Entry states are never # reached by normal state transitions. They are only used as (re-)start # states. states = [ State.new(self) ] @patterns.each do |pattern| states += pattern.generateStates(self, rules) end states end |
#include?(token) ⇒ Boolean
56 57 58 59 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 56 def include?(token) @patterns.each { |p| return true if p[0][1] == token } false end |
#optional?(rules) ⇒ Boolean
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.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 69 def optional?(rules) # If we have a cached result, use this. return @transitiveOptional if @transitiveOptional # If the rule is marked optional, then it is optional. if @optional return @transitiveOptional = true end # If all patterns describe optional content, then this rule is optional # as well. @transitiveOptional = true @patterns.each do |pat| return @transitiveOptional = false unless pat.optional?(rules) end end |
#pattern(idx) ⇒ Object
Return a reference the pattern of this Rule.
156 157 158 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 156 def pattern(idx) @patterns[idx] end |
#setArg(idx, doc) ⇒ Object
Add a description for a pattern element of the last added pattern.
124 125 126 127 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 124 def setArg(idx, doc) raise 'No pattern defined yet' if @patterns.empty? @patterns[-1].setArg(idx, doc) end |
#setDoc(keyword, doc) ⇒ Object
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).
118 119 120 121 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 118 def setDoc(keyword, doc) raise 'No pattern defined yet' if @patterns.empty? @patterns[-1].setDoc(keyword, doc) end |
#setExample(file, tag) ⇒ Object
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.
151 152 153 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 151 def setExample(file, tag) @patterns[-1].setExample(file, tag) end |
#setLastSyntaxToken(idx) ⇒ Object
Specify the index idx
of the last token to be used for the syntax documentation. All subsequent tokens will be ignored.
131 132 133 134 135 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 131 def setLastSyntaxToken(idx) raise 'No pattern defined yet' if @patterns.empty? raise 'Token index too large' if idx >= @patterns[-1].tokens.length @patterns[-1].setLastSyntaxToken(idx) end |
#setOptional ⇒ Object
Mark the rule as an optional element of the syntax.
62 63 64 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 62 def setOptional @optional = true end |
#setRepeatable ⇒ Object
Mark the syntax element described by this Rule as a repeatable element that can occur once or more times in sequence.
110 111 112 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 110 def setRepeatable @repeatable = true end |
#setSeeAlso(also) ⇒ Object
Add a reference to another rule for documentation purposes.
144 145 146 147 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 144 def setSeeAlso(also) raise 'No pattern defined yet' if @patterns.empty? @patterns[-1].setSeeAlso(also) end |
#setSupportLevel(level) ⇒ Object
Specify the support level of the current pattern.
138 139 140 141 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 138 def setSupportLevel(level) raise 'No pattern defined yet' if @patterns.empty? @patterns[-1].setSupportLevel(level) end |
#to_syntax(stack, docs, rules, skip) ⇒ Object
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 160 def to_syntax(stack, docs, rules, skip) str = '' str << '[' if @optional || @repeatable str << '(' if @patterns.length > 1 first = true pStr = '' @patterns.each do |pat| if first first = false else pStr << ' | ' end pStr << pat.to_syntax_r(stack, docs, rules, skip) end return '' if pStr == '' str << pStr str << '...' if @repeatable str << ')' if @patterns.length > 1 str << ']' if @optional || @repeatable str end |