Module: Antelope::Ace::Scanner::Second
- Included in:
- Antelope::Ace::Scanner
- Defined in:
- lib/antelope/ace/scanner/second.rb
Overview
Scans the second part of the file. The second part of the
file only contains productions (or rules). Rules have a
label and a body; the label may be any lowercase alphabetical
identifier followed by a colon; the body consists of "parts",
an "or", a "prec", and/or a "block". The part may consist
of any alphabetical characters. An or is just a vertical bar
(|). A prec is a precedence declaraction, which is %prec
followed by any alphabetical characters. A block is a {,
followed by code, followed by a terminating }. Rules may
be terminated by a semicolon, but this is optional.
Instance Method Summary collapse
-
#_scan_block ⇒ String
private
Scans the block; it scans until it encounters enough closing brackets to match the opening brackets.
-
#scan_second_part ⇒ void
Scans the second part of the file.
-
#scan_second_rule ⇒ Boolean
Scans a rule.
-
#scan_second_rule_block ⇒ Boolean
Attempts to scan a block.
-
#scan_second_rule_body ⇒ void
The body can contain parts, ors, precs, or blocks (or whitespaces).
-
#scan_second_rule_label ⇒ Boolean
Scans the label for a rule.
-
#scan_second_rule_or ⇒ Boolean
Attempts to scan an "or".
-
#scan_second_rule_part ⇒ Boolean
Attempts to scan a "part".
-
#scan_second_rule_prec ⇒ Boolean
Attempts to scan a precedence definition.
Instance Method Details
#_scan_block ⇒ String (private)
Scans the block; it scans until it encounters enough closing brackets to match the opening brackets. If it encounters an opening brackets, it increments the bracket counter by one; if it encounters a closing bracket, it decrements by one. It will error if it reaches the end before the brackets are fully closed.
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/antelope/ace/scanner/second.rb', line 137 def _scan_block brack = 1 body = "{" until brack.zero? if part = @scanner.scan_until(/(\}|\{)/) body << part if @scanner[1] == "}" brack -= 1 else brack += 1 end else error! end end body end |
#scan_second_part ⇒ void
This method returns an undefined value.
Scans the second part of the file. This should be from just before the first content boundry; if the scanner doesn't find a content boundry, it will error. It will then check for a rule.
28 29 30 31 32 33 34 35 |
# File 'lib/antelope/ace/scanner/second.rb', line 28 def scan_second_part scanner.scan(CONTENT_BOUNDRY) or error! tokens << [:second] until @scanner.check(CONTENT_BOUNDRY) scan_second_rule || scan_whitespace || error! end end |
#scan_second_rule ⇒ Boolean
Scans a rule. A rule consists of a label (the nonterminal the production is for), a body, and a block; and then, an optional semicolon.
45 46 47 48 49 50 51 |
# File 'lib/antelope/ace/scanner/second.rb', line 45 def scan_second_rule if @scanner.check(/([a-z]+):/) scan_second_rule_label or error! scan_second_rule_body true end end |
#scan_second_rule_block ⇒ Boolean
Attempts to scan a block. This correctly balances brackets; however, if a bracket is opened/closed within a string, it still counts that as a bracket that needs to be balanced. So, having extensive code within a block is not a good idea.
119 120 121 122 123 |
# File 'lib/antelope/ace/scanner/second.rb', line 119 def scan_second_rule_block if @scanner.scan(/\{/) tokens << [:block, _scan_block] end end |
#scan_second_rule_body ⇒ void
This method returns an undefined value.
The body can contain parts, ors, precs, or blocks (or whitespaces). Scans all of them, and then attempts to scan a semicolon.
73 74 75 76 77 78 79 80 81 |
# File 'lib/antelope/ace/scanner/second.rb', line 73 def scan_second_rule_body body = true while body scan_second_rule_part || scan_second_rule_or || scan_second_rule_prec || scan_second_rule_block || scan_whitespace || (body = false) end @scanner.scan(/;/) end |
#scan_second_rule_label ⇒ Boolean
Scans the label for a rule. It should contain only lower case letters and a colon.
57 58 59 60 61 |
# File 'lib/antelope/ace/scanner/second.rb', line 57 def scan_second_rule_label if @scanner.scan(/([a-z]+): ?/) tokens << [:label, @scanner[1]] end end |
#scan_second_rule_or ⇒ Boolean
Attempts to scan an "or". It's just a vertical bar.
97 98 99 100 101 |
# File 'lib/antelope/ace/scanner/second.rb', line 97 def scan_second_rule_or if @scanner.scan(/\|/) tokens << [:or] end end |
#scan_second_rule_part ⇒ Boolean
Attempts to scan a "part". A part is any series of alphabetical characters that are not followed by a colon.
88 89 90 91 92 |
# File 'lib/antelope/ace/scanner/second.rb', line 88 def scan_second_rule_part if @scanner.scan(/([A-Za-z]+)(?!\:)/) tokens << [:part, @scanner[1]] end end |
#scan_second_rule_prec ⇒ Boolean
Attempts to scan a precedence definition. A precedence definition is "%prec " followed by a terminal or nonterminal.
107 108 109 110 111 |
# File 'lib/antelope/ace/scanner/second.rb', line 107 def scan_second_rule_prec if @scanner.scan(/%prec ([A-Za-z]+)/) tokens << [:prec, @scanner[1]] end end |