1 | #!/usr/bin/env python2
|
2 | from __future__ import print_function
|
3 |
|
4 | import sys
|
5 |
|
6 | from _devbuild.gen.option_asdl import option_i
|
7 | from _devbuild.gen.syntax_asdl import source, source_t, command, command_t
|
8 | from asdl import format as fmt
|
9 | from core import alloc
|
10 | from core import error
|
11 | from core import optview
|
12 | #from core import main_loop
|
13 | from core import pyutil
|
14 | from core import state
|
15 | from display import ui
|
16 | from frontend import parse_lib
|
17 | from frontend import reader
|
18 | from mycpp import mylib
|
19 | from mycpp.mylib import log
|
20 |
|
21 | _ = log
|
22 |
|
23 | from typing import List, Dict, TYPE_CHECKING
|
24 | if TYPE_CHECKING:
|
25 | from osh.cmd_parse import CommandParser
|
26 | from pgen2.grammar import Grammar
|
27 |
|
28 |
|
29 | # TEMP: Copied from core/main_loop.py
|
30 | def ParseWholeFile(c_parser):
|
31 | # type: (CommandParser) -> command_t
|
32 | """Parse an entire shell script.
|
33 |
|
34 | This uses the same logic as Batch().
|
35 | """
|
36 | children = [] # type: List[command_t]
|
37 | while True:
|
38 | node = c_parser.ParseLogicalLine() # can raise ParseError
|
39 | if node is None: # EOF
|
40 | c_parser.CheckForPendingHereDocs() # can raise ParseError
|
41 | break
|
42 | children.append(node)
|
43 |
|
44 | if len(children) == 1:
|
45 | return children[0]
|
46 | else:
|
47 | return command.CommandList(children)
|
48 |
|
49 |
|
50 | def main(argv):
|
51 | # type: (List[str]) -> int
|
52 | arena = alloc.Arena()
|
53 | errfmt = ui.ErrorFormatter()
|
54 |
|
55 | opt0_array = state.InitOpts()
|
56 | no_stack = None # type: List[bool] # for mycpp
|
57 | opt_stacks = [no_stack] * option_i.ARRAY_SIZE # type: List[List[bool]]
|
58 | parse_opts = optview.Parse(opt0_array, opt_stacks)
|
59 | # Dummy value; not respecting aliases!
|
60 | aliases = {} # type: Dict[str, str]
|
61 | # parse `` and a[x+1]=bar differently
|
62 |
|
63 | ysh_grammar = None # type: Grammar
|
64 | if mylib.PYTHON:
|
65 | loader = pyutil.GetResourceLoader()
|
66 | ysh_grammar = pyutil.LoadYshGrammar(loader)
|
67 |
|
68 | parse_ctx = parse_lib.ParseContext(arena, parse_opts, aliases, ysh_grammar)
|
69 |
|
70 | pretty_print = True
|
71 |
|
72 | if len(argv) == 1:
|
73 | line_reader = reader.FileLineReader(mylib.Stdin(), arena)
|
74 | src = source.Stdin('') # type: source_t
|
75 |
|
76 | elif len(argv) == 2:
|
77 | path = argv[1]
|
78 | f = mylib.open(path)
|
79 | line_reader = reader.FileLineReader(f, arena)
|
80 | src = source.MainFile(path)
|
81 |
|
82 | elif len(argv) == 3:
|
83 | if argv[1] == '-c':
|
84 | # This path is easier to run through GDB
|
85 | line_reader = reader.StringLineReader(argv[2], arena)
|
86 | src = source.CFlag
|
87 |
|
88 | elif argv[1] == '-n': # For benchmarking, allow osh_parse -n file.txt
|
89 | path = argv[2]
|
90 | f = mylib.open(path)
|
91 | line_reader = reader.FileLineReader(f, arena)
|
92 | src = source.MainFile(path)
|
93 | # This is like --ast-format none, which benchmarks/osh-helper.sh passes.
|
94 | pretty_print = False
|
95 |
|
96 | else:
|
97 | raise AssertionError()
|
98 |
|
99 | else:
|
100 | raise AssertionError()
|
101 |
|
102 | arena.PushSource(src)
|
103 |
|
104 | c_parser = parse_ctx.MakeOshParser(line_reader)
|
105 |
|
106 | try:
|
107 | #node = main_loop.ParseWholeFile(c_parser)
|
108 | node = ParseWholeFile(c_parser)
|
109 | except error.Parse as e:
|
110 | errfmt.PrettyPrintError(e)
|
111 | return 2
|
112 | assert node is not None
|
113 |
|
114 | if pretty_print:
|
115 | tree = node.PrettyTree(True)
|
116 | fmt.HNodePrettyPrint(tree, mylib.Stdout())
|
117 |
|
118 | return 0
|
119 |
|
120 |
|
121 | if __name__ == '__main__':
|
122 | try:
|
123 | main(sys.argv)
|
124 | except RuntimeError as e:
|
125 | print('FATAL: %s' % e, file=sys.stderr)
|
126 | sys.exit(1)
|