}
         }
     };
-    //println!("{output}");
+    println!("{output}");
     Ok(output)
 }
 
 
 use flagset::FlagSet;
 
-use super::{Comma, Command, Equals, Integer, Punctuated, Slash};
+use super::{Comma, Command, Equals, Integer, Punctuated, Seq0, Seq1, Slash};
 use crate::{
     command::{FromTokens, InParens, MismatchToError, ParseError, ParseResult, Parsed, TokenSlice},
     identifier::Identifier,
 
 #[derive(Debug, pspp_derive::FromTokens)]
 #[pspp(add_lifetime)]
-struct DataList<'a>(Vec<Setting<'a>>);
+struct DataList<'a>(Seq1<Setting<'a>>, Seq1<Record<'a>>);
 
 #[derive(Debug, pspp_derive::FromTokens)]
 #[pspp(add_lifetime)]
     Handle(&'a Identifier),
 }
 
-#[derive(Debug, pspp_derive::FromTokens)]
-#[pspp(add_lifetime)]
+#[derive(Debug)]
 struct Record<'a> {
     slash: Slash,
     record: Option<Integer>,
-    variables: Vec<Variable<'a>>,
+    variables: Seq0<Variable<'a>>,
+}
+
+impl<'a> FromTokens<'a> for Record<'a> {
+    fn from_tokens(input: TokenSlice<'a>) -> ParseResult<'a, Self> {
+        println!("{input:?}");
+        println!("{}:{}", file!(), line!());
+        let mut diagnostics = crate::command::Diagnostics::default();
+        println!("{}:{}", file!(), line!());
+        let (field0, input) = FromTokens::from_tokens(input)?.take_diagnostics(&mut diagnostics);
+        println!("{}:{}", file!(), line!());
+        let (field1, input) = FromTokens::from_tokens(input)?.take_diagnostics(&mut diagnostics);
+        println!("{}:{}", file!(), line!());
+        let (field2, input) = FromTokens::from_tokens(input)?.take_diagnostics(&mut diagnostics);
+        println!("{}:{}", file!(), line!());
+        Ok(Parsed::new(
+            Record {
+                slash: field0,
+                record: field1,
+                variables: field2,
+            },
+            input,
+            diagnostics,
+        ))
+    }
 }
 
 #[derive(Debug, pspp_derive::FromTokens)]
 #[pspp(add_lifetime)]
 struct Variable<'a> {
-    names: Vec<&'a Identifier>,
+    names: Seq1<&'a Identifier>,
     location: Location<'a>,
 }
 
     #[test]
     fn basics() {
         test(
-            "CROSSTABS r by c /STATISTICS=CHISQ
-/CELLS=COUNT EXPECTED RESID SRESID ASRESID
-/HIDESMALLCOUNTS COUNT=6.
-",
+            r#"DATA LIST FILE="/data/hubdata.txt" RECORDS=3
+/1 DEPT 19 SEX 20 MOHIRED YRHIRED 12-15
+/2 SALARY 21-25."#,
         );
     }
-
-    #[test]
-    fn integer_mode() {
-        test("CROSSTABS VARIABLES=X (1,7) Y (1,7) /TABLES=X BY Y/WRITE=CELLS.");
-    }
 }
 
 use flagset::FlagSet;
 
-use super::{Comma, Command, Equals, Punctuated, Subcommand};
+use super::{Comma, Command, Equals, Punctuated, Seq1, Subcommand};
 use crate::command::{
     FromTokens, Identifier, InParens, MismatchToError, ParseError, ParseResult, Parsed, Punct,
     Token, TokenSlice, VarRange,
 #[derive(Debug, pspp_derive::FromTokens)]
 #[pspp(add_lifetime)]
 struct Descriptives<'a> {
-    subcommands: Vec<Subcommand<DescriptivesSubcommand<'a>>>,
+    subcommands: Seq1<Subcommand<DescriptivesSubcommand<'a>>>,
 }
 
 #[derive(Debug, pspp_derive::FromTokens)]
 enum DescriptivesSubcommand<'a> {
     #[pspp(default)]
     Variables(Option<Equals>, Punctuated<DescriptivesVars<'a>>),
-    Missing(Equals, Vec<Missing>),
+    Missing(Equals, Seq1<Missing>),
     Save,
-    Statistics(Equals, Vec<Statistic>),
+    Statistics(Equals, Seq1<Statistic>),
     Sort(Equals, Sort),
-    Format(Equals, Vec<Format>),
+    Format(Equals, Seq1<Format>),
 }
 
 #[derive(Debug, pspp_derive::FromTokens)]
 
 }
 
 #[derive(Debug, pspp_derive::FromTokens)]
-#[pspp(syntax="/")]
+#[pspp(syntax = "/")]
 pub struct Slash;
 
 #[derive(Debug)]
     }
 }
 
-#[derive(Debug)]
-pub struct Equals(Token);
-
-impl<'a> FromTokens<'a> for Equals {
-    fn from_tokens(input: TokenSlice<'a>) -> ParseResult<'a, Self>
-    where
-        Self: Sized,
-    {
-        _parse_token(input, &Token::Punct(Punct::Equals)).map(|p| p.map(|token| Equals(token)))
-    }
-}
+#[derive(Debug, pspp_derive::FromTokens)]
+#[pspp(syntax = "=")]
+pub struct Equals;
 
 #[derive(Debug)]
 struct By(Token);
     }
 }
 
+#[derive(Debug)]
+pub struct Seq0<T>(Vec<T>);
+
+impl<'a, T> FromTokens<'a> for Seq0<T>
+where
+    T: FromTokens<'a>,
+{
+    fn from_tokens(mut input: TokenSlice<'a>) -> ParseResult<'a, Self>
+    where
+        Self: Sized,
+    {
+        let mut values_vec = Vec::new();
+        let mut warnings_vec = Vec::new();
+        while !input.is_empty() {
+            match T::from_tokens(input) {
+                Ok(Parsed {
+                    value,
+                    rest,
+                    diagnostics: mut warnings,
+                }) => {
+                    warnings_vec.append(&mut warnings.0);
+                    if input.len() == rest.len() {
+                        break;
+                    }
+                    values_vec.push(value);
+                    input = rest;
+                }
+                Err(ParseError::Mismatch(_)) => break,
+                Err(ParseError::Error(e)) => return Err(ParseError::Error(e)),
+            }
+        }
+        Ok(Parsed {
+            value: Seq0(values_vec),
+            rest: input,
+            diagnostics: Diagnostics(warnings_vec),
+        })
+    }
+}
+
+#[derive(Debug)]
+pub struct Seq1<T>(Vec<T>);
+
+impl<'a, T> FromTokens<'a> for Seq1<T>
+where
+    T: FromTokens<'a>,
+{
+    fn from_tokens(mut input: TokenSlice<'a>) -> ParseResult<'a, Self>
+    where
+        Self: Sized,
+    {
+        let mut values_vec = Vec::new();
+        let mut warnings_vec = Vec::new();
+        while !input.is_empty() {
+            match T::from_tokens(input) {
+                Ok(Parsed {
+                    value,
+                    rest,
+                    diagnostics: mut warnings,
+                }) => {
+                    warnings_vec.append(&mut warnings.0);
+                    if input.len() == rest.len() {
+                        break;
+                    }
+                    values_vec.push(value);
+                    input = rest;
+                }
+                Err(ParseError::Mismatch(_)) => break,
+                Err(ParseError::Error(e)) => return Err(ParseError::Error(e)),
+            }
+        }
+        if values_vec.is_empty() {
+            return Err(ParseError::Mismatch(input.error("Syntax error.").into()));
+        }
+        Ok(Parsed {
+            value: Seq1(values_vec),
+            rest: input,
+            diagnostics: Diagnostics(warnings_vec),
+        })
+    }
+}
+
+/*
 impl<'a, T> FromTokens<'a> for Vec<T>
 where
     T: FromTokens<'a>,
             diagnostics: Diagnostics(warnings_vec),
         })
     }
-}
+}*/
 
 impl<'a> FromTokens<'a> for TokenSlice<'a> {
     fn from_tokens(input: TokenSlice<'a>) -> ParseResult<'a, Self>