Class: BibTeX::Lexer
- Inherits:
-
Object
- Object
- BibTeX::Lexer
- Extended by:
- Forwardable
- Defined in:
- lib/bibtex/lexer.rb
Overview
The BibTeX::Lexer handles the lexical analysis of BibTeX bibliographies.
Constant Summary collapse
- MODE =
Hash.new(:meta).merge({ :bibtex => :bibtex, :entry => :bibtex, :string => :bibtex, :preamble => :bibtex, :comment => :bibtex, :meta => :meta, :literal => :literal, :content => :content }).freeze
Class Attribute Summary collapse
-
.defaults ⇒ Object
Returns the value of attribute defaults.
Instance Attribute Summary collapse
-
#mode ⇒ Object
Returns the value of attribute mode.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#scanner ⇒ Object
readonly
Returns the value of attribute scanner.
-
#stack ⇒ Object
readonly
Returns the value of attribute stack.
Instance Method Summary collapse
-
#active?(object) ⇒ Boolean
Returns true if the lexer is currently parsing the given object type.
-
#analyse(string = nil) ⇒ Object
Start the lexical analysis.
-
#bibtex_mode? ⇒ Boolean
Returns true if the lexer is currenty parsing a BibTeX object.
-
#data=(data) ⇒ Object
Sets the source for the lexical analysis and resets the internal state.
-
#initialize(options = {}) ⇒ Lexer
constructor
Creates a new instance.
-
#next_token ⇒ Object
Returns the next token from the parse stack.
-
#push(value) ⇒ Object
Pushes a value onto the parse stack.
- #reset ⇒ Object
-
#strict? ⇒ Boolean
Returns true if the lexer is currently in strict mode.
- #strip_line_breaks? ⇒ Boolean
- #symbols ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ Lexer
Creates a new instance. Possible options and their respective default values are:
-
:include => [:errors] A list that may contain :meta_content, and :errors; depending on whether or not these are present, the respective tokens are included in the parse tree.
-
:strict => true In strict mode objects can start anywhere; therefore the ‘@’ symbol is not possible except inside literals or @comment objects; for a more lenient lexer set to false and objects are expected to start after a new line (leading white space is permitted).
-
:strip => true When enabled, newlines will be stripped from quoted string values.
65 66 67 68 |
# File 'lib/bibtex/lexer.rb', line 65 def initialize( = {}) @options = Lexer.defaults.merge() reset end |
Class Attribute Details
.defaults ⇒ Object
Returns the value of attribute defaults.
48 49 50 |
# File 'lib/bibtex/lexer.rb', line 48 def defaults @defaults end |
Instance Attribute Details
#mode ⇒ Object
Returns the value of attribute mode.
29 30 31 |
# File 'lib/bibtex/lexer.rb', line 29 def mode @mode end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
29 30 31 |
# File 'lib/bibtex/lexer.rb', line 29 def @options end |
#scanner ⇒ Object (readonly)
Returns the value of attribute scanner.
29 30 31 |
# File 'lib/bibtex/lexer.rb', line 29 def scanner @scanner end |
#stack ⇒ Object (readonly)
Returns the value of attribute stack.
29 30 31 |
# File 'lib/bibtex/lexer.rb', line 29 def stack @stack end |
Instance Method Details
#active?(object) ⇒ Boolean
Returns true if the lexer is currently parsing the given object type.
102 103 104 |
# File 'lib/bibtex/lexer.rb', line 102 def active?(object) @active_object == object end |
#analyse(string = nil) ⇒ Object
Start the lexical analysis.
137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/bibtex/lexer.rb', line 137 def analyse(string = nil) raise(ArgumentError, 'Lexer: failed to start analysis: no source given!') unless string || @scanner self.data = string || @scanner.string until @scanner.eos? send("parse_#{MODE[@mode]}") end push([false, '$end']) end |
#bibtex_mode? ⇒ Boolean
Returns true if the lexer is currenty parsing a BibTeX object.
93 94 95 |
# File 'lib/bibtex/lexer.rb', line 93 def bibtex_mode? MODE[@mode] == :bibtex end |
#data=(data) ⇒ Object
Sets the source for the lexical analysis and resets the internal state.
82 83 84 85 |
# File 'lib/bibtex/lexer.rb', line 82 def data=(data) @scanner = StringScanner.new(data) reset end |
#next_token ⇒ Object
Returns the next token from the parse stack.
90 |
# File 'lib/bibtex/lexer.rb', line 90 def next_token; @stack.shift; end |
#push(value) ⇒ Object
Pushes a value onto the parse stack. Returns the Lexer.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/bibtex/lexer.rb', line 114 def push(value) case value[0] when :CONTENT, :STRING_LITERAL value[1].gsub!(/\n\s*/, ' ') if strip_line_breaks? if !@stack.empty? && value[0] == @stack[-1][0] @stack[-1][1] << value[1] else @stack.push(value) end when :ERROR @stack.push(value) if @include_errors leave_object when :META_CONTENT @stack.push(value) if @include_meta_content else @stack.push(value) end self end |
#reset ⇒ Object
70 71 72 73 74 75 76 77 78 79 |
# File 'lib/bibtex/lexer.rb', line 70 def reset @stack, @brace_level, @mode, @active_object = [], 0, :meta, nil @scanner.reset if @scanner # cache options for speed @include_meta_content = @options[:include].include?(:meta_content) @include_errors = @options[:include].include?(:errors) self end |
#strict? ⇒ Boolean
Returns true if the lexer is currently in strict mode.
107 |
# File 'lib/bibtex/lexer.rb', line 107 def strict?; !!(@options[:strict]); end |
#strip_line_breaks? ⇒ Boolean
109 110 111 |
# File 'lib/bibtex/lexer.rb', line 109 def strip_line_breaks? !![:strip] && !active?(:comment) end |
#symbols ⇒ Object
87 |
# File 'lib/bibtex/lexer.rb', line 87 def symbols; @stack.map(&:first); end |