aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChong Yidong2010-01-09 19:38:07 -0500
committerChong Yidong2010-01-09 19:38:07 -0500
commit52bee098ba25ff9ff0f7697f3c2aed8f130866d6 (patch)
treeb32bc8379e592fa494f33a3ef0db37514c34ebbf
parente709e39d6e4014c85d0a73f7b5debf2e7660fcb4 (diff)
downloademacs-52bee098ba25ff9ff0f7697f3c2aed8f130866d6.tar.gz
emacs-52bee098ba25ff9ff0f7697f3c2aed8f130866d6.zip
Add Semantic parsers for Python.
* cedet/semantic.el (semantic-new-buffer-setup-functions): Add python parser. * cedet/semantic/wisent/python-wy.el, cedet/semantic/wisent/python.el: New files.
-rw-r--r--lisp/ChangeLog10
-rw-r--r--lisp/cedet/semantic.el9
-rw-r--r--lisp/cedet/semantic/wisent/python-wy.el749
-rw-r--r--lisp/cedet/semantic/wisent/python.el344
4 files changed, 1108 insertions, 4 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index ca021b92a44..96e9f4808aa 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,13 @@
12010-01-10 Chong Yidong <cyd@stupidchicken.com>
2
3 * cedet/semantic.el (semantic-new-buffer-setup-functions): Add
4 python parser.
5
62010-01-10 Richard Kim <emacs18@gmail.com>
7
8 * cedet/semantic/wisent/python-wy.el:
9 * cedet/semantic/wisent/python.el: New files.
10
12010-01-09 Chong Yidong <cyd@stupidchicken.com> 112010-01-09 Chong Yidong <cyd@stupidchicken.com>
2 12
3 * man.el (Man-goto-section): Signal error if the section is not 13 * man.el (Man-goto-section): Signal error if the section is not
diff --git a/lisp/cedet/semantic.el b/lisp/cedet/semantic.el
index 7e3673e6adb..466bb3fdcc3 100644
--- a/lisp/cedet/semantic.el
+++ b/lisp/cedet/semantic.el
@@ -266,12 +266,13 @@ setup to use Semantic."
266 :type 'hook) 266 :type 'hook)
267 267
268(defcustom semantic-new-buffer-setup-functions 268(defcustom semantic-new-buffer-setup-functions
269 '((js-mode . wisent-javascript-setup-parser) 269 '((c-mode . semantic-default-c-setup)
270 (java-mode . wisent-java-default-setup)
271 (scheme-mode . semantic-default-scheme-setup)
272 (c-mode . semantic-default-c-setup)
273 (c++-mode . semantic-default-c-setup) 270 (c++-mode . semantic-default-c-setup)
274 (html-mode . semantic-default-html-setup) 271 (html-mode . semantic-default-html-setup)
272 (java-mode . wisent-java-default-setup)
273 (js-mode . wisent-javascript-setup-parser)
274 (python-mode . wisent-python-default-setup)
275 (scheme-mode . semantic-default-scheme-setup)
275 (srecode-template-mode . srecode-template-setup-parser) 276 (srecode-template-mode . srecode-template-setup-parser)
276 (makefile-automake-mode . semantic-default-make-setup) 277 (makefile-automake-mode . semantic-default-make-setup)
277 (makefile-gmake-mode . semantic-default-make-setup) 278 (makefile-gmake-mode . semantic-default-make-setup)
diff --git a/lisp/cedet/semantic/wisent/python-wy.el b/lisp/cedet/semantic/wisent/python-wy.el
new file mode 100644
index 00000000000..62839abe949
--- /dev/null
+++ b/lisp/cedet/semantic/wisent/python-wy.el
@@ -0,0 +1,749 @@
1;;; semantic/wisent/python-wy.el --- Generated parser support file
2
3;; Copyright (C) 2002, 2003, 2004, 2007, 2010
4;; Free Software Foundation, Inc.
5
6;; This file is part of GNU Emacs.
7
8;; GNU Emacs is free software: you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation, either version 3 of the License, or
11;; (at your option) any later version.
12
13;; GNU Emacs is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;; GNU General Public License for more details.
17
18;; You should have received a copy of the GNU General Public License
19;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
20
21;;; Commentary:
22;;
23;; This file was generated from the grammar file
24;; semantic/wisent/wisent-python.wy in the CEDET repository.
25
26;;; Code:
27
28(require 'semantic/lex)
29
30;;; Prologue
31;;
32
33;;; Declarations
34;;
35(defconst wisent-python-wy--keyword-table
36 (semantic-lex-make-keyword-table
37 '(("and" . AND)
38 ("assert" . ASSERT)
39 ("break" . BREAK)
40 ("class" . CLASS)
41 ("continue" . CONTINUE)
42 ("def" . DEF)
43 ("del" . DEL)
44 ("elif" . ELIF)
45 ("else" . ELSE)
46 ("except" . EXCEPT)
47 ("exec" . EXEC)
48 ("finally" . FINALLY)
49 ("for" . FOR)
50 ("from" . FROM)
51 ("global" . GLOBAL)
52 ("if" . IF)
53 ("import" . IMPORT)
54 ("in" . IN)
55 ("is" . IS)
56 ("lambda" . LAMBDA)
57 ("not" . NOT)
58 ("or" . OR)
59 ("pass" . PASS)
60 ("print" . PRINT)
61 ("raise" . RAISE)
62 ("return" . RETURN)
63 ("try" . TRY)
64 ("while" . WHILE)
65 ("yield" . YIELD))
66 '(("yield" summary "Create a generator function")
67 ("while" summary "Start a 'while' loop")
68 ("try" summary "Start of statements protected by exception handlers")
69 ("return" summary "Return from a function")
70 ("raise" summary "Raise an exception")
71 ("print" summary "Print each argument to standard output")
72 ("pass" summary "Statement that does nothing")
73 ("or" summary "Binary logical 'or' operator")
74 ("not" summary "Unary boolean negation operator")
75 ("is" summary "Binary operator that tests for object equality")
76 ("in" summary "Part of 'for' statement ")
77 ("import" summary "Load specified modules")
78 ("if" summary "Start 'if' conditional statement")
79 ("global" summary "Declare one or more symbols as global symbols")
80 ("from" summary "Modify behavior of 'import' statement")
81 ("for" summary "Start a 'for' loop")
82 ("finally" summary "Specify code to be executed after 'try' statements whether or not an exception occured")
83 ("exec" summary "Dynamically execute python code")
84 ("except" summary "Specify exception handlers along with 'try' keyword")
85 ("else" summary "Start the 'else' clause following an 'if' statement")
86 ("elif" summary "Shorthand for 'else if' following an 'if' statement")
87 ("del" summary "Delete specified objects, i.e., undo what assignment did")
88 ("def" summary "Define a new function")
89 ("continue" summary "Skip to the next interation of enclosing for or whilte loop")
90 ("class" summary "Define a new class")
91 ("break" summary "Terminate 'for' or 'while loop")
92 ("assert" summary "Raise AssertionError exception if <expr> is false")
93 ("and" summary "Logical AND binary operator ... ")))
94 "Table of language keywords.")
95
96(defconst wisent-python-wy--token-table
97 (semantic-lex-make-type-table
98 '(("symbol"
99 (NAME))
100 ("number"
101 (NUMBER_LITERAL))
102 ("string"
103 (STRING_LITERAL))
104 ("punctuation"
105 (BACKQUOTE . "`")
106 (ASSIGN . "=")
107 (COMMA . ",")
108 (SEMICOLON . ";")
109 (COLON . ":")
110 (BAR . "|")
111 (TILDE . "~")
112 (PERIOD . ".")
113 (MINUS . "-")
114 (PLUS . "+")
115 (MOD . "%")
116 (DIV . "/")
117 (MULT . "*")
118 (AMP . "&")
119 (GT . ">")
120 (LT . "<")
121 (HAT . "^")
122 (NE . "!=")
123 (LTGT . "<>")
124 (HATEQ . "^=")
125 (OREQ . "|=")
126 (AMPEQ . "&=")
127 (MODEQ . "%=")
128 (DIVEQ . "/=")
129 (MULTEQ . "*=")
130 (MINUSEQ . "-=")
131 (PLUSEQ . "+=")
132 (LE . "<=")
133 (GE . ">=")
134 (EQ . "==")
135 (EXPONENT . "**")
136 (GTGT . ">>")
137 (LTLT . "<<")
138 (DIVDIV . "//")
139 (DIVDIVEQ . "//=")
140 (EXPEQ . "**=")
141 (GTGTEQ . ">>=")
142 (LTLTEQ . "<<="))
143 ("close-paren"
144 (RBRACK . "]")
145 (RBRACE . "}")
146 (RPAREN . ")"))
147 ("open-paren"
148 (LBRACK . "[")
149 (LBRACE . "{")
150 (LPAREN . "("))
151 ("block"
152 (BRACK_BLOCK . "(LBRACK RBRACK)")
153 (BRACE_BLOCK . "(LBRACE RBRACE)")
154 (PAREN_BLOCK . "(LPAREN RPAREN)"))
155 ("indentation"
156 (INDENT_BLOCK . "(INDENT DEDENT)")
157 (DEDENT . "[^:INDENT:]")
158 (INDENT . "^\\s-+"))
159 ("newline"
160 (NEWLINE . "\n"))
161 ("charquote"
162 (BACKSLASH . "\\")))
163 '(("keyword" :declared t)
164 ("symbol" :declared t)
165 ("number" :declared t)
166 ("punctuation" :declared t)
167 ("block" :declared t)))
168 "Table of lexical tokens.")
169
170(defconst wisent-python-wy--parse-table
171 (progn
172 (eval-when-compile
173 (require 'semantic/wisent/comp))
174 (wisent-compile-grammar
175 '((BACKSLASH NEWLINE INDENT DEDENT INDENT_BLOCK PAREN_BLOCK BRACE_BLOCK BRACK_BLOCK LPAREN RPAREN LBRACE RBRACE LBRACK RBRACK LTLTEQ GTGTEQ EXPEQ DIVDIVEQ DIVDIV LTLT GTGT EXPONENT EQ GE LE PLUSEQ MINUSEQ MULTEQ DIVEQ MODEQ AMPEQ OREQ HATEQ LTGT NE HAT LT GT AMP MULT DIV MOD PLUS MINUS PERIOD TILDE BAR COLON SEMICOLON COMMA ASSIGN BACKQUOTE STRING_LITERAL NUMBER_LITERAL NAME AND ASSERT BREAK CLASS CONTINUE DEF DEL ELIF ELSE EXCEPT EXEC FINALLY FOR FROM GLOBAL IF IMPORT IN IS LAMBDA NOT OR PASS PRINT RAISE RETURN TRY WHILE YIELD)
176 nil
177 (goal
178 ((NEWLINE))
179 ((simple_stmt))
180 ((compound_stmt)))
181 (simple_stmt
182 ((small_stmt_list semicolon_opt NEWLINE)))
183 (small_stmt_list
184 ((small_stmt))
185 ((small_stmt_list SEMICOLON small_stmt)))
186 (small_stmt
187 ((expr_stmt))
188 ((print_stmt))
189 ((del_stmt))
190 ((pass_stmt))
191 ((flow_stmt))
192 ((import_stmt))
193 ((global_stmt))
194 ((exec_stmt))
195 ((assert_stmt)))
196 (print_stmt
197 ((PRINT print_stmt_trailer)
198 (wisent-raw-tag
199 (semantic-tag-new-code $1 nil))))
200 (print_stmt_trailer
201 ((test_list_opt)
202 nil)
203 ((GTGT test trailing_test_list_with_opt_comma_opt)
204 nil))
205 (trailing_test_list_with_opt_comma_opt
206 (nil)
207 ((trailing_test_list comma_opt)
208 nil))
209 (trailing_test_list
210 ((COMMA test)
211 nil)
212 ((trailing_test_list COMMA test)
213 nil))
214 (expr_stmt
215 ((testlist expr_stmt_trailer)
216 (if
217 (and $2
218 (stringp $1)
219 (string-match "^\\(\\sw\\|\\s_\\)+$" $1))
220 (wisent-raw-tag
221 (semantic-tag-new-variable $1 nil nil))
222 (wisent-raw-tag
223 (semantic-tag-new-code $1 nil)))))
224 (expr_stmt_trailer
225 ((augassign testlist))
226 ((eq_testlist_zom)))
227 (eq_testlist_zom
228 (nil)
229 ((eq_testlist_zom ASSIGN testlist)
230 (identity $3)))
231 (augassign
232 ((PLUSEQ))
233 ((MINUSEQ))
234 ((MULTEQ))
235 ((DIVEQ))
236 ((MODEQ))
237 ((AMPEQ))
238 ((OREQ))
239 ((HATEQ))
240 ((LTLTEQ))
241 ((GTGTEQ))
242 ((EXPEQ))
243 ((DIVDIVEQ)))
244 (del_stmt
245 ((DEL exprlist)
246 (wisent-raw-tag
247 (semantic-tag-new-code $1 nil))))
248 (exprlist
249 ((expr_list comma_opt)
250 nil))
251 (expr_list
252 ((expr)
253 nil)
254 ((expr_list COMMA expr)
255 nil))
256 (pass_stmt
257 ((PASS)
258 (wisent-raw-tag
259 (semantic-tag-new-code $1 nil))))
260 (flow_stmt
261 ((break_stmt))
262 ((continue_stmt))
263 ((return_stmt))
264 ((raise_stmt))
265 ((yield_stmt)))
266 (break_stmt
267 ((BREAK)
268 (wisent-raw-tag
269 (semantic-tag-new-code $1 nil))))
270 (continue_stmt
271 ((CONTINUE)
272 (wisent-raw-tag
273 (semantic-tag-new-code $1 nil))))
274 (return_stmt
275 ((RETURN testlist_opt)
276 (wisent-raw-tag
277 (semantic-tag-new-code $1 nil))))
278 (testlist_opt
279 (nil)
280 ((testlist)
281 nil))
282 (yield_stmt
283 ((YIELD testlist)
284 (wisent-raw-tag
285 (semantic-tag-new-code $1 nil))))
286 (raise_stmt
287 ((RAISE zero_one_two_or_three_tests)
288 (wisent-raw-tag
289 (semantic-tag-new-code $1 nil))))
290 (zero_one_two_or_three_tests
291 (nil)
292 ((test zero_one_or_two_tests)
293 nil))
294 (zero_one_or_two_tests
295 (nil)
296 ((COMMA test zero_or_one_comma_test)
297 nil))
298 (zero_or_one_comma_test
299 (nil)
300 ((COMMA test)
301 nil))
302 (import_stmt
303 ((IMPORT dotted_as_name_list)
304 (wisent-raw-tag
305 (semantic-tag-new-include $2 nil)))
306 ((FROM dotted_name IMPORT star_or_import_as_name_list)
307 (wisent-raw-tag
308 (semantic-tag-new-include $2 nil))))
309 (dotted_as_name_list
310 ((dotted_as_name))
311 ((dotted_as_name_list COMMA dotted_as_name)))
312 (star_or_import_as_name_list
313 ((MULT)
314 nil)
315 ((import_as_name_list)
316 nil))
317 (import_as_name_list
318 ((import_as_name)
319 nil)
320 ((import_as_name_list COMMA import_as_name)
321 nil))
322 (import_as_name
323 ((NAME name_name_opt)
324 nil))
325 (dotted_as_name
326 ((dotted_name name_name_opt)))
327 (name_name_opt
328 (nil)
329 ((NAME NAME)
330 nil))
331 (dotted_name
332 ((NAME))
333 ((dotted_name PERIOD NAME)
334 (format "%s.%s" $1 $3)))
335 (global_stmt
336 ((GLOBAL comma_sep_name_list)
337 (wisent-raw-tag
338 (semantic-tag-new-code $1 nil))))
339 (comma_sep_name_list
340 ((NAME))
341 ((comma_sep_name_list COMMA NAME)))
342 (exec_stmt
343 ((EXEC expr exec_trailer)
344 (wisent-raw-tag
345 (semantic-tag-new-code $1 nil))))
346 (exec_trailer
347 (nil)
348 ((IN test comma_test_opt)
349 nil))
350 (comma_test_opt
351 (nil)
352 ((COMMA test)
353 nil))
354 (assert_stmt
355 ((ASSERT test comma_test_opt)
356 (wisent-raw-tag
357 (semantic-tag-new-code $1 nil))))
358 (compound_stmt
359 ((if_stmt))
360 ((while_stmt))
361 ((for_stmt))
362 ((try_stmt))
363 ((funcdef))
364 ((class_declaration)))
365 (if_stmt
366 ((IF test COLON suite elif_suite_pair_list else_suite_pair_opt)
367 (wisent-raw-tag
368 (semantic-tag-new-code $1 nil))))
369 (elif_suite_pair_list
370 (nil)
371 ((elif_suite_pair_list ELIF test COLON suite)
372 nil))
373 (else_suite_pair_opt
374 (nil)
375 ((ELSE COLON suite)
376 nil))
377 (suite
378 ((simple_stmt)
379 (list $1))
380 ((NEWLINE indented_block)
381 (progn $2)))
382 (indented_block
383 ((INDENT_BLOCK)
384 (semantic-parse-region
385 (car $region1)
386 (cdr $region1)
387 'indented_block_body 1)))
388 (indented_block_body
389 ((INDENT)
390 nil)
391 ((DEDENT)
392 nil)
393 ((simple_stmt))
394 ((compound_stmt)))
395 (while_stmt
396 ((WHILE test COLON suite else_suite_pair_opt)
397 (wisent-raw-tag
398 (semantic-tag-new-code $1 nil))))
399 (for_stmt
400 ((FOR exprlist IN testlist COLON suite else_suite_pair_opt)
401 (wisent-raw-tag
402 (semantic-tag-new-code $1 nil))))
403 (try_stmt
404 ((TRY COLON suite except_clause_suite_pair_list else_suite_pair_opt)
405 (wisent-raw-tag
406 (semantic-tag-new-code $1 nil)))
407 ((TRY COLON suite FINALLY COLON suite)
408 (wisent-raw-tag
409 (semantic-tag-new-code $1 nil))))
410 (except_clause_suite_pair_list
411 ((except_clause COLON suite)
412 nil)
413 ((except_clause_suite_pair_list except_clause COLON suite)
414 nil))
415 (except_clause
416 ((EXCEPT zero_one_or_two_test)
417 nil))
418 (zero_one_or_two_test
419 (nil)
420 ((test zero_or_one_comma_test)
421 nil))
422 (funcdef
423 ((DEF NAME function_parameter_list COLON suite)
424 (wisent-raw-tag
425 (semantic-tag-new-function $2 nil $3))))
426 (function_parameter_list
427 ((PAREN_BLOCK)
428 (let
429 ((wisent-python-EXPANDING-block t))
430 (semantic-parse-region
431 (car $region1)
432 (cdr $region1)
433 'function_parameters 1))))
434 (function_parameters
435 ((LPAREN)
436 nil)
437 ((RPAREN)
438 nil)
439 ((function_parameter COMMA))
440 ((function_parameter RPAREN)))
441 (function_parameter
442 ((fpdef_opt_test))
443 ((MULT NAME)
444 (wisent-raw-tag
445 (semantic-tag-new-variable $2 nil nil)))
446 ((EXPONENT NAME)
447 (wisent-raw-tag
448 (semantic-tag-new-variable $2 nil nil))))
449 (class_declaration
450 ((CLASS NAME paren_class_list_opt COLON suite)
451 (wisent-raw-tag
452 (semantic-tag-new-type $2 $1 $5
453 (cons $3 nil)))))
454 (paren_class_list_opt
455 (nil)
456 ((paren_class_list)))
457 (paren_class_list
458 ((PAREN_BLOCK)
459 (let
460 ((wisent-python-EXPANDING-block t))
461 (mapcar 'semantic-tag-name
462 (semantic-parse-region
463 (car $region1)
464 (cdr $region1)
465 'paren_classes 1)))))
466 (paren_classes
467 ((LPAREN)
468 nil)
469 ((RPAREN)
470 nil)
471 ((paren_class COMMA)
472 (wisent-raw-tag
473 (semantic-tag-new-variable $1 nil nil)))
474 ((paren_class RPAREN)
475 (wisent-raw-tag
476 (semantic-tag-new-variable $1 nil nil))))
477 (paren_class
478 ((dotted_name)))
479 (test
480 ((test_test))
481 ((lambdef)))
482 (test_test
483 ((and_test))
484 ((test_test OR and_test)
485 nil))
486 (and_test
487 ((not_test))
488 ((and_test AND not_test)
489 nil))
490 (not_test
491 ((NOT not_test)
492 nil)
493 ((comparison)))
494 (comparison
495 ((expr))
496 ((comparison comp_op expr)
497 nil))
498 (comp_op
499 ((LT))
500 ((GT))
501 ((EQ))
502 ((GE))
503 ((LE))
504 ((LTGT))
505 ((NE))
506 ((IN))
507 ((NOT IN))
508 ((IS))
509 ((IS NOT)))
510 (expr
511 ((xor_expr))
512 ((expr BAR xor_expr)
513 nil))
514 (xor_expr
515 ((and_expr))
516 ((xor_expr HAT and_expr)
517 nil))
518 (and_expr
519 ((shift_expr))
520 ((and_expr AMP shift_expr)
521 nil))
522 (shift_expr
523 ((arith_expr))
524 ((shift_expr shift_expr_operators arith_expr)
525 nil))
526 (shift_expr_operators
527 ((LTLT))
528 ((GTGT)))
529 (arith_expr
530 ((term))
531 ((arith_expr plus_or_minus term)
532 nil))
533 (plus_or_minus
534 ((PLUS))
535 ((MINUS)))
536 (term
537 ((factor))
538 ((term term_operator factor)
539 nil))
540 (term_operator
541 ((MULT))
542 ((DIV))
543 ((MOD))
544 ((DIVDIV)))
545 (factor
546 ((prefix_operators factor)
547 nil)
548 ((power)))
549 (prefix_operators
550 ((PLUS))
551 ((MINUS))
552 ((TILDE)))
553 (power
554 ((atom trailer_zom exponent_zom)
555 (concat $1
556 (if $2
557 (concat " " $2 " ")
558 "")
559 (if $3
560 (concat " " $3)
561 ""))))
562 (trailer_zom
563 (nil)
564 ((trailer_zom trailer)
565 nil))
566 (exponent_zom
567 (nil)
568 ((exponent_zom EXPONENT factor)
569 nil))
570 (trailer
571 ((PAREN_BLOCK)
572 nil)
573 ((BRACK_BLOCK)
574 nil)
575 ((PERIOD NAME)
576 nil))
577 (atom
578 ((PAREN_BLOCK)
579 nil)
580 ((BRACK_BLOCK)
581 nil)
582 ((BRACE_BLOCK)
583 nil)
584 ((BACKQUOTE testlist BACKQUOTE)
585 nil)
586 ((NAME))
587 ((NUMBER_LITERAL))
588 ((one_or_more_string)))
589 (test_list_opt
590 (nil)
591 ((testlist)
592 nil))
593 (testlist
594 ((comma_sep_test_list comma_opt)))
595 (comma_sep_test_list
596 ((test))
597 ((comma_sep_test_list COMMA test)
598 (format "%s, %s" $1 $3)))
599 (one_or_more_string
600 ((STRING_LITERAL))
601 ((one_or_more_string STRING_LITERAL)
602 (concat $1 $2)))
603 (lambdef
604 ((LAMBDA varargslist_opt COLON test)
605 (format "%s %s" $1
606 (or $2 ""))))
607 (varargslist_opt
608 (nil)
609 ((varargslist)))
610 (varargslist
611 ((fpdef_opt_test_list_comma_zom rest_args)
612 (nconc $2 $1))
613 ((fpdef_opt_test_list comma_opt)))
614 (rest_args
615 ((MULT NAME multmult_name_opt)
616 nil)
617 ((EXPONENT NAME)
618 nil))
619 (multmult_name_opt
620 (nil)
621 ((COMMA EXPONENT NAME)
622 (wisent-raw-tag
623 (semantic-tag-new-variable $3 nil nil))))
624 (fpdef_opt_test_list_comma_zom
625 (nil)
626 ((fpdef_opt_test_list_comma_zom fpdef_opt_test COMMA)
627 (nconc $2 $1)))
628 (fpdef_opt_test_list
629 ((fpdef_opt_test))
630 ((fpdef_opt_test_list COMMA fpdef_opt_test)
631 (nconc $3 $1)))
632 (fpdef_opt_test
633 ((fpdef eq_test_opt)))
634 (fpdef
635 ((NAME)
636 (wisent-raw-tag
637 (semantic-tag-new-variable $1 nil nil))))
638 (fplist
639 ((fpdef_list comma_opt)))
640 (fpdef_list
641 ((fpdef))
642 ((fpdef_list COMMA fpdef)))
643 (eq_test_opt
644 (nil)
645 ((ASSIGN test)
646 nil))
647 (comma_opt
648 (nil)
649 ((COMMA)))
650 (semicolon_opt
651 (nil)
652 ((SEMICOLON))))
653 '(goal function_parameter paren_class indented_block function_parameters paren_classes indented_block_body)))
654 "Parser table.")
655
656(defun wisent-python-wy--install-parser ()
657 "Setup the Semantic Parser."
658 (semantic-install-function-overrides
659 '((parse-stream . wisent-parse-stream)))
660 (setq semantic-parser-name "LALR"
661 semantic--parse-table wisent-python-wy--parse-table
662 semantic-debug-parser-source "wisent-python.wy"
663 semantic-flex-keywords-obarray wisent-python-wy--keyword-table
664 semantic-lex-types-obarray wisent-python-wy--token-table)
665 ;; Collect unmatched syntax lexical tokens
666 (semantic-make-local-hook 'wisent-discarding-token-functions)
667 (add-hook 'wisent-discarding-token-functions
668 'wisent-collect-unmatched-syntax nil t))
669
670
671;;; Analyzers
672
673(define-lex-keyword-type-analyzer wisent-python-wy--<keyword>-keyword-analyzer
674 "keyword analyzer for <keyword> tokens."
675 "\\(\\sw\\|\\s_\\)+")
676
677(define-lex-block-type-analyzer wisent-python-wy--<block>-block-analyzer
678 "block analyzer for <block> tokens."
679 "\\s(\\|\\s)"
680 '((("(" LPAREN PAREN_BLOCK)
681 ("{" LBRACE BRACE_BLOCK)
682 ("[" LBRACK BRACK_BLOCK))
683 (")" RPAREN)
684 ("}" RBRACE)
685 ("]" RBRACK))
686 )
687
688(define-lex-regex-type-analyzer wisent-python-wy--<symbol>-regexp-analyzer
689 "regexp analyzer for <symbol> tokens."
690 "\\(\\sw\\|\\s_\\)+"
691 nil
692 'NAME)
693
694(define-lex-regex-type-analyzer wisent-python-wy--<number>-regexp-analyzer
695 "regexp analyzer for <number> tokens."
696 semantic-lex-number-expression
697 nil
698 'NUMBER_LITERAL)
699
700(define-lex-string-type-analyzer wisent-python-wy--<punctuation>-string-analyzer
701 "string analyzer for <punctuation> tokens."
702 "\\(\\s.\\|\\s$\\|\\s'\\)+"
703 '((BACKQUOTE . "`")
704 (ASSIGN . "=")
705 (COMMA . ",")
706 (SEMICOLON . ";")
707 (COLON . ":")
708 (BAR . "|")
709 (TILDE . "~")
710 (PERIOD . ".")
711 (MINUS . "-")
712 (PLUS . "+")
713 (MOD . "%")
714 (DIV . "/")
715 (MULT . "*")
716 (AMP . "&")
717 (GT . ">")
718 (LT . "<")
719 (HAT . "^")
720 (NE . "!=")
721 (LTGT . "<>")
722 (HATEQ . "^=")
723 (OREQ . "|=")
724 (AMPEQ . "&=")
725 (MODEQ . "%=")
726 (DIVEQ . "/=")
727 (MULTEQ . "*=")
728 (MINUSEQ . "-=")
729 (PLUSEQ . "+=")
730 (LE . "<=")
731 (GE . ">=")
732 (EQ . "==")
733 (EXPONENT . "**")
734 (GTGT . ">>")
735 (LTLT . "<<")
736 (DIVDIV . "//")
737 (DIVDIVEQ . "//=")
738 (EXPEQ . "**=")
739 (GTGTEQ . ">>=")
740 (LTLTEQ . "<<="))
741 'punctuation)
742
743
744;;; Epilogue
745;;
746
747(provide 'semantic/wisent/python-wy)
748
749;;; semantic/wisent/python-wy.el ends here
diff --git a/lisp/cedet/semantic/wisent/python.el b/lisp/cedet/semantic/wisent/python.el
new file mode 100644
index 00000000000..af226553ff0
--- /dev/null
+++ b/lisp/cedet/semantic/wisent/python.el
@@ -0,0 +1,344 @@
1;;; wisent-python.el --- Semantic support for Python
2
3;; Copyright (C) 2002, 2004, 2006, 2007, 2008, 2009, 2010
4;; Free Software Foundation, Inc.
5
6;; Author: Richard Kim <emacs18@gmail.com>
7;; Maintainer: Richard Kim <emacs18@gmail.com>
8;; Created: June 2002
9;; Keywords: syntax
10
11;; This file is part of GNU Emacs.
12
13;; GNU Emacs is free software: you can redistribute it and/or modify
14;; it under the terms of the GNU General Public License as published by
15;; the Free Software Foundation, either version 3 of the License, or
16;; (at your option) any later version.
17
18;; GNU Emacs is distributed in the hope that it will be useful,
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;; GNU General Public License for more details.
22
23;; You should have received a copy of the GNU General Public License
24;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
25
26;;; Commentary:
27;;
28;; Parser support for Python.
29
30;;; Code:
31
32(require 'semantic/wisent)
33(require 'semantic/wisent/python-wy)
34(require 'semantic/dep)
35(require 'semantic/ctxt)
36
37
38;;; Lexical analysis
39;;
40
41;; Python strings are delimited by either single quotes or double
42;; quotes, e.g., "I'm a string" and 'I too am s string'.
43;; In addition a string can have either a 'r' and/or 'u' prefix.
44;; The 'r' prefix means raw, i.e., normal backslash substitutions are
45;; to be suppressed. For example, r"01\n34" is a string with six
46;; characters 0, 1, \, n, 3 and 4. The 'u' prefix means the following
47;; string is a unicode.
48(defconst wisent-python-string-re
49 (concat (regexp-opt '("r" "u" "ur" "R" "U" "UR" "Ur" "uR") t)
50 "?['\"]")
51 "Regexp matching beginning of a python string.")
52
53(defvar wisent-python-EXPANDING-block nil
54 "Non-nil when expanding a paren block for Python lexical analyzer.")
55
56(defun wisent-python-implicit-line-joining-p ()
57 "Return non-nil if implicit line joining is active.
58That is, if inside an expressions in parentheses, square brackets or
59curly braces."
60 wisent-python-EXPANDING-block)
61
62(defsubst wisent-python-forward-string ()
63 "Move point at the end of the python string at point."
64 (when (looking-at wisent-python-string-re)
65 ;; skip the prefix
66 (and (match-end 1) (goto-char (match-end 1)))
67 ;; skip the quoted part
68 (cond
69 ((looking-at "\"\"\"[^\"]")
70 (search-forward "\"\"\"" nil nil 2))
71 ((looking-at "'''[^']")
72 (search-forward "'''" nil nil 2))
73 ((forward-sexp 1)))))
74
75(defun wisent-python-forward-line ()
76 "Move point to the beginning of the next logical line.
77Usually this is simply the next physical line unless strings,
78implicit/explicit line continuation, blank lines, or comment lines are
79encountered. This function skips over such items so that the point is
80at the beginning of the next logical line. If the current logical
81line ends at the end of the buffer, leave the point there."
82 (while (not (eolp))
83 (when (= (point)
84 (progn
85 (cond
86 ;; Skip over python strings.
87 ((looking-at wisent-python-string-re)
88 (wisent-python-forward-string))
89 ;; At a comment start just goto end of line.
90 ((looking-at "\\s<")
91 (end-of-line))
92 ;; Skip over generic lists and strings.
93 ((looking-at "\\(\\s(\\|\\s\"\\)")
94 (forward-sexp 1))
95 ;; At the explicit line continuation character
96 ;; (backslash) move to next line.
97 ((looking-at "\\s\\")
98 (forward-line 1))
99 ;; Skip over white space, word, symbol, punctuation,
100 ;; and paired delimiter (backquote) characters.
101 ((skip-syntax-forward "-w_.$)")))
102 (point)))
103 (error "python-forward-line endless loop detected")))
104 ;; The point is at eol, skip blank and comment lines.
105 (forward-comment (point-max))
106 ;; Goto the beginning of the next line.
107 (or (eobp) (beginning-of-line)))
108
109(defun wisent-python-forward-line-skip-indented ()
110 "Move point to the next logical line, skipping indented lines.
111That is the next line whose indentation is less than or equal to the
112identation of the current line."
113 (let ((indent (current-indentation)))
114 (while (progn (wisent-python-forward-line)
115 (and (not (eobp))
116 (> (current-indentation) indent))))))
117
118(defun wisent-python-end-of-block ()
119 "Move point to the end of the current block."
120 (let ((indent (current-indentation)))
121 (while (and (not (eobp)) (>= (current-indentation) indent))
122 (wisent-python-forward-line-skip-indented))
123 ;; Don't include final comments in current block bounds
124 (forward-comment (- (point-max)))
125 (or (bolp) (forward-line 1))
126 ))
127
128;; Indentation stack, what the Python (2.3) language spec. says:
129;;
130;; The indentation levels of consecutive lines are used to generate
131;; INDENT and DEDENT tokens, using a stack, as follows.
132;;
133;; Before the first line of the file is read, a single zero is pushed
134;; on the stack; this will never be popped off again. The numbers
135;; pushed on the stack will always be strictly increasing from bottom
136;; to top. At the beginning of each logical line, the line's
137;; indentation level is compared to the top of the stack. If it is
138;; equal, nothing happens. If it is larger, it is pushed on the stack,
139;; and one INDENT token is generated. If it is smaller, it must be one
140;; of the numbers occurring on the stack; all numbers on the stack
141;; that are larger are popped off, and for each number popped off a
142;; DEDENT token is generated. At the end of the file, a DEDENT token
143;; is generated for each number remaining on the stack that is larger
144;; than zero.
145(defvar wisent-python-indent-stack)
146
147(define-lex-analyzer wisent-python-lex-beginning-of-line
148 "Detect and create python indentation tokens at beginning of line."
149 (and
150 (bolp) (not (wisent-python-implicit-line-joining-p))
151 (let ((last-indent (car wisent-python-indent-stack))
152 (last-pos (point))
153 (curr-indent (current-indentation)))
154 (skip-syntax-forward "-")
155 (cond
156 ;; Skip comments and blank lines. No change in indentation.
157 ((or (eolp) (looking-at semantic-lex-comment-regex))
158 (forward-comment (point-max))
159 (or (eobp) (beginning-of-line))
160 (setq semantic-lex-end-point (point))
161 ;; Loop lexer to handle the next line.
162 t)
163 ;; No change in indentation.
164 ((= curr-indent last-indent)
165 (setq semantic-lex-end-point (point))
166 ;; Try next analyzers.
167 nil)
168 ;; Indentation increased
169 ((> curr-indent last-indent)
170 (if (or (not semantic-lex-maximum-depth)
171 (< semantic-lex-current-depth semantic-lex-maximum-depth))
172 (progn
173 ;; Return an INDENT lexical token
174 (setq semantic-lex-current-depth (1+ semantic-lex-current-depth))
175 (push curr-indent wisent-python-indent-stack)
176 (semantic-lex-push-token
177 (semantic-lex-token 'INDENT last-pos (point))))
178 ;; Add an INDENT_BLOCK token
179 (semantic-lex-push-token
180 (semantic-lex-token
181 'INDENT_BLOCK
182 (progn (beginning-of-line) (point))
183 (semantic-lex-unterminated-syntax-protection 'INDENT_BLOCK
184 (wisent-python-end-of-block)
185 (point)))))
186 ;; Loop lexer to handle tokens in current line.
187 t)
188 ;; Indentation decreased
189 (t
190 ;; Pop items from indentation stack
191 (while (< curr-indent last-indent)
192 (pop wisent-python-indent-stack)
193 (setq semantic-lex-current-depth (1- semantic-lex-current-depth)
194 last-indent (car wisent-python-indent-stack))
195 (semantic-lex-push-token
196 (semantic-lex-token 'DEDENT last-pos (point))))
197 ;; If pos did not change, then we must return nil so that
198 ;; other lexical analyzers can be run.
199 (/= last-pos (point))))))
200 ;; All the work was done in the above analyzer matching condition.
201 )
202
203(define-lex-regex-analyzer wisent-python-lex-end-of-line
204 "Detect and create python newline tokens.
205Just skip the newline character if the following line is an implicit
206continuation of current line."
207 "\\(\n\\|\\s>\\)"
208 (if (wisent-python-implicit-line-joining-p)
209 (setq semantic-lex-end-point (match-end 0))
210 (semantic-lex-push-token
211 (semantic-lex-token 'NEWLINE (point) (match-end 0)))))
212
213(define-lex-regex-analyzer wisent-python-lex-string
214 "Detect and create python string tokens."
215 wisent-python-string-re
216 (semantic-lex-push-token
217 (semantic-lex-token
218 'STRING_LITERAL
219 (point)
220 (semantic-lex-unterminated-syntax-protection 'STRING_LITERAL
221 (wisent-python-forward-string)
222 (point)))))
223
224(define-lex-regex-analyzer wisent-python-lex-ignore-backslash
225 "Detect and skip over backslash (explicit line joining) tokens.
226A backslash must be the last token of a physical line, it is illegal
227elsewhere on a line outside a string literal."
228 "\\s\\\\s-*$"
229 ;; Skip over the detected backslash and go to the first
230 ;; non-whitespace character in the next physical line.
231 (forward-line)
232 (skip-syntax-forward "-")
233 (setq semantic-lex-end-point (point)))
234
235(define-lex wisent-python-lexer
236 "Lexical Analyzer for Python code."
237 ;; Must analyze beginning of line first to handle indentation.
238 wisent-python-lex-beginning-of-line
239 wisent-python-lex-end-of-line
240 ;; Must analyze string before symbol to handle string prefix.
241 wisent-python-lex-string
242 ;; Analyzers auto-generated from grammar.
243 wisent-python-wy--<number>-regexp-analyzer
244 wisent-python-wy--<keyword>-keyword-analyzer
245 wisent-python-wy--<symbol>-regexp-analyzer
246 wisent-python-wy--<block>-block-analyzer
247 wisent-python-wy--<punctuation>-string-analyzer
248 ;; Ignored things.
249 wisent-python-lex-ignore-backslash
250 semantic-lex-ignore-whitespace
251 semantic-lex-ignore-comments
252 ;; Signal error on unhandled syntax.
253 semantic-lex-default-action)
254
255;;; Overridden Semantic API.
256;;
257(define-mode-local-override semantic-lex python-mode
258 (start end &optional depth length)
259 "Lexically analyze python code in current buffer.
260See the function `semantic-lex' for the meaning of the START, END,
261DEPTH and LENGTH arguments.
262This function calls `wisent-python-lexer' to actually perform the
263lexical analysis, then emits the necessary python DEDENT tokens from
264what remains in the `wisent-python-indent-stack'."
265 (let* ((wisent-python-indent-stack (list 0))
266 (stream (wisent-python-lexer start end depth length))
267 (semantic-lex-token-stream nil))
268 ;; Emit DEDENT tokens if something remains in the INDENT stack.
269 (while (> (pop wisent-python-indent-stack) 0)
270 (semantic-lex-push-token (semantic-lex-token 'DEDENT end end)))
271 (nconc stream (nreverse semantic-lex-token-stream))))
272
273(define-mode-local-override semantic-get-local-variables python-mode ()
274 "Get the local variables based on point's context.
275To be implemented for python! For now just return nil."
276 nil)
277
278(defcustom-mode-local-semantic-dependency-system-include-path
279 python-mode semantic-python-dependency-system-include-path
280 nil
281 "The system include path used by Python langauge.")
282
283;;; Enable Semantic in `python-mode'.
284;;
285
286;;;###autoload
287(defun wisent-python-default-setup ()
288 "Setup buffer for parse."
289 (wisent-python-wy--install-parser)
290 (set (make-local-variable 'parse-sexp-ignore-comments) t)
291 (setq
292 ;; Character used to separation a parent/child relationship
293 semantic-type-relation-separator-character '(".")
294 semantic-command-separation-character ";"
295 ;; The following is no more necessary as semantic-lex is overriden
296 ;; in python-mode.
297 ;; semantic-lex-analyzer 'wisent-python-lexer
298
299 ;; Semantic to take over from the one provided by python.
300 ;; The python one, if it uses the senator advice, will hang
301 ;; Emacs unrecoverably.
302 imenu-create-index-function 'semantic-create-imenu-index
303
304 ;; I need a python guru to update this list:
305 semantic-symbol->name-assoc-list-for-type-parts '((variable . "Variables")
306 (function . "Methods"))
307 semantic-symbol->name-assoc-list '((type . "Classes")
308 (variable . "Variables")
309 (function . "Functions")
310 (include . "Imports")
311 (package . "Package")
312 (code . "Code")))
313 )
314
315;;;###autoload
316(add-hook 'python-mode-hook 'wisent-python-default-setup)
317
318;; Make sure the newer python modes pull in the same python
319;; mode overrides.
320(define-child-mode python-2-mode python-mode "Python 2 mode")
321(define-child-mode python-3-mode python-mode "Python 3 mode")
322
323
324;;; Test
325;;
326(defun wisent-python-lex-buffer ()
327 "Run `wisent-python-lexer' on current buffer."
328 (interactive)
329 (semantic-lex-init)
330 (let ((token-stream (semantic-lex (point-min) (point-max) 0)))
331 (with-current-buffer (get-buffer-create "*wisent-python-lexer*")
332 (erase-buffer)
333 (pp token-stream (current-buffer))
334 (goto-char (point-min))
335 (pop-to-buffer (current-buffer)))))
336
337(provide 'semantic/wisent/python)
338
339;; Local variables:
340;; generated-autoload-file: "../loaddefs.el"
341;; generated-autoload-load-name: "semantic/wisent/python"
342;; End:
343
344;;; semantic/wisent/python.el ends here