1 |
commit: 8600327ca12c34900887989dd7d0d93b6a366f01 |
2 |
Author: Mu Qiao <qiaomuf <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon Apr 4 12:45:44 2011 +0000 |
4 |
Commit: Petteri Räty <betelgeuse <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon Apr 4 16:00:58 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=8600327c |
7 |
|
8 |
Refactor walker grammar |
9 |
|
10 |
String related rules are too complex in walker grammar. Now we use |
11 |
a wildcard instead of listing all possible characters. Some names |
12 |
are modified to have a clearer meaning. |
13 |
|
14 |
--- |
15 |
bashast/libbashWalker.g | 62 +++++++++++----------------------------------- |
16 |
src/core/interpreter.h | 4 +++ |
17 |
2 files changed, 19 insertions(+), 47 deletions(-) |
18 |
|
19 |
diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g |
20 |
index d0f89bf..ac8a040 100644 |
21 |
--- a/bashast/libbashWalker.g |
22 |
+++ b/bashast/libbashWalker.g |
23 |
@@ -61,54 +61,22 @@ var_def: |
24 |
}; |
25 |
|
26 |
string_expr returns[std::string libbash_value]: |
27 |
- ^(STRING libbash_string=string_expr) { $libbash_value = libbash_string; } |
28 |
- |^(DOUBLE_QUOTED_STRING (libbash_string=dqstr { $libbash_value += libbash_string; })*) |
29 |
- |^(STRING libbash_string=dqstr) { $libbash_value = libbash_string; }; |
30 |
+ ^(STRING( |
31 |
+ (DOUBLE_QUOTED_STRING) => ^(DOUBLE_QUOTED_STRING (libbash_string=double_quoted_string { $libbash_value += libbash_string; })*) |
32 |
+ |libbash_string=any_string { $libbash_value = libbash_string; } |
33 |
+ )); |
34 |
|
35 |
-//A rule for filenames/strings |
36 |
-res_word_str returns[std::string libbash_value] |
37 |
-@after { |
38 |
- $libbash_value = walker->get_string($res_word_str.start); |
39 |
-}: |
40 |
- CASE|DO|DONE|ELIF|ELSE|ESAC|FI|FOR|FUNCTION|IF|IN|SELECT|THEN|UNTIL|WHILE|TIME; |
41 |
- |
42 |
-//Parts of strings, no slashes, no reserved words |
43 |
-ns_str_part_no_res returns[std::string libbash_value] |
44 |
-options{ backtrack=true; } |
45 |
-@after { |
46 |
- $libbash_value = walker->get_string($ns_str_part_no_res.start); |
47 |
-}: |
48 |
- num|name|EQUALS|PCT|PCTPCT|MINUS|DOT|DOTDOT|COLON|BOP|UOP|TEST_EXPR|'_'|TILDE|INC|DEC|MUL_ASSIGN|DIVIDE_ASSIGN|MOD_ASSIGN|PLUS_ASSIGN|MINUS_ASSIGN|LSHIFT_ASSIGN|RSHIFT_ASSIGN|AND_ASSIGN|XOR_ASSIGN|OR_ASSIGN|ESC_CHAR|CARET|OTHER; |
49 |
- |
50 |
-//Parts of strings, no slashes |
51 |
-ns_str_part returns[std::string libbash_value]: |
52 |
- ns_str_part_no_res { $libbash_value = $ns_str_part_no_res.libbash_value; } |
53 |
- |res_word_str {$libbash_value = $res_word_str.libbash_value; }; |
54 |
- |
55 |
-//Any allowable part of a string, including slashes, no pounds |
56 |
-str_part returns[std::string libbash_value]: |
57 |
- libbash_string=ns_str_part { $libbash_value = libbash_string; } |
58 |
- |SLASH { $libbash_value = "/"; }; |
59 |
- |
60 |
-//Any allowable part of a string, with pounds |
61 |
-str_part_with_pound returns[std::string libbash_value] |
62 |
-@after { |
63 |
- $libbash_value = walker->get_string($str_part_with_pound.start); |
64 |
-}: |
65 |
- str_part|POUND|POUNDPOUND; |
66 |
+//double quoted string rule, allows expansions |
67 |
+double_quoted_string returns[std::string libbash_value]: |
68 |
+ (var_ref) => libbash_string=var_ref { $libbash_value = libbash_string; } |
69 |
+ |(ARITHMETIC_EXPRESSION) => ^(ARITHMETIC_EXPRESSION value=arithmetics) { $libbash_value = boost::lexical_cast<std::string>(value); } |
70 |
+ |libbash_string=any_string { $libbash_value = libbash_string; }; |
71 |
|
72 |
-//Allowable parts of double quoted strings |
73 |
-dq_str_part returns[std::string libbash_value] |
74 |
-@after { |
75 |
- $libbash_value = walker->get_string($dq_str_part.start); |
76 |
+any_string returns[std::string libbash_value] |
77 |
+@declarations { |
78 |
+ pANTLR3_BASE_TREE any_token; |
79 |
}: |
80 |
- BLANK|EOL|AMP|LOGICAND|LOGICOR|LESS_THAN|GREATER_THAN|PIPE|SQUOTE|SEMIC|COMMA|LPAREN|RPAREN|LLPAREN|RRPAREN|DOUBLE_SEMIC|LBRACE|RBRACE|TICK|LEQ|GEQ|str_part_with_pound; |
81 |
- |
82 |
-//double quoted string rule, allows expansions |
83 |
-dqstr returns[std::string libbash_value]: |
84 |
- dq_str_part { $libbash_value = $dq_str_part.libbash_value; } |
85 |
- | libbash_string=var_ref { $libbash_value = libbash_string; } |
86 |
- | ^(ARITHMETIC_EXPRESSION value=arithmetics) { $libbash_value = boost::lexical_cast<std::string>(value); }; |
87 |
+ any_token=. { $libbash_value = walker->get_string(any_token); }; |
88 |
|
89 |
//Allowable variable names in the variable expansion |
90 |
var_name returns[std::string libbash_value] |
91 |
@@ -117,7 +85,7 @@ var_name returns[std::string libbash_value] |
92 |
}: |
93 |
num|name|TIMES|AT; |
94 |
|
95 |
-var_exp returns[std::string libbash_value]: |
96 |
+var_expansion returns[std::string libbash_value]: |
97 |
^(USE_DEFAULT var_name libbash_word=word) { |
98 |
libbash_value = walker->do_default_expansion($var_name.libbash_value, libbash_word); |
99 |
}; |
100 |
@@ -133,7 +101,7 @@ word returns[std::string libbash_value]: |
101 |
//variable reference |
102 |
var_ref returns[std::string libbash_value]: |
103 |
^(VAR_REF libbash_name=name) { $libbash_value = walker->resolve<std::string>(libbash_name); } |
104 |
- |^(VAR_REF libbash_string=var_exp) { $libbash_value = libbash_string; }; |
105 |
+ |^(VAR_REF libbash_string=var_expansion) { $libbash_value = libbash_string; }; |
106 |
|
107 |
// shell arithmetic |
108 |
arithmetics returns[int value] |
109 |
|
110 |
diff --git a/src/core/interpreter.h b/src/core/interpreter.h |
111 |
index 2fc8703..5e097ea 100644 |
112 |
--- a/src/core/interpreter.h |
113 |
+++ b/src/core/interpreter.h |
114 |
@@ -104,6 +104,10 @@ public: |
115 |
static std::string get_string(pANTLR3_BASE_TREE node) |
116 |
{ |
117 |
pANTLR3_COMMON_TOKEN token = node->getToken(node); |
118 |
+ // The tree walker may send null pointer here, so return an empty |
119 |
+ // string if that's the case. |
120 |
+ if(!token->start) |
121 |
+ return ""; |
122 |
// Use reinterpret_cast here because we have to cast C code. |
123 |
// The real type here is int64_t which is used as a pointer. |
124 |
return std::string(reinterpret_cast<const char *>(token->start), |