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
.
34 35 36 37 38 39 40 41 42 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 34 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.
31 32 33 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 31 def doc @doc end |
#keyword ⇒ Object (readonly)
Returns the value of attribute keyword.
31 32 33 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 31 def keyword @keyword end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
31 32 33 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 31 def name @name end |
#optional ⇒ Object (readonly)
Returns the value of attribute optional.
31 32 33 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 31 def optional @optional end |
#patterns ⇒ Object (readonly)
Returns the value of attribute patterns.
31 32 33 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 31 def patterns @patterns end |
#repeatable ⇒ Object (readonly)
Returns the value of attribute repeatable.
31 32 33 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 31 def repeatable @repeatable end |
Instance Method Details
#addPattern(pattern) ⇒ Object
Add a new pattern
to the Rule. It should be of type TextParser::Pattern.
53 54 55 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 53 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.
101 102 103 104 105 106 107 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 101 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
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 183 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
44 45 46 47 48 49 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 44 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
87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 87 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
57 58 59 60 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 57 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.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 70 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.
157 158 159 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 157 def pattern(idx) @patterns[idx] end |
#setArg(idx, doc) ⇒ Object
Add a description for a pattern element of the last added pattern.
125 126 127 128 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 125 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).
119 120 121 122 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 119 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.
152 153 154 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 152 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.
132 133 134 135 136 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 132 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.
63 64 65 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 63 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.
111 112 113 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 111 def setRepeatable @repeatable = true end |
#setSeeAlso(also) ⇒ Object
Add a reference to another rule for documentation purposes.
145 146 147 148 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 145 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.
139 140 141 142 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 139 def setSupportLevel(level) raise 'No pattern defined yet' if @patterns.empty? @patterns[-1].setSupportLevel(level) end |
#to_syntax(stack, docs, rules, skip) ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/taskjuggler/TextParser/Rule.rb', line 161 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 |