Skip to content

Commit

Permalink
Change object tokens, support bare key-values
Browse files Browse the repository at this point in the history
This commit makes several changes to the proposed lexer.

First, it changes the tokens used in JavaScript objects. It was proposed
that keys be tokenised as `Str::Double` and that string values be
tokenised as `Name::Tag`. The token `Name::Label` seems a more
appropriate token for keys while `Str::Double` should be used for
string values.

Second, it remoeves the tokenisation of escape sequences inside object
keys. While this is correct insofar as the keys are merely strings, it
fits awkwardly with the tokenisation of keys with a non-string token.
This commit tokenises all characters within the key as `Name::Label`.

Third, it adds support for 'bare' key-value pairs, that is text of the
form <string>: <value>. These 'bare' key-value pairs are not tokenised
the same way as they would be within objects. Rather, keys are tokenised
as ordinary strings. This preserves backwards compatability with how the
JSON lexer previously worked.
  • Loading branch information
pyrmont committed Jul 10, 2019
1 parent 293a3d9 commit 77dd1b8
Showing 1 changed file with 28 additions and 20 deletions.
48 changes: 28 additions & 20 deletions lib/rouge/lexers/json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,58 +12,66 @@ class JSON < RegexLexer
'application/hal+json', 'application/problem+json',
'application/schema+json'

state :root do
state :whitespace do
rule %r/\s+/, Text::Whitespace
end

state :root do
mixin :whitespace
rule %r/{/, Punctuation, :object
rule %r/\[/, Punctuation, :array

rule(%r//) { push :value }
end

state :object do
rule %r/\s+/, Text::Whitespace
rule %r/"/, Str::Double, :name
mixin :whitespace
rule %r/"/, Name::Label, :name
rule %r/:/, Punctuation, :value
rule %r/,/, Punctuation
rule %r/}/, Punctuation, :pop!
end

state :value do
rule %r/"/, Name::Tag, :stringvalue
mixin :whitespace
rule %r/"/, Str::Double, :string_value
mixin :constants
rule %r/}/ do
token Punctuation
pop! 2 # pop both this state and the :object one below it
end
rule %r/\[/, Punctuation, :array
rule %r/{/, Punctuation, :object
rule %r/}/ do
token Punctuation
pop! 2 # pop both this state and the :object one below it
if stack[-2].name == :object
token Punctuation
pop! 2 # pop both this state and the :object one below it
else
token Error
pop!
end
end
rule %r/,/, Punctuation, :pop!
rule %r/\s+/, Text::Whitespace
rule %r/:/, Punctuation
end

state :name do
rule %r/[^\\"]+/, Str::Double
rule %r/\\./, Str::Escape
rule %r/"/, Str::Double, :pop!
rule %r/[^\\"]+/, Name::Label
rule %r/\\./, Name::Label
rule %r/"/, Name::Label, :pop!
end

state :stringvalue do
rule %r/[^\\"]+/, Name::Tag
state :string_value do
rule %r/[^\\"]+/, Str::Double
rule %r/\\./, Str::Escape
rule %r/"/, Name::Tag, :pop!
rule %r/"/, Str::Double, :pop!
end

state :array do
rule %r/\]/, Punctuation, :pop!
rule %r/"/, Name::Tag, :stringvalue
rule %r/"/, Str::Double, :string_value
rule %r/,/, Punctuation
mixin :constants
mixin :root
end

state :constants do
state :constants do
rule %r/(?:true|false|null)/, Keyword::Constant
rule %r/-?(?:0|[1-9]\d*)\.\d+(?:e[+-]?\d+)?/i, Num::Float
rule %r/-?(?:0|[1-9]\d*)(?:e[+-]?\d+)?/i, Num::Integer
Expand Down

0 comments on commit 77dd1b8

Please sign in to comment.