blob: 874b73545180e38fb5fea9acce05a670f612533e [file] [log] [blame]
# Copyright (c) 2008, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# ---
#
# Author: falmeida@google.com (Filipe Almeida)
name = 'jsparser'
comment = 'Simplified finite state machine for tracking of javascript states'
condition('q', '\''),
condition('dq', '\"'),
condition('/', '/'),
condition('*', '*'),
condition('[', '['),
condition(']', ']'),
condition('lf', '\n'),
condition('backslash', '\\'),
condition('default', '[:default:]')
# Main javascript body.
state(name = 'js_text',
external = 'text',
transitions = [
['q', 'js_q'],
['dq', 'js_dq'],
['/', 'js_slash'],
['default', 'js_text']
])
# Single quoted string literal.
state(name = 'js_q',
external = 'q',
transitions = [
['backslash', 'js_q_e'],
['q', 'js_text'],
['default', 'js_q']
])
# Javascript escaped character in a single quoted string literal.
state(name = 'js_q_e',
external = 'q',
transitions = [
['default', 'js_q']
])
# Double quoted string literal
state(name = 'js_dq',
external = 'dq',
transitions = [
['backslash', 'js_dq_e'],
['dq', 'js_text'],
['default', 'js_dq']
])
# Javascript escaped character in a double quoted string literal.
state(name = 'js_dq_e',
external = 'dq',
transitions = [
['default', 'js_dq']
])
# Possible start of a javascript comment.
state(name = 'js_slash',
external = 'text',
transitions = [
['/', 'js_comment_ln'],
['*', 'js_comment_ml'],
['default', 'js_text']
])
# Possible start of a regular expression literal.
#
# The state diagram does not reach this state directly. When js_slash is
# reached, the function enter_state_js_slash() is called, which checks if the
# last token belongs to the set of tokens that can precede a regular
# expression, in which case it changes the state to js_regexp_slash.
#
# For more information please read the comments in
# jsparser.c:enter_state_js_slash().
state(name = 'js_regexp_slash',
external = 'text',
transitions = [
['/', 'js_comment_ln'],
['*', 'js_comment_ml'],
['backslash', 'js_regexp_e'],
['[', 'js_regexp_bracket'],
['default', 'js_regexp']
])
# Regular expression literal.
state(name = 'js_regexp',
external = 'regexp',
transitions = [
['backslash', 'js_regexp_e'],
['[', 'js_regexp_bracket'],
['/', 'js_text'],
['default', 'js_regexp']
])
# Regexp bracket expression
state(name = 'js_regexp_bracket',
external = 'regexp',
transitions = [
['backslash', 'js_regexp_bracket_e'],
[']', 'js_regexp'],
['default', 'js_regexp_bracket']
])
# Backslash escaped regexp bracket expression
state(name = 'js_regexp_bracket_e',
external = 'regexp',
transitions = [
['default', 'js_regexp_bracket']
])
# Escaped regular expression char.
state(name = 'js_regexp_e',
external = 'regexp',
transitions = [
['default', 'js_regexp']
])
# Start of a single line javascript comment (//).
state(name = 'js_comment_ln',
external = 'comment',
transitions = [
['lf', 'js_comment_after'],
['default', 'js_comment_ln']
])
# Start of a multiline javascript comment (/*).
state(name = 'js_comment_ml',
external = 'comment',
transitions = [
['*', 'js_comment_ml_close'],
['default', 'js_comment_ml']
])
# Close of a multiline javascript comment (*/).
state(name = 'js_comment_ml_close',
external = 'comment',
transitions = [
['/', 'js_comment_after'],
['default', 'js_comment_ml']
])
# Ending character of a javascript comment.
# In can either be a '/ in the case of a multiline comment, or a line
# terminator in the case of a single line comment.
# This is needed so we don't insert the '/' or the new line character into the
# ring buffer.
state(name = 'js_comment_after',
external = 'text',
transitions = [
['q', 'js_q'],
['dq', 'js_dq'],
['/', 'js_slash'],
['default', 'js_text']
])