diff options
author | David Brazdil <dbrazdil@google.com> | 2015-04-28 13:53:59 +0100 |
---|---|---|
committer | David Brazdil <dbrazdil@google.com> | 2015-05-12 17:05:28 +0100 |
commit | a490be5dd95982f77ff1447bea9ee06604038a96 (patch) | |
tree | b08302c509e569590d4f506743467156eea6d836 /tools/checker/file_format/c1visualizer/parser.py | |
parent | 987b2e66de00d754d19b6f59a17891dd34e04e61 (diff) |
ART: Split Checker into smaller files
Checker code has become too messy and incomprehensible. This patch
splits it into more manageable and better structured units.
Functionality remains unchanged.
Change-Id: I870c69827d2be2d09196a51382a3f47f31cd2ba3
Diffstat (limited to 'tools/checker/file_format/c1visualizer/parser.py')
-rw-r--r-- | tools/checker/file_format/c1visualizer/parser.py | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/tools/checker/file_format/c1visualizer/parser.py b/tools/checker/file_format/c1visualizer/parser.py new file mode 100644 index 0000000000..f34161b297 --- /dev/null +++ b/tools/checker/file_format/c1visualizer/parser.py @@ -0,0 +1,87 @@ +# Copyright (C) 2015 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from common.logger import Logger +from file_format.common import SplitStream +from file_format.c1visualizer.struct import C1visualizerFile, C1visualizerPass + +import re + +class C1ParserState: + OutsideBlock, InsideCompilationBlock, StartingCfgBlock, InsideCfgBlock = range(4) + + def __init__(self): + self.currentState = C1ParserState.OutsideBlock + self.lastMethodName = None + +def __parseC1Line(line, lineNo, state, fileName): + """ This function is invoked on each line of the output file and returns + a pair which instructs the parser how the line should be handled. If the + line is to be included in the current group, it is returned in the first + value. If the line starts a new output group, the name of the group is + returned in the second value. + """ + if state.currentState == C1ParserState.StartingCfgBlock: + # Previous line started a new 'cfg' block which means that this one must + # contain the name of the pass (this is enforced by C1visualizer). + if re.match("name\s+\"[^\"]+\"", line): + # Extract the pass name, prepend it with the name of the method and + # return as the beginning of a new group. + state.currentState = C1ParserState.InsideCfgBlock + return (None, state.lastMethodName + " " + line.split("\"")[1]) + else: + Logger.fail("Expected output group name", fileName, lineNo) + + elif state.currentState == C1ParserState.InsideCfgBlock: + if line == "end_cfg": + state.currentState = C1ParserState.OutsideBlock + return (None, None) + else: + return (line, None) + + elif state.currentState == C1ParserState.InsideCompilationBlock: + # Search for the method's name. Format: method "<name>" + if re.match("method\s+\"[^\"]*\"", line): + methodName = line.split("\"")[1].strip() + if not methodName: + Logger.fail("Empty method name in output", fileName, lineNo) + state.lastMethodName = methodName + elif line == "end_compilation": + state.currentState = C1ParserState.OutsideBlock + return (None, None) + + else: + assert state.currentState == C1ParserState.OutsideBlock + if line == "begin_cfg": + # The line starts a new group but we'll wait until the next line from + # which we can extract the name of the pass. + if state.lastMethodName is None: + Logger.fail("Expected method header", fileName, lineNo) + state.currentState = C1ParserState.StartingCfgBlock + return (None, None) + elif line == "begin_compilation": + state.currentState = C1ParserState.InsideCompilationBlock + return (None, None) + else: + Logger.fail("C1visualizer line not inside a group", fileName, lineNo) + +def ParseC1visualizerStream(fileName, stream): + c1File = C1visualizerFile(fileName) + state = C1ParserState() + fnProcessLine = lambda line, lineNo: __parseC1Line(line, lineNo, state, fileName) + fnLineOutsideChunk = lambda line, lineNo: \ + Logger.fail("C1visualizer line not inside a group", fileName, lineNo) + for passName, passLines, startLineNo in SplitStream(stream, fnProcessLine, fnLineOutsideChunk): + C1visualizerPass(c1File, passName, passLines, startLineNo + 1) + return c1File |