antlr3 1.8.0 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +35 -0
- data/Manifest.txt +73 -0
- data/README.txt +6 -13
- data/java/RubyTarget.java +43 -19
- data/java/antlr-full-3.2.1.jar +0 -0
- data/lib/antlr3/debug.rb +2 -0
- data/lib/antlr3/debug/event-hub.rb +55 -55
- data/lib/antlr3/debug/record-event-listener.rb +2 -2
- data/lib/antlr3/debug/rule-tracer.rb +14 -14
- data/lib/antlr3/debug/socket.rb +47 -47
- data/lib/antlr3/debug/trace-event-listener.rb +8 -8
- data/lib/antlr3/main.rb +29 -9
- data/lib/antlr3/modes/ast-builder.rb +7 -7
- data/lib/antlr3/modes/filter.rb +19 -17
- data/lib/antlr3/profile.rb +34 -6
- data/lib/antlr3/recognizers.rb +50 -1
- data/lib/antlr3/streams.rb +19 -15
- data/lib/antlr3/streams/rewrite.rb +241 -229
- data/lib/antlr3/template/group-file-lexer.rb +6 -8
- data/lib/antlr3/template/group-file-parser.rb +16 -16
- data/lib/antlr3/template/group-file.rb +1 -1
- data/lib/antlr3/test/call-stack.rb +13 -13
- data/lib/antlr3/test/core-extensions.rb +69 -69
- data/lib/antlr3/test/functional.rb +0 -4
- data/lib/antlr3/test/grammar.rb +70 -70
- data/lib/antlr3/token.rb +41 -17
- data/lib/antlr3/tree.rb +11 -14
- data/lib/antlr3/tree/debug.rb +53 -53
- data/lib/antlr3/tree/visitor.rb +11 -11
- data/lib/antlr3/tree/wizard.rb +35 -35
- data/lib/antlr3/util.rb +18 -0
- data/lib/antlr3/version.rb +1 -1
- data/rakefile +1 -0
- data/samples/ANTLRv3Grammar.g +3 -3
- data/samples/JavaScript.g +702 -0
- data/samples/standard/C/C.g +543 -0
- data/samples/standard/C/C.tokens +175 -0
- data/samples/standard/C/C__testrig.st +0 -0
- data/samples/standard/C/c.rb +12 -0
- data/samples/standard/C/input +3479 -0
- data/samples/standard/C/output +171 -0
- data/samples/standard/LL-star/LLStar.g +101 -0
- data/samples/standard/LL-star/input +12 -0
- data/samples/standard/LL-star/ll-star.rb +12 -0
- data/samples/standard/LL-star/output +2 -0
- data/samples/standard/calc/Calculator.g +47 -0
- data/samples/standard/calc/Calculator.py +16 -0
- data/samples/standard/calc/Calculator.rb +28 -0
- data/samples/standard/cminus/CMinus.g +141 -0
- data/samples/standard/cminus/bytecode.group +80 -0
- data/samples/standard/cminus/cminus.rb +16 -0
- data/samples/standard/cminus/input +9 -0
- data/samples/standard/cminus/java.group +91 -0
- data/samples/standard/cminus/output +11 -0
- data/samples/standard/cminus/python.group +48 -0
- data/samples/standard/dynamic-scope/DynamicScopes.g +50 -0
- data/samples/standard/dynamic-scope/dynamic-scopes.rb +12 -0
- data/samples/standard/dynamic-scope/input +7 -0
- data/samples/standard/dynamic-scope/output +4 -0
- data/samples/standard/fuzzy/FuzzyJava.g +89 -0
- data/samples/standard/fuzzy/fuzzy.py +11 -0
- data/samples/standard/fuzzy/fuzzy.rb +9 -0
- data/samples/standard/fuzzy/input +13 -0
- data/samples/standard/fuzzy/output +12 -0
- data/samples/standard/hoisted-predicates/HoistedPredicates.g +40 -0
- data/samples/standard/hoisted-predicates/hoisted-predicates.rb +13 -0
- data/samples/standard/hoisted-predicates/input +1 -0
- data/samples/standard/hoisted-predicates/output +1 -0
- data/samples/standard/island-grammar/Javadoc.g +46 -0
- data/samples/standard/island-grammar/Simple.g +104 -0
- data/samples/standard/island-grammar/input +11 -0
- data/samples/standard/island-grammar/island.rb +12 -0
- data/samples/standard/island-grammar/output +16 -0
- data/samples/standard/java/Java.g +827 -0
- data/samples/standard/java/input +80 -0
- data/samples/standard/java/java.rb +13 -0
- data/samples/standard/java/output +1 -0
- data/samples/standard/python/Python.g +718 -0
- data/samples/standard/python/PythonTokenSource.rb +107 -0
- data/samples/standard/python/input +210 -0
- data/samples/standard/python/output +24 -0
- data/samples/standard/python/python.rb +14 -0
- data/samples/standard/rakefile +18 -0
- data/samples/standard/scopes/SymbolTable.g +66 -0
- data/samples/standard/scopes/input +12 -0
- data/samples/standard/scopes/output +3 -0
- data/samples/standard/scopes/scopes.rb +12 -0
- data/samples/standard/simplecTreeParser/SimpleC.g +113 -0
- data/samples/standard/simplecTreeParser/SimpleCWalker.g +64 -0
- data/samples/standard/simplecTreeParser/input +12 -0
- data/samples/standard/simplecTreeParser/output +1 -0
- data/samples/standard/simplecTreeParser/simplec.rb +18 -0
- data/samples/standard/treeparser/Lang.g +24 -0
- data/samples/standard/treeparser/LangDumpDecl.g +17 -0
- data/samples/standard/treeparser/input +1 -0
- data/samples/standard/treeparser/output +2 -0
- data/samples/standard/treeparser/treeparser.rb +18 -0
- data/samples/standard/tweak/Tweak.g +68 -0
- data/samples/standard/tweak/input +9 -0
- data/samples/standard/tweak/output +16 -0
- data/samples/standard/tweak/tweak.rb +13 -0
- data/samples/standard/xml/README +16 -0
- data/samples/standard/xml/XML.g +123 -0
- data/samples/standard/xml/input +21 -0
- data/samples/standard/xml/output +39 -0
- data/samples/standard/xml/xml.rb +9 -0
- data/templates/Ruby.stg +4 -4
- data/test/functional/ast-output/auto-ast.rb +0 -5
- data/test/functional/ast-output/rewrites.rb +4 -4
- data/test/unit/test-scope.rb +45 -0
- metadata +96 -8
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
group Bytecode
|
|
2
|
+
|
|
3
|
+
program(globals,functions) ::=
|
|
4
|
+
<<<
|
|
5
|
+
.class public Wrapper
|
|
6
|
+
.super java/lang/Object
|
|
7
|
+
<%= @globals.join( "\n" ) %>
|
|
8
|
+
<%= @functions.join( "\n" ) %>
|
|
9
|
+
>>>
|
|
10
|
+
|
|
11
|
+
variable(type,name) ::= ".var is <%= @name %> <%= @type %>"
|
|
12
|
+
|
|
13
|
+
globalVariable(type,name) ::= ".field <%= @name %> <%= @type %>"
|
|
14
|
+
|
|
15
|
+
function(type,name,args,locals,stats) ::=
|
|
16
|
+
<<<
|
|
17
|
+
.method <%= @name %>(<%= @args.map { | i | i.type } %>)<%= @type %>
|
|
18
|
+
<%= @locals %>
|
|
19
|
+
% for stat in @stats
|
|
20
|
+
<%= stat %>
|
|
21
|
+
% end
|
|
22
|
+
return
|
|
23
|
+
.end method
|
|
24
|
+
>>>
|
|
25
|
+
|
|
26
|
+
type_int() ::= "I"
|
|
27
|
+
|
|
28
|
+
type_char() ::= "C"
|
|
29
|
+
|
|
30
|
+
type_user_object( name ) ::= "L<%= @name %>;"
|
|
31
|
+
|
|
32
|
+
parameter(type,name) ::= "<%= @type %> <%= @name %>"
|
|
33
|
+
|
|
34
|
+
statement(expr) ::= "<%= @expr %>"
|
|
35
|
+
|
|
36
|
+
statementList(locals,stats) ::= <<
|
|
37
|
+
<%= @locals %>
|
|
38
|
+
<%= stats.join( "\n" ) %>
|
|
39
|
+
>>
|
|
40
|
+
|
|
41
|
+
forLoop(e1,e2,e3,locals,stats) ::= <<
|
|
42
|
+
<%= @e1 %>
|
|
43
|
+
start:
|
|
44
|
+
<%= @e2 %>
|
|
45
|
+
bf exit
|
|
46
|
+
<%= @locals %>
|
|
47
|
+
% for stat in @stats
|
|
48
|
+
<%= stat %>
|
|
49
|
+
% end
|
|
50
|
+
<%= e3 %>
|
|
51
|
+
goto start
|
|
52
|
+
exit:
|
|
53
|
+
>>
|
|
54
|
+
|
|
55
|
+
assign(lhs,rhs) ::= <<
|
|
56
|
+
<%= @rhs %>
|
|
57
|
+
store <%= @lhs %>
|
|
58
|
+
>>
|
|
59
|
+
|
|
60
|
+
equals(left,right) ::= <<
|
|
61
|
+
<%= @left %>
|
|
62
|
+
<%= @right %>
|
|
63
|
+
equals
|
|
64
|
+
>>
|
|
65
|
+
|
|
66
|
+
lessThan(left,right) ::= <<
|
|
67
|
+
<%= @left %>
|
|
68
|
+
<%= @right %>
|
|
69
|
+
lt
|
|
70
|
+
>>
|
|
71
|
+
|
|
72
|
+
add(left,right) ::= <<
|
|
73
|
+
<%= @left %>
|
|
74
|
+
<%= @right %>
|
|
75
|
+
add
|
|
76
|
+
>>
|
|
77
|
+
|
|
78
|
+
refVar(id) ::= "push <%= @id %>"
|
|
79
|
+
|
|
80
|
+
iconst(value) ::= "iconst <%= @value %>"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
|
|
4
|
+
$LOAD_PATH.unshift( File.dirname( __FILE__ ) )
|
|
5
|
+
require 'CMinusLexer'
|
|
6
|
+
require 'CMinusParser'
|
|
7
|
+
|
|
8
|
+
input = ARGV.shift or fail( "please provide an input file path" )
|
|
9
|
+
options = {}
|
|
10
|
+
if template_file = ARGV.shift
|
|
11
|
+
options[ :templates ] = ANTLR3::Template::Group.load( template_file )
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
input = ANTLR3::FileStream.new( input )
|
|
15
|
+
lexer = CMinus::Lexer.new( input )
|
|
16
|
+
puts( CMinus::Parser.new( lexer, options ).program.template )
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
group CMinus::Java
|
|
2
|
+
|
|
3
|
+
indent( text, level ) ::=
|
|
4
|
+
<<<
|
|
5
|
+
% @text.to_s.each_line do | line |
|
|
6
|
+
<%= ' ' * @level %><%= line.chomp %>
|
|
7
|
+
% end
|
|
8
|
+
>>>
|
|
9
|
+
|
|
10
|
+
program(globals,functions) ::=
|
|
11
|
+
<<<
|
|
12
|
+
class Wrapper {
|
|
13
|
+
% for global in @globals
|
|
14
|
+
<%= global %>
|
|
15
|
+
% end
|
|
16
|
+
% for function in @functions
|
|
17
|
+
% for line in function.to_s.lines
|
|
18
|
+
<%= line.chomp %>
|
|
19
|
+
% end
|
|
20
|
+
% end
|
|
21
|
+
}
|
|
22
|
+
>>>
|
|
23
|
+
|
|
24
|
+
variable(type,name) ::= "<%= @type %> <%= @name %>;"
|
|
25
|
+
|
|
26
|
+
globalVariable ::= variable
|
|
27
|
+
|
|
28
|
+
function(type,name,args,locals,stats) ::=
|
|
29
|
+
<<<
|
|
30
|
+
<%= @type %> <%= @name %>( <%= @args.join( ', ' ) %> ) {
|
|
31
|
+
% for local in @locals
|
|
32
|
+
<%= local %>
|
|
33
|
+
% end
|
|
34
|
+
% for stat in @stats
|
|
35
|
+
% for line in stat.to_s.lines
|
|
36
|
+
<%= line.chomp %>
|
|
37
|
+
% end
|
|
38
|
+
% end
|
|
39
|
+
}
|
|
40
|
+
>>>
|
|
41
|
+
|
|
42
|
+
type_int() ::= "int"
|
|
43
|
+
|
|
44
|
+
type_char() ::= "char"
|
|
45
|
+
|
|
46
|
+
type_user_object(name) ::= "<%= @name %>"
|
|
47
|
+
|
|
48
|
+
parameter(type,name) ::= "<%= @type %> <%= @name %>"
|
|
49
|
+
|
|
50
|
+
statement(expr) ::= "<%= @expr %>;"
|
|
51
|
+
|
|
52
|
+
statementList(locals,stats) ::=
|
|
53
|
+
<<<
|
|
54
|
+
{
|
|
55
|
+
% for local in @locals
|
|
56
|
+
<%= local %>
|
|
57
|
+
% end
|
|
58
|
+
% for stat in @stats
|
|
59
|
+
% for line in stat.to_s.lines
|
|
60
|
+
<%= line.chomp %>
|
|
61
|
+
% end
|
|
62
|
+
% end
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
>>>
|
|
66
|
+
|
|
67
|
+
forLoop(e1,e2,e3,locals,stats) ::=
|
|
68
|
+
<<<
|
|
69
|
+
for (<%= @e1 %> <%= @e2 %>; <%= @e3 %>) {
|
|
70
|
+
% for local in @locals
|
|
71
|
+
<%= local %>
|
|
72
|
+
% end
|
|
73
|
+
% for stat in @stats
|
|
74
|
+
% for line in stat.to_s.lines
|
|
75
|
+
<%= line.chomp %>
|
|
76
|
+
% end
|
|
77
|
+
% end
|
|
78
|
+
}
|
|
79
|
+
>>>
|
|
80
|
+
|
|
81
|
+
assign(lhs,rhs) ::= "<%= @lhs %> = <%= @rhs %>;"
|
|
82
|
+
|
|
83
|
+
equals(left,right) ::= "<%= @left %> == <%= @right %>"
|
|
84
|
+
|
|
85
|
+
lessThan(left,right) ::= "<%= @left %> < <%= @right %>"
|
|
86
|
+
|
|
87
|
+
add(left,right) ::= "<%= @left %> + <%= @right %>"
|
|
88
|
+
|
|
89
|
+
refVar(id) ::= "<%= @id %>"
|
|
90
|
+
|
|
91
|
+
iconst(value) ::= "<%= @value %>"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
group Python;
|
|
2
|
+
|
|
3
|
+
program(globals,functions) ::= <<
|
|
4
|
+
<functions; separator="\n">
|
|
5
|
+
>>
|
|
6
|
+
|
|
7
|
+
variable(type,name) ::= " "
|
|
8
|
+
|
|
9
|
+
globalVariable ::= variable
|
|
10
|
+
|
|
11
|
+
function(type,name,args,locals,stats) ::= <<
|
|
12
|
+
def <name>(<args; separator=", ">):
|
|
13
|
+
<stats>
|
|
14
|
+
>>
|
|
15
|
+
|
|
16
|
+
type_int() ::= "int"
|
|
17
|
+
|
|
18
|
+
type_char() ::= "char"
|
|
19
|
+
|
|
20
|
+
type_user_object(name) ::= "<name>"
|
|
21
|
+
|
|
22
|
+
parameter(type,name) ::= "<name>"
|
|
23
|
+
|
|
24
|
+
statement(expr) ::= "<expr>"
|
|
25
|
+
|
|
26
|
+
statementList(locals,stats) ::= <<
|
|
27
|
+
<stats; separator="\n">
|
|
28
|
+
>>
|
|
29
|
+
|
|
30
|
+
// python has a weird FOR, use a WHILE. :)
|
|
31
|
+
forLoop(e1,e2,e3,locals,stats) ::= <<
|
|
32
|
+
<e1>
|
|
33
|
+
while ( <e2> ):
|
|
34
|
+
<stats; separator="\n">
|
|
35
|
+
<e3>
|
|
36
|
+
>>
|
|
37
|
+
|
|
38
|
+
assign(lhs,rhs) ::= "<lhs> = <rhs>"
|
|
39
|
+
|
|
40
|
+
equals(left,right) ::= "<left> == <right>"
|
|
41
|
+
|
|
42
|
+
lessThan(left,right) ::= "<left> \< <right>"
|
|
43
|
+
|
|
44
|
+
add(left,right) ::= "<left> + <right>"
|
|
45
|
+
|
|
46
|
+
refVar(id) ::= "<id>"
|
|
47
|
+
|
|
48
|
+
iconst(value) ::= "<value>"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
grammar DynamicScopes;
|
|
2
|
+
|
|
3
|
+
options {
|
|
4
|
+
language = Ruby;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
program : method ;
|
|
8
|
+
|
|
9
|
+
method
|
|
10
|
+
/* name is visible to any rule called by method directly or indirectly.
|
|
11
|
+
* There is also a stack of these names, one slot for each nested
|
|
12
|
+
* invocation of method. If you have a method nested within another
|
|
13
|
+
* method then you have name strings on the stack. Referencing
|
|
14
|
+
* $method.name access the topmost always. I have no way at the moment
|
|
15
|
+
* to access earlier elements on the stack.
|
|
16
|
+
*/
|
|
17
|
+
scope {
|
|
18
|
+
name;
|
|
19
|
+
}
|
|
20
|
+
: 'method' ID '(' ')' { $method::name = $ID.text } body
|
|
21
|
+
;
|
|
22
|
+
|
|
23
|
+
body: '{' stat* '}'
|
|
24
|
+
;
|
|
25
|
+
|
|
26
|
+
stat: ID '=' expr ';'
|
|
27
|
+
| method // allow nested methods to demo stack nature of dynamic attributes
|
|
28
|
+
;
|
|
29
|
+
|
|
30
|
+
expr: mul ('+' mul)*
|
|
31
|
+
;
|
|
32
|
+
|
|
33
|
+
mul : atom ('*' atom)*
|
|
34
|
+
;
|
|
35
|
+
|
|
36
|
+
/** Demonstrate that 'name' is a dynamically-scoped attribute defined
|
|
37
|
+
* within rule method. With lexical-scoping (variables go away at
|
|
38
|
+
* the end of the '}'), you'd have to pass the current method name
|
|
39
|
+
* down through all rules as a parameter. Ick. This is much much better.
|
|
40
|
+
*/
|
|
41
|
+
atom: ID { puts( "ref #{ $ID.text } from method #{ $method::name }" ) }
|
|
42
|
+
| INT { puts( "int #{ $INT.text } in method #{ $method::name }" ) }
|
|
43
|
+
;
|
|
44
|
+
|
|
45
|
+
ID : ('a'..'z'|'A'..'Z')+ ;
|
|
46
|
+
|
|
47
|
+
INT : '0'..'9'+ ;
|
|
48
|
+
|
|
49
|
+
WS : (' '|'\t'|'\n')+ {$channel=HIDDEN}
|
|
50
|
+
;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
$:.unshift( File.dirname( __FILE__ ) )
|
|
4
|
+
require 'DynamicScopesLexer'
|
|
5
|
+
require 'DynamicScopesParser'
|
|
6
|
+
|
|
7
|
+
for file in ARGV
|
|
8
|
+
input = ANTLR3::FileStream.new( file )
|
|
9
|
+
lexer = DynamicScopes::Lexer.new( input )
|
|
10
|
+
parser = DynamicScopes::Parser.new( lexer )
|
|
11
|
+
parser.program
|
|
12
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
lexer grammar FuzzyJava;
|
|
2
|
+
options {
|
|
3
|
+
language=Ruby;
|
|
4
|
+
filter=true;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
IMPORT
|
|
8
|
+
: 'import' WS name=QIDStar WS? ';'
|
|
9
|
+
;
|
|
10
|
+
|
|
11
|
+
/** Avoids having "return foo;" match as a field */
|
|
12
|
+
RETURN
|
|
13
|
+
: 'return' .* ';'
|
|
14
|
+
;
|
|
15
|
+
|
|
16
|
+
CLASS
|
|
17
|
+
: 'class' WS name=ID WS? ('extends' WS QID WS?)?
|
|
18
|
+
('implements' WS QID WS? (',' WS? QID WS?)*)? '{'
|
|
19
|
+
{ puts( "found class #{ $name.text }" ) }
|
|
20
|
+
;
|
|
21
|
+
|
|
22
|
+
METHOD
|
|
23
|
+
: TYPE WS name=ID WS? '(' ( ARG WS? (',' WS? ARG WS?)* )? ')' WS?
|
|
24
|
+
('throws' WS QID WS? (',' WS? QID WS?)*)? '{'
|
|
25
|
+
{ puts( "found method #{ $name.text }" ) }
|
|
26
|
+
;
|
|
27
|
+
|
|
28
|
+
FIELD
|
|
29
|
+
: TYPE WS name=ID '[]'? WS? (';'|'=')
|
|
30
|
+
{ puts( "found var #{ $name.text }" ) }
|
|
31
|
+
;
|
|
32
|
+
|
|
33
|
+
STAT: ('if'|'while'|'switch'|'for') WS? '(' ;
|
|
34
|
+
|
|
35
|
+
CALL
|
|
36
|
+
: name=QID WS? '('
|
|
37
|
+
{ puts( "found call #{ $name.text }" ) }
|
|
38
|
+
;
|
|
39
|
+
|
|
40
|
+
COMMENT
|
|
41
|
+
: '/*' (options {greedy=false;} : . )* '*/'
|
|
42
|
+
{ puts( "found comment #{ $text }" ) }
|
|
43
|
+
;
|
|
44
|
+
|
|
45
|
+
SL_COMMENT
|
|
46
|
+
: '//' (options {greedy=false;} : . )* '\n'
|
|
47
|
+
{ puts( "found // comment #{ $text }" ) }
|
|
48
|
+
;
|
|
49
|
+
|
|
50
|
+
STRING
|
|
51
|
+
: '"' (options {greedy=false;}: ESC | .)* '"'
|
|
52
|
+
;
|
|
53
|
+
|
|
54
|
+
CHAR
|
|
55
|
+
: '\'' (options {greedy=false;}: ESC | .)* '\''
|
|
56
|
+
;
|
|
57
|
+
|
|
58
|
+
WS : (' '|'\t'|'\n')+
|
|
59
|
+
;
|
|
60
|
+
|
|
61
|
+
fragment
|
|
62
|
+
QID : ID ('.' ID)*
|
|
63
|
+
;
|
|
64
|
+
|
|
65
|
+
/** QID cannot see beyond end of token so using QID '.*'? somewhere won't
|
|
66
|
+
* ever match since k=1 lookahead in the QID loop of '.' will make it loop.
|
|
67
|
+
* I made this rule to compensate.
|
|
68
|
+
*/
|
|
69
|
+
fragment
|
|
70
|
+
QIDStar
|
|
71
|
+
: ID ('.' ID)* '.*'?
|
|
72
|
+
;
|
|
73
|
+
|
|
74
|
+
fragment
|
|
75
|
+
TYPE: QID '[]'?
|
|
76
|
+
;
|
|
77
|
+
|
|
78
|
+
fragment
|
|
79
|
+
ARG : TYPE WS ID
|
|
80
|
+
;
|
|
81
|
+
|
|
82
|
+
fragment
|
|
83
|
+
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
|
|
84
|
+
;
|
|
85
|
+
|
|
86
|
+
fragment
|
|
87
|
+
ESC : '\\' ('"'|'\''|'\\')
|
|
88
|
+
|
|
89
|
+
;
|