Robot Framework
tokens.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 from robot.variables import VariableIterator
17 
18 
19 
39 class Token:
40 
41  SETTING_HEADER = 'SETTING HEADER'
42  VARIABLE_HEADER = 'VARIABLE HEADER'
43  TESTCASE_HEADER = 'TESTCASE HEADER'
44  TASK_HEADER = 'TASK HEADER'
45  KEYWORD_HEADER = 'KEYWORD HEADER'
46  COMMENT_HEADER = 'COMMENT HEADER'
47 
48  TESTCASE_NAME = 'TESTCASE NAME'
49  KEYWORD_NAME = 'KEYWORD NAME'
50 
51  DOCUMENTATION = 'DOCUMENTATION'
52  SUITE_SETUP = 'SUITE SETUP'
53  SUITE_TEARDOWN = 'SUITE TEARDOWN'
54  METADATA = 'METADATA'
55  TEST_SETUP = 'TEST SETUP'
56  TEST_TEARDOWN = 'TEST TEARDOWN'
57  TEST_TEMPLATE = 'TEST TEMPLATE'
58  TEST_TIMEOUT = 'TEST TIMEOUT'
59  FORCE_TAGS = 'FORCE TAGS'
60  DEFAULT_TAGS = 'DEFAULT TAGS'
61  KEYWORD_TAGS = 'KEYWORD TAGS'
62  LIBRARY = 'LIBRARY'
63  RESOURCE = 'RESOURCE'
64  VARIABLES = 'VARIABLES'
65  SETUP = 'SETUP'
66  TEARDOWN = 'TEARDOWN'
67  TEMPLATE = 'TEMPLATE'
68  TIMEOUT = 'TIMEOUT'
69  TAGS = 'TAGS'
70  ARGUMENTS = 'ARGUMENTS'
71  # Use ´RETURN_SETTING` type instead of `RETURN`. `[Return]` is deprecated and
72  # `RETURN` type will be used with `RETURN` statement in the future.
73  RETURN = 'RETURN'
74  RETURN_SETTING = RETURN
75 
76  NAME = 'NAME'
77  VARIABLE = 'VARIABLE'
78  ARGUMENT = 'ARGUMENT'
79  ASSIGN = 'ASSIGN'
80  KEYWORD = 'KEYWORD'
81  WITH_NAME = 'WITH NAME'
82  FOR = 'FOR'
83  FOR_SEPARATOR = 'FOR SEPARATOR'
84  END = 'END'
85  IF = 'IF'
86  INLINE_IF = 'INLINE IF'
87  ELSE_IF = 'ELSE IF'
88  ELSE = 'ELSE'
89  TRY = 'TRY'
90  EXCEPT = 'EXCEPT'
91  FINALLY = 'FINALLY'
92  AS = 'AS'
93  WHILE = 'WHILE'
94  RETURN_STATEMENT = 'RETURN STATEMENT'
95  CONTINUE = 'CONTINUE'
96  BREAK = 'BREAK'
97  OPTION = 'OPTION'
98 
99  SEPARATOR = 'SEPARATOR'
100  COMMENT = 'COMMENT'
101  CONTINUATION = 'CONTINUATION'
102  CONFIG = 'CONFIG'
103  EOL = 'EOL'
104  EOS = 'EOS'
105 
106  ERROR = 'ERROR'
107  FATAL_ERROR = 'FATAL ERROR'
108 
109  NON_DATA_TOKENS = frozenset((
110  SEPARATOR,
111  COMMENT,
112  CONTINUATION,
113  EOL,
114  EOS
115  ))
116  SETTING_TOKENS = frozenset((
117  DOCUMENTATION,
118  SUITE_SETUP,
119  SUITE_TEARDOWN,
120  METADATA,
121  TEST_SETUP,
122  TEST_TEARDOWN,
123  TEST_TEMPLATE,
124  TEST_TIMEOUT,
125  FORCE_TAGS,
126  DEFAULT_TAGS,
127  KEYWORD_TAGS,
128  LIBRARY,
129  RESOURCE,
130  VARIABLES,
131  SETUP,
132  TEARDOWN,
133  TEMPLATE,
134  TIMEOUT,
135  TAGS,
136  ARGUMENTS,
137  RETURN
138  ))
139  HEADER_TOKENS = frozenset((
140  SETTING_HEADER,
141  VARIABLE_HEADER,
142  TESTCASE_HEADER,
143  TASK_HEADER,
144  KEYWORD_HEADER,
145  COMMENT_HEADER
146  ))
147  ALLOW_VARIABLES = frozenset((
148  NAME,
149  ARGUMENT,
150  TESTCASE_NAME,
151  KEYWORD_NAME
152  ))
153 
154  __slots__ = ['type', 'value', 'lineno', 'col_offset', 'error',
155  '_add_eos_before', '_add_eos_after']
156 
157  def __init__(self, type=None, value=None, lineno=-1, col_offset=-1, error=None):
158  self.typetype = type
159  if value is None:
160  value = {
161  Token.IF: 'IF', Token.INLINE_IF: 'IF', Token.ELSE_IF: 'ELSE IF',
162  Token.ELSE: 'ELSE', Token.FOR: 'FOR', Token.WHILE: 'WHILE',
163  Token.TRY: 'TRY', Token.EXCEPT: 'EXCEPT', Token.FINALLY: 'FINALLY',
164  Token.END: 'END', Token.CONTINUE: 'CONTINUE', Token.BREAK: 'BREAK',
165  Token.RETURN_STATEMENT: 'RETURN', Token.CONTINUATION: '...',
166  Token.EOL: '\n', Token.WITH_NAME: 'WITH NAME', Token.AS: 'AS'
167  }.get(type, '')
168  self.valuevalue = value
169  self.linenolineno = lineno
170  self.col_offsetcol_offset = col_offset
171  self.errorerror = error
172  # Used internally be lexer to indicate that EOS is needed before/after.
173  self._add_eos_before_add_eos_before = False
174  self._add_eos_after_add_eos_after = False
175 
176  @property
177  end_col_offset = property
178 
179  def end_col_offset(self):
180  if self.col_offsetcol_offset == -1:
181  return -1
182  return self.col_offsetcol_offset + len(self.valuevalue)
183 
184  def set_error(self, error, fatal=False):
185  self.typetype = Token.ERROR if not fatal else Token.FATAL_ERROR
186  self.errorerror = error
187 
188 
197  if self.typetype not in Token.ALLOW_VARIABLES:
198  return self._tokenize_no_variables_tokenize_no_variables()
199  variables = VariableIterator(self.valuevalue)
200  if not variables:
201  return self._tokenize_no_variables_tokenize_no_variables()
202  return self._tokenize_variables_tokenize_variables(variables)
203 
205  yield self
206 
207  def _tokenize_variables(self, variables):
208  lineno = self.linenolineno
209  col_offset = self.col_offsetcol_offset
210  remaining = ''
211  for before, variable, remaining in variables:
212  if before:
213  yield Token(self.typetype, before, lineno, col_offset)
214  col_offset += len(before)
215  yield Token(Token.VARIABLE, variable, lineno, col_offset)
216  col_offset += len(variable)
217  if remaining:
218  yield Token(self.typetype, remaining, lineno, col_offset)
219 
220  def __str__(self):
221  return self.valuevalue
222 
223  def __repr__(self):
224  type_ = self.typetype.replace(' ', '_') if self.typetype else 'None'
225  error = '' if not self.errorerror else ', %r' % self.errorerror
226  return 'Token(%s, %r, %s, %s%s)' % (type_, self.valuevalue, self.linenolineno,
227  self.col_offsetcol_offset, error)
228 
229  def __eq__(self, other):
230  return (isinstance(other, Token)
231  and self.typetype == other.type
232  and self.valuevalue == other.value
233  and self.linenolineno == other.lineno
234  and self.col_offsetcol_offset == other.col_offset
235  and self.errorerror == other.error)
236 
237 
238 
239 class EOS(Token):
240  __slots__ = []
241 
242  def __init__(self, lineno=-1, col_offset=-1):
243  Token.__init__(self, Token.EOS, '', lineno, col_offset)
244 
245  @classmethod
246  def from_token(cls, token, before=False):
247  col_offset = token.col_offset if before else token.end_col_offset
248  return EOS(token.lineno, col_offset)
249 
250 
251 
256 class END(Token):
257  __slots__ = []
258 
259  def __init__(self, lineno=-1, col_offset=-1, virtual=False):
260  value = 'END' if not virtual else ''
261  Token.__init__(self, Token.END, value, lineno, col_offset)
262 
263  @classmethod
264  def from_token(cls, token, virtual=False):
265  return END(token.lineno, token.end_col_offset, virtual)
Token representing END token used to signify block ending.
Definition: tokens.py:256
def from_token(cls, token, virtual=False)
Definition: tokens.py:264
def __init__(self, lineno=-1, col_offset=-1, virtual=False)
Definition: tokens.py:259
Token representing end of a statement.
Definition: tokens.py:239
def from_token(cls, token, before=False)
Definition: tokens.py:246
def __init__(self, lineno=-1, col_offset=-1)
Definition: tokens.py:242
Token representing piece of Robot Framework data.
Definition: tokens.py:39
def __eq__(self, other)
Definition: tokens.py:229
def tokenize_variables(self)
Tokenizes possible variables in token value.
Definition: tokens.py:196
def set_error(self, error, fatal=False)
Definition: tokens.py:184
def __init__(self, type=None, value=None, lineno=-1, col_offset=-1, error=None)
Definition: tokens.py:157
def _tokenize_variables(self, variables)
Definition: tokens.py:207