Class: Rubycc::Preprocess::TokenConverter
- Inherits:
-
Object
- Object
- Rubycc::Preprocess::TokenConverter
- Defined in:
- lib/rubycc/preprocess/token_converter.rb
Overview
Ends translation phase 4 by turning preprocessing tokens into the Front::Token stream the parser consumes. Numbers are folded, string and character literals decoded, and identifiers classified as keywords, all via the shared LexemeReader so the result matches the streaming lexer exactly. Newlines are dropped here; a "#"/"##" that survives to this point is a stray operator with no macro meaning (directive lines are diagnosed earlier), so it is rejected.
This is where translation phases 5-7 sit in this pipeline, so adjacent string-literal concatenation (phase 6, ISO C 6.4.5p5) happens here: a run of neighbouring string tokens folds into one, its bytes the per-literal decodings laid end to end. The streaming Front::Lexer takes the direct path and does not concatenate — nothing but this converter ever feeds the parser in the real compile pipeline (which always runs through the preprocessor), so the lexer's simpler single-literal path serves its unit-test-only role without the phase-6 fold.
Instance Method Summary collapse
Instance Method Details
#convert(pp_tokens) ⇒ Object
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 |
# File 'lib/rubycc/preprocess/token_converter.rb', line 27 def convert(pp_tokens) tokens = [] index = 0 while index < pp_tokens.length pp = pp_tokens[index] case pp.type when :newline index += 1 when :eof tokens << front_token(pp, :eof, nil) index += 1 when :identifier spelling = Front::LexemeReader.keyword_spelling(pp.text) tokens << front_token(pp, spelling ? :keyword : :ident, spelling || pp.text) index += 1 when :pp_number tokens << convert_number(pp) index += 1 when :string value, index = concatenate_strings(pp_tokens, index) tokens << front_token(pp, :string, value) when :char tokens << num_token(pp, decode_char(pp), 10, "") index += 1 when :punct if pp.text == "#" || pp.text == "##" raise_at(pp, "stray '#' in program") end tokens << front_token(pp, :punct, pp.text) index += 1 when :other raise_at(pp, "unexpected character #{pp.text.inspect}") end end tokens end |