Class: TaskJuggler::ProjectFileScanner
- Inherits:
-
TextParser::Scanner
- Object
- TextParser::Scanner
- TaskJuggler::ProjectFileScanner
- Defined in:
- lib/taskjuggler/ProjectFileScanner.rb
Overview
This class specializes the TextParser::Scanner class to detect the tokens of the TJP syntax.
Instance Method Summary collapse
-
#initialize(masterFile) ⇒ ProjectFileScanner
constructor
A new instance of ProjectFileScanner.
Methods inherited from TextParser::Scanner
#addMacro, #addPattern, #close, #columnNo, #error, #expandMacro, #fileName, #include, #line, #lineNo, #macroDefined?, #mode=, #nextToken, #open, #returnToken, #sourceFileInfo, #warning
Constructor Details
#initialize(masterFile) ⇒ ProjectFileScanner
Returns a new instance of ProjectFileScanner.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/taskjuggler/ProjectFileScanner.rb', line 22 def initialize(masterFile) tokenPatterns = [ # Any white spaces [ nil, /\s+/, :tjp, method('newPos') ], # Single line comments starting with # [ nil, /#.*\n?/, :tjp, method('newPos') ], # C++ style single line comments starting with // [ nil, /\/\/.*\n?/, :tjp, method('newPos') ], # C style single line comment /* .. */. [ nil, /\/\*.*\*\//, :tjp, method('newPos') ], # C style multi line comment: We need three patterns here. The first # one is for the start of the string. It switches the scanner mode to # the :cppComment mode. [ nil, /\/\*([^*]*[^\/]|.*)\n/, :tjp, method('startComment') ], # This is the string end pattern. It switches back to tjp mode. [ nil, /.*\*\//, :cppComment, method('endComment') ], # This pattern matches string lines that contain neither the start, # nor the end of the string. [ nil, /^.*\n/, :cppComment ], # Macro Call: This case is more complicated because we want to replace # macro calls inside of numbers, strings and identifiers. For this to # work, macro calls may have a prefix that looks like a number, a part # of a string or an identifier. This prefix is preserved and # re-injected into the scanner together with the expanded text. Macro # calls may span multiple lines. The ${ and the macro name must be in # the first line. Arguments that span multiple lines are not # supported. As above, we need rules for the start, the end and lines # with neither start nor end. Macro calls inside of strings need a # special start pattern that is active in the string modes. Both # patterns switch the scanner to macroCall mode. [ nil, /([-a-zA-Z_0-9>:.+]*|"(\\"|[^"])*?|'(\\'|[^'])*?)?\$\{\s*(\??[a-zA-Z_]\w*)(\s*"(\\"|[^"])*")*/, :tjp, method('startMacroCall') ], # This pattern is similar to the previous one, but is active inside of # multi-line strings. The corresponding rule for sizzors strings # can be found below. [ nil, /(\\"|[^"])*?\$\{\s*(\??[a-zA-Z_]\w*)(\s*"(\\"|[^"])*")*/, :dqString, method('startMacroCall') ], [ nil, /(\\'|[^'])*?\$\{\s*(\??[a-zA-Z_]\w*)(\s*"(\\"|[^"])*")*/, :sqString, method('startMacroCall') ], # This pattern matches the end of a macro call. It injects the prefix # and the expanded macro into the scanner again. The mode is restored # to the previous mode. [ nil, /(\s*"(\\"|[^"])*")*\s*\}/, :macroCall, method('endMacroCall') ], # This pattern collects macro call arguments in lines that contain # neither the start nor the end of the macro. [ nil, /.*\n/, :macroCall, method('midMacroCall') ], # Environment variable reference. This is similar to the macro call, # but the it can only extend within the starting line. [ nil, /([-a-zA-Z_0-9>:.+]*|"(\\"|[^"])*?|'(\\'|[^'])*?)?\$\([A-Z_][A-Z_0-9]*\)/, :tjp, method('environmentVariable') ], # An ID with a colon suffix: foo: [ :ID_WITH_COLON, /[a-zA-Z_]\w*:/, :tjp, method('chop') ], # An absolute ID: a.b.c [ :ABSOLUTE_ID, /[a-zA-Z_]\w*(\.[a-zA-Z_]\w*)+/ ], # A normal ID: bar [ :ID, /[a-zA-Z_]\w*/ ], # A date [ :DATE, /\d{4}-\d{1,2}-\d{1,2}(-\d{1,2}:\d{1,2}(:\d{1,2})?(-[-+]?\d{4})?)?/, :tjp, method('to_date') ], # A time of day [ :TIME, /\d{1,2}:\d{2}/, :tjp, method('to_time') ], # A floating point number (e. g. 3.143) [ :FLOAT, /\d*\.\d+/, :tjp, method('to_f') ], # An integer number [ :INTEGER, /\d+/, :tjp, method('to_i') ], # Multi line string enclosed with double quotes. The string may # contain double quotes prefixed by a backslash. The first rule # switches the scanner to dqString mode. [ 'nil', /"(\\"|[^"])*/, :tjp, method('startStringDQ') ], # Any line not containing the start or end. [ 'nil', /^(\\"|[^"])*\n/, :dqString, method('midStringDQ') ], # The end of the string. [ :STRING, /(\\"|[^"])*"/, :dqString, method('endStringDQ') ], # Multi line string enclosed with single quotes. [ 'nil', /'(\\'|[^'])*/, :tjp, method('startStringSQ') ], # Any line not containing the start or end. [ 'nil', /^(\\'|[^'])*\n/, :sqString, method('midStringSQ') ], # The end of the string. [ :STRING, /(\\'|[^'])*'/, :sqString, method('endStringSQ') ], # Scizzors marked string -8<- ... ->8-: The opening mark must be the # last thing in the line. The indentation of the first line after the # opening mark determines the indentation for all following lines. So, # we first switch the scanner to szrString1 mode. [ 'nil', /-8<-.*\n/, :tjp, method('startStringSZR') ], # Since the first line can be the last line (empty string case), we # need to detect the end in szrString1 and szrString mode. The # patterns switch the scanner back to tjp mode. [ :STRING, /\s*->8-/, :szrString1, method('endStringSZR') ], [ :STRING, /\s*->8-/, :szrString, method('endStringSZR') ], # This rule handles macros inside of sizzors strings. [ nil, /.*?\$\{\s*(\??[a-zA-Z_]\w*)(\s*"(\\"|[^"])*")*/, [ :szrString, :szrString1 ], method('startMacroCall') ], # Any line not containing the start or end. [ 'nil', /.*\n/, :szrString1, method('firstStringSZR') ], [ 'nil', /.*\n/, :szrString, method('midStringSZR') ], # Single line macro definition [ :MACRO, /\[.*\]\n/, :tjp, method('chop2nl') ], # Multi line macro definition: The pattern switches the scanner into # macroDef mode. [ nil, /\[.*\n/, :tjp, method('startMacroDef') ], # The end of the macro is marked by a ']' that is immediately followed # by a line break. It switches the scanner back to tjp mode. [ :MACRO, /.*\]\n/, :macroDef, method('endMacroDef') ], # Any line not containing the start or end. [ nil, /.*\n/, :macroDef, method('midMacroDef') ], # Some multi-char literals. [ :LITERAL, /<=?/ ], [ :LITERAL, />=?/ ], [ :LITERAL, /!=?/ ], # Everything else is returned as a single-char literal. [ :LITERAL, /./ ] ] super(masterFile, Log, tokenPatterns, :tjp) end |