Skip to content

Commit

Permalink
Rewrite lexing rules
Browse files Browse the repository at this point in the history
  • Loading branch information
pyrmont committed Sep 6, 2019
1 parent ed34426 commit 9d692c7
Show file tree
Hide file tree
Showing 2 changed files with 345 additions and 87 deletions.
234 changes: 233 additions & 1 deletion lib/rouge/lexers/robot_framework.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,245 @@ module Rouge
module Lexers
class RobotFramework < RegexLexer
tag 'robot_framework'
aliases 'robot' 'robot-framework'
aliases 'robot', 'robot-framework'

title "Robot Framework"
desc 'Robot Framework is a generic open source automation testing framework (robotframework.org)'

filenames '*.robot'
mimetypes 'text/x-robot'

def initialize(opts = {})
super(opts)
@col = 0
@next = nil
@is_template = false
end

def self.settings_with_keywords
@settings_with_keywords ||= Set.new [
"library", "resource", "setup", "teardown", "template", "suite setup",
"suite teardown", "task setup", "task teardown", "task template",
"test setup", "test teardown", "test template", "variables"
]
end

def self.settings_with_args
@settings_with_args ||= Set.new [
"arguments", "default tags", "documentation", "force tags",
"metadata", "return", "tags", "timeout", "task timeout",
"test timeout"
]
end

id = %r/(?:\\|[^|$@&% \t\n])+(?: (?:\\.|[^|$@&% \t\n])+)*/
bdd = %r/(?:Given|When|Then|And|But) /i
sep = %r/ +\| +|[ ]{2,}|\t+/

start do
push :prior_text
end

state :prior_text do
rule %r/^[^*].*/, Text
rule(//) { pop! }
end

# Mixins

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

state :section_include do
mixin :end_section
mixin :sep
mixin :newline
end

state :end_section do
rule(/(?=^(?:\| )?\*)/) { pop! }
end

state :return do
rule(//) { pop! }
end

state :sep do
rule %r/\| /, Text::Whitespace

rule sep do
token Text::Whitespace
@col = @col + 1
if @next
push @next
elsif @is_template
push :args
elsif @col == 1
@next = :keyword
push :keyword
else
push :args
end
push :cell_start
end

rule %r/\.\.\. */ do
token Text::Whitespace
@col = @col + 1
push :args
end

rule %r/ ?\|/, Text::Whitespace
end

state :newline do
rule %r/\n/ do
token Text::Whitespace
@col = 0
@next = nil
push :cell_start
end
end

# States

state :root do
mixin :whitespace

rule %r/^(?:\| )?\*[* ]*([A-Z]+(?: [A-Z]+)?).*/i do |m|
token Generic::Heading, m[0]
case m[1].chomp("s").downcase
when "setting" then push :section_settings
when "test case" then push :section_tests
when "task" then push :section_tasks
when "keyword" then push :section_keywords
when "variable" then push :section_variables
end
end
end

state :section_settings do
mixin :section_include

rule %r/([A-Z]+(?: [A-Z]+)?)(:?)/i do |m|
match = m[1].downcase
@next = if self.class.settings_with_keywords.include? match
:keyword
elsif self.class.settings_with_args.include? match
:args
end
groups Name::Builtin::Pseudo, Punctuation
end
end

state :section_tests do
mixin :section_include

rule %r/[$@&%{}]+/, Name::Label
rule %r/( )(?![ |])/, Name::Label

rule id do
@is_template = false
token Name::Label
end
end

state :section_tasks do
mixin :section_tests
end

state :section_keywords do
mixin :section_include

rule %r/[$@&%]\{/ do
token Name::Variable
push :var
end

rule %r/[$@&%{}]+/, Name::Label
rule %r/( )(?![ |])/, Name::Label

rule id, Name::Label
end

state :section_variables do
mixin :section_include

rule %r/[$@&%]\{/ do
token Name::Variable
@next = :args
push :var
end
end

state :cell_start do
rule %r/#.*/, Comment
mixin :return
end

state :keyword do
rule %r/(\[)([A-Z]+(?: [A-Z]+)?)(\])/i do |m|
groups Punctuation, Name::Builtin::Pseudo, Punctuation

match = m[2].downcase
@is_template = true if match == "template"
if self.class.settings_with_keywords.include? match
@next = :keyword
elsif self.class.settings_with_args.include? match
@next = :args
end

pop!
end

rule %r/[$@&%]\{/ do
token Name::Variable
@next = :keyword unless @next.nil?
push :var
end

rule %r/FOR/i do
token Name::Function
@next = :keyword unless @next.nil?
end

rule %r/( )(?![ |])/, Name::Function

rule bdd, Name::Builtin
rule id do
token Name::Function
@next = nil
end

mixin :return
end

state :args do
rule %r/[$@&%]\{/ do
token Name::Variable
@next = :keyword unless @next.nil?
push :var
end

rule %r/[$@&%]+/, Str
rule %r/( )(?![ |])/, Str
rule id, Str

mixin :return
end

state :var do
rule %r/(\})( )(=)/ do
groups Name::Variable, Text::Whitespace, Punctuation
pop!
end
rule %r/[$@&%]\{/, Name::Variable, :var
rule %r/[{\[]/, Name::Variable, :var
rule %r/[}\]]/, Name::Variable, :pop!
rule %r/[^$@&%{}\[\]]+/, Name::Variable
rule %r/\}\[/, Name::Variable
end
end
end
end
Loading

0 comments on commit 9d692c7

Please sign in to comment.